[Deep Dive] Using Script in WebReports/ActiveView
Introduction & history
WebReports-based products (the Content Intelligence suite) are widely and effectively used by a wide variety of Content Server customers. Despite the broad appeal of these products, occasionally I have heard suggestions that a more traditional, scripting-based approach might be more usable - at least for some users.
The good news is that for some years, the WebReports engine has supported the ability to include programatic scripting in a webreport. The WebReports programming methodology was not originally designed as a pure scripting language. The basic design paradigm is similar to some other template-based web development frameworks but it was originally designed around the ability to layout content (including markup language) and to insert system data within that content. Of course, there has always been an inherent looping mechanism built in to WebReports through the natural iteration of the row section, and very early on we introduced IF statements as am obvious way to allow conditional content and/or mutually exclusive content. However, the original processing engine did not really lend itself well to more complex looping and logic conditions and it seemed that further script like extensions of the tag library might be stretching the paradigm too far. Ultimately, we realized that while our existing paradigm was popular with business users (particularly as we closely aligned with the WebForms tag syntax), some developers found this paradigm to be limiting. These days, thanks to the development of the new processing engine, new “content control tags” have been created to support FOR loops and a variety of logic expressions along with complex management of variable values. Notwithstanding these new capabilities within the tag paradigm, the ability to use a more conventional scripting language (spoiler alert, it’s OScript) has been available since around 2006. I believe this feature still provides some value and usefulness today, especially for developers who prefer this mode of programming. In this blog I explore the basics of how this feature works, when to use it and some of the advantages of using it. This Blog is not intended as a detailed instructional guide, but we would be happy to provide more information, training or guidance by request: Contact Us
For anyone who didn’t know this feature existed in WebReports - welcome to the feature called “server-side scripting.”
Why use script in a WebReport?
There are a variety of scenarios where a server-side scripting language makes sense. For example, if you are doing any complex data manipulation that might involve things like merging lists, massaging strings, etc. WebReports tags can do most of these things but the syntax gets a real workout and can be fairly heavy weight and cumbersome in some scenarios.
The script feature is implemented with content Control tags that allow you to define a script function that can be called from anywhere in the context of a webreport. This allows you to create discrete functions to perform specialized tasks. Of course you could wrap the entire contents of the webreport in a function (the function will ultimately return a string that represents the WebReports output), but more typically developers will create a set of discrete script blocks to perform functions that might otherwise be cumbersome to create using the typical WebReports tags. Besides making development easier, this can lead to more readable functionality and in some cases can realize performance benefits.
One little-known benefit of server-side scripting is the ability to work with multiple data sources. When WebReports was first designed there was an intent to allow multiple data sources (and thus multiple row sections). This feature was never developed for various reasons, one of which was due to the fact server-side scripting included this ability. The way this works is that you can invoke sub-webreports from a block of script and the sub-webreport call allows you to specify that in addition to getting the normal output of a sub-webreport, you can also get the source data of that sub-webreport. This means you get a RecArray with all of the rows from the data source of the sub-webreport.
Using this approach you could call multiple sub-webreports (or the same one with different parameters) and then append, merge, or otherwise combine the multiple arrays of data to create a single data structure. This is essentially impossible to do with non-scripted webreports so typically, without server-side scripting, developers will either do this type of manipulation in the client, or with more complex SQL queries.
Wouldn’t script make WebReports insecure or prone to upgrade problems?
In a word: No! Or at least not if you use server-side scripting the way it was designed. Like most WebReports features, the design team provided enough flexibility for you to potentially get into trouble, but by default, this scripting is heavily locked down to force you to use the WebReports tag-based API for any access to the server.
The point of this feature was to provide access to conventional scripting language functionality. The feature was named quite generically as there was some potential to use other languages in the future. We chose OScript as the first such language available because it is readily available within Content Server and it works consistently on any OpenText platform. We also felt that OScript is a relatively easy language to use. Most of the complexity of OScript customization is usually in understanding the Content Suite software architecture and how to override the core functionality.
As we are using the native development language of Content Suite you might expect or assume that you can use all features and packages available through the OScript development environment; however, this feature has been restricted to only support the basic language syntax and some features that would be available in any development language. The rationale for locking it down was partly so that using OScript in a webreport doesn’t lead to objects that get broken as a result of software upgrades and partly to avoid the potential for creating security holes. I’ll talk a bit about the security features in a later section but put simply, you cannot reference anything outside of the webreport context unless you use one of the provided API functions. Specifically:
- ._repTag(...)
- ._subTag(...)
- ._subWebReport(...)
As you can probably tell, these functions are designed to invoke webreport tags, sub-tags and sub-webreports. This is essentially the only way to access Content Server data, thus maintaining the same level of abstraction that is present through webreport tags.
Besides these functions, you can use a few useful OScript packages by default. For example, any function in the STR package can be used, and some functions (like Web.Escape) from the WEB package can be used. For a full current list of available packages or functions see the online documentation. Note that you can configure this feature to add or remove the functions that are allowed by this feature, but you do this at your own risk.
What are the disadvantages of using server-side scripting?
As suggested above, there are two main perceived risks to using this feature. These are:
-
The possibility of making a webreport non-upgrade friendly.
-
Security exposure
I’ve already described above why these points can and should be non-issues, so instead I’ll focus here on any other potential disadvantages.
-
I was recently told by a partner, that while scripting language in a webreport might be calming for a typical OScript developer, business users tend to prefer a non-script-based approach. In other words, using OScript in a webreport can make it less understandable and readable for a non-developer. This is a fair point, though I suppose it depends on the complexity of the OScript and the level of commenting. Script blocks are fairly self-contained and could simply be documented according to its input/output and a description of purpose.
-
Because of the multitude of security constraints, any webreport that includes scripting blocks requires some admin enablement and approval. This is provided to make sure that for anyone who has been allowed to add a webreport to a production system, any script blocks will not run unless an admin has approved the containing webreport. The proposed development model is that a developer works on a development system where they have an admin login or a syspriv level of privilege. Once functionality is developed, they would either need to build a CSApp (Content Server Application) which usually gets installed by an admin, or they would need to have an admin user enable scripting for that object (there are a couple of easy ways to do this).
-
Debugging can be difficult if you don’t have an SDK. While you can actually write Script in a webreport without using an SDK, any errors in your code might be more difficult to resolve. Ideally you would have builder or Eclipse running to make it easier to identify problems in your script code.
-
Script bugs can cause more severe issues. When you are using WebReports tags you will not normally have any trace logs or bugs that might bring the system down unless there is a serious bug found in the WebReports software. When you are using server-side scripting you can obviously cause your own trace occurrences as well as bugs (such as endless loops) that could require you to restart the system.
-
If used inappropriately, you could create worse performance than the equivalent code in a tag-based webreport. This is a complex subject and one we're happy to discuss, but basically if you’re using script to remove overly complicated uses of WebReports script-based tags (loops, if/else, variables, etc.) you will almost certainly improve performance. If you try to bypass the entire WebReports paradigm with one all-inclusive function, the performance is entirely dependent on how well you’ve written your code. Note that the WebReports paradigm is designed to convert a reportview/template into an optimized, compiled OScript so there is some inherent performance benefit in using the WebReports paradigm without modification.
How can administrators control or manage this feature?
Server-side scripting provides a few tools for Content Suite administrators to control and or manage any WebReports reportviews or ActiveView templates that contain scripting. These are listed below and for the sake of simplifying the terminology I use the term “scripted webreport” to refer to webreport reportviews or ActiveView templates that have script blocks in them:
-
Each scripted webreport includes an additional option on the Specific properties tab called “OScript Scripting Enabled.” If a developer is logged in as admin or has system admin rights then this box is automatically checked; however, when a scripted webreport is added for users who do not have this level of privilege, then the box is not checked and is also greyed out. The object can subsequently be enabled by admin or another user with system administrator rights. This prevents any unauthorized creation and submission of scripts to a production system. Note, if a webreport is run without admin approval, the following message is received:
Error - An attempt to call an Oscript block failed because server side scripting is not enabled for WebReport "MultiSource Testing". Only System Administrators can enable scripting for a WebReport and must do so every time a new version of the reportview is added.
-
Admin.index function. "?func=webreports.ManageScripting" allows an administrator to view any and all scripted webreports. (Note, due to a bug, this page does not list any ActiveViews with script in them.) Besides providing access to the function menu for each of these items, this screen also provides an Enable/Disable checkbox. This checkbox provides a quick way to disable script blocks in any of the listed items, but it is also a quick way to enable any Scripts that have not yet been “admin approved” via the Specific property tab.
-
Opentext.ini settings. There are three settings available to administrators with access to the opentext.ini file. They come under the [WebReports] section. These settings are:
-
EnableOscriptReportviews=true. The scripting feature can be completely disabled with this option for any users on the server with this setting.
-
OscriptAllowWholePkg={'Assoc','Bytes',……. }. This setting defines all of the “packages” that can be used in their entirety within a script block. Each package supports a number of functions and this setting enables all functions in the package.
-
OscriptAllowFunction1={ 'Scheduler.debugbreak','Web.CRLF', …..}. This setting specifies any individual functions that can be used from otherwise disallowed packages.
Where can I get more information?
Full documentation on the script feature within WebReports is available from the following sources:
- WebReports Help: ./Reports/WebReports Advanced Information/Server-Side Scripting
- Training Course: Content Server WebReports Design II (Appendix)
- Contact Ravenblack for additional training or support related to this feature