In this blog we talk about a well-known feature of WebReports that is key to creating robust and flexible applications—WebReports Constants. We’ll review what they are, how they are used, and some of the common issues that we’ve seen with typical WebReports applications. Plus, we’ll share a few tips that you might not know about.
The basics
Constants are an important part of WebReports development as they allow a developer to pre-define one or more values in the metadata for a WebReports object that can then be referenced repeatedly in the WebReports source code.
As an initial statement of purpose, WebReports developers will experience the same common benefits of pre-defining constants (and variables) as any other development language. One of these benefits is the ability to manage frequently referenced content such as text or numbers in one place, maintaining consistency in its usage across the application, and making it easy to find and modify these values. Where a common word, phrase, or number is used in multiple places, this content can be modified by tweaking a single constant on the constant tab of a WebReport without ever touching the source. Beyond this simple convenience, some applications may have some sort of identifier that needs to remain consistent between WebReports – e.g. a database column name, or a lookup field for an Oscript structure.
Most applications will have cases where this application of constants is useful, but there is a much more important application of the Constants feature—to provide references to other Content Server objects, users and groups. We’ll talk about this aspect of Constants more below.
Here is the basic syntax used to reference any constant defined for a WebReport:
[LL_REPTAG_$constName /], where “constName” is the name of the constant as defined on the Constants tab. Of course, as with any WebReports tag, a combination of sub-tags can be applied to whatever value the constant returns.
History and purpose
Constants were introduced to WebReports relatively early in the evolution of the product. As we (RKT) already had data sources that required references to Content Server objects (such as LiveReports), we had already encountered a fundamental problem with maintaining multiple linked objects as part of an application. The IDs assigned to each object (AKA Data IDs, Node IDs, Object IDs) are unique to the system where the objects were created. Re-creating an application with more than one Content Server object on a second system requires some kind of mapping to maintain the links. Fortunately, Content Server had, and still has, an XML export/import capability that allows data IDs to be resolved between systems. This functionality has been adapted in more recent years to build the Transport feature and is also used to manage CS Apps (WebReports applications).
As WebReports tend to have references to a variety of Content Server objects, we developed Constants as a way to define any other linked Content Server objects. As these Data ID values are explicitly defined as part of a WebReports object, any export/import code can map these IDs and set new IDs when the WebReports are imported to a new system. To support this ability, and to support user/group references, we created two new types of WebReports constants in addition to the simple string type: one for CS objects, and one for CS users and groups.
This brings me to the first of a few important points.
All Content Server object/user references (that are not already referenced by a tag) MUST be referenced by a constant. Literal IDs, i.e., values directly written into the source, are bad practice and our Application Analyzer product identifies such literals as application issues to be corrected.
Apart from anything else, the process of defining a constant using the WebReports interface, provides you with an object browser that automatically assigns the object ID to the constant. This avoids finding an object, loading it and then copy/pasting from the browser URL.
Another useful feature of WebReports Constants is that you can pre-define them on the Constants tab, and then reference them in the source as if they are existing WebReports tags (they appear on a list of available Constants). Alternatively, you can create them in the source (using whatever names make sense) and later go to the WebReports Constants tab where it can automatically add all the constant names it finds in the source, ready for you to define.
Shameless product plug: The Ravenblack Application Analyzer now supports the definition, viewing, or editing of constants directly in the source – see a quick demo in this video.
Advanced concepts
Now that we’ve been through the basics of Constants we can touch on some more advanced concepts.
Global Constant Files
The first advanced concept is Global Constant files, sometimes referred to as reference files. The basic idea is that any WebReport can reference any other WebReport in order to use its constants. There is a special field on the constants tab that allows this connection to be made.
This feature provides a variety of benefits, but also some potential pitfalls that are listed in the next section. The most obvious benefit is that one WebReport can be used to define all common constants used by an application. This reduces duplication, and the need to define the same constants over and over again for different WebReports. This file referencing can be “chained,” meaning that a WebReport being referenced as a Global Constant file, can also reference another WebReport as a Global Constant file. This referencing is cumulative as shown in the diagram below.
In some cases, a Global Constant WebReport is created purely for the purpose of defining common constants, i.e., the WebReport doesn’t have any content and is never “RUN” by the application. In other cases, the developer might already have a WebReport running in an application with several constants defined that can then be referenced by other running WebReports that require some of the same Constants. In more extreme cases (with bigger applications) there may be multiple Global Constant files with varying purposes being used by different parts of the application.
As described above, sometimes there will be Global Constant files pointing to other Global Constant files. This referencing and nesting can become very convoluted and can make it difficult to manage applications and may lead to performance issues.
Inheritance
A little-known feature of Constants is that any WebReport called as a sub-WebReport inherits the constants of the parent WebReport. This inheritance is by design, and it can be very useful when used with intent and understanding. Conversely for many applications that we have seen, constants are being added (or Global Constant files linked) despite the fact that the necessary constants are already available through inheritance. This can create duplication which in some cases can lead to errors, but in most cases worsens the performance of WebReports as they get further down a chain of sub-WebReports.
Another shameless product plug: Ravenblack is working on a new version of the sub-tag called RUNSWR--which calls sub-WebReports--to allow inheritance to be disabled when it is not required.
For existing applications, an awareness of this feature can help you to use it effectively, and more importantly, to improve the performance of your application.
Yet another shameless product plug: The Ravenblack Application Analyzer provides the ability to see the accumulation of constants for each sub-WebReport and is very useful to manage your constants.
The reason that constant inheritance can affect performance is that when a sub-WebReport is called, all the constants that exist in the parent WebReport, as well as any Global Constants, are copied into a list of constants available to the sub-WebReport. In some cases, this can lead to hundreds of constants being copied for each sub-WebReport call. When you add up multiple layers of sub-WebReport calls, this can potentially add measurable delay to the performance of a WebReport. Currently there is a bug in WebReports that causes this operation to be executed twice, magnifying this effect.
Example:
In one specific customer application we saw recently, there was a hierarchy of two Global Constant files linked together, resulting in a top-level Global Constants file that had more than a hundred constants. This Global Constants file was linked to various WebReports that were in turn linked as sub-WebReports. This resulted in hundreds of constants being copied multiple times unnecessarily, and significant duplication.
Performance recommendations:
We use our Application Analyzer product to review the accumulation and usage of Constants, both in our own development, and in auditing customer application. Even without this product, some knowledge of these principles when building an application can be very helpful. Ravenblack can provide guidance and advice around application design, but this list describes some common considerations:
Application Analyzer method: look at the Actual Constants view. It shows all of the constants that a WebReport has access to and which ones are actually being used. Note: If a WebReport has several constants that are not being used in its source, it's possible that it being used as a dedicated Global Constants WebReport.
Final (I promise) shameless product plug: The Application Analyzer can create the tree of sub-WebReport calls and also provides the ability to see all of the available constants, whether by reference, inheritance or any combination of these. It also shows which ones are actually being used.
INI Constants
One of the best kept secrets of WebReports Constants might be the INI feature. Basically, any setting in the opentext.ini file under the [WebReports] section, can be revealed using a constant. For example, if you have the setting: maxNestedSubWebReports in the [WebReports] section, this constant [LL_REPTAG_$maxNestedSubWebReports /] will return the value of this setting (typically 500).
This feature was not intended to be used for returning existing settings (many of which have been moved to KINI in recent versions of Content Server), but to allow Global Constants to be defined on a per-server basis.
Secure Constants
As of CS 22.3, there is a new constant type called Secure Constants. The purpose of this (and the only one as far as I know) is (from the release notes) to “store secret data that you can use with the LL_WEBREPORT_RESTCLIENT tag in either a WebReport or an ActiveView.” Once you define one of these constants you can use them in the RESTCLIENT tag using the { {constname} } type syntax. To define these constants, you need to use the WebReports administration pages, and the “Manage Secure Constants” section is fairly self-explanatory.
Nicknames versus Constants
I am aware that some developers use Content Server “nicknames” to provide object references, rather than Constants. We believe this approach is probably driven by the need to avoid some of the complexities and issues involved in migrating (transporting) applications. I’ll discuss the pros and cons of this approach in a future blog but am happy to respond to any questions in the meantime – shoot me an email at info@ravenblackts.com.
Summary