| Version 5.4
Introduction
Installation
SysAdmin
Network
Objects
Storage
E-mail
Real-Time
Access
Services
Directory
Clusters
Applications
Miscellaneous
Licensing
WebMail
Pronto!
PBX
Applications | Data | CLI/API | Rules | CG/PL | PBXApp | XIMSS | WebApp | WSSP | Helpers
# Web Server-Side Programming (WSSP) Scripting Elements Expressions Text Elements Structural Elements The CommuniGate Pro Web Application module processes a request for a WSSP file by calling a code component that produces a dataset - a dictionary containing text string keys and values, associated with those keys. Values can be text strings, numbers, timestamp, arrays, or dictionaries. See the Data section for more details on data types. For example, when a Domain default page is requested, the code component is called. The component processes request (HTML FORM) parameters and produces a dataset - a dictionary containing keyed values. For example, a dataset produced with the component processing the Login requests may contain `canAutoSignup`, `hasMailLists`, and `hasCertificate` keys. The Web Application module then uses the script code from a WSSP file to convert this dataset into a markup language (HTML, WML, etc.) page.

## Scripting Elements

The WSSP file is a markup language (usually - HTML) file with two additional types of elements:

- text elements, started and ended with double percent (`%%`) symbols
- structural elements, started with the `<!--%%` marker and ended with the `-->` marker.

The following is a sample of an WSSP document:

    <html>
    <body>

    <h1>Welcome to %%server%%. Your ID is %%ID%%.</h1>

    <!--%%IF EXISTS(lastLogin)-->
    Last time you visited us on %%lastLogin%%
    <!--%%ENDIF-->

    </body>
    </html>

This WSSP document contains the `%%server%%`, `%%ID%%`, and `%%lastLogin%%` text elements, and the `<!--%%IF EXISTS(lastLogin)-->` and `<!--%%ENDIF-->` structural elements (these text elements are fictitious, do not try to use these samples in your real .wssp pages).

If the WSSP document should contain non-ASCII symbols, the UTF-8 character set should be used. When the WSSP document is being processed, the Web Application module retrieves the `charset` string value from the produced data dictionary. If this value is not `UTF-8`, then the WSSP text is converted into this page charset.

## Expressions

The text and structural WSSP elements use expressions - combinations of names and symbols that specify the data to be retrieved from the data dictionary or from other available sources.

The WSSP scripting uses several types of expressions:

- data element
- array scanner
- keyed element
- indexed element
- function call
- boolean expression
- string constant

An alphanumeric string (such as `system` or `id`) is a data element name. The value of such an expression is the dataset value associated with this name. If the dataset does not have a specified key, the expression value is a null-value.
Example: the dataset contains the key `system` and its associated value is the `Sun Solaris` string, the value of the expression `system` is the string `Sun Solaris`.

The dataset dictionary is case-insensitive, so the data element names are case-insensitive, too.

An alphanumeric string followed by the `[]` symbols is interpreted as an index scanner name. It can be used only inside the `<!--%%FOREACH name...-->` ....`<!--%%ENDFOR name-->` structure where this index element is defined (see below). The index scanner names are case-insensitive.

An expression followed by the dot (`.`) symbol and an alphanumeric string is a keyed element. The expression before the dot symbol is calculated, and its value should be a dictionary. The alphanumeric string after the dot symbol specifies the key to be used to extract the value from that dictionary. If the value of the expression before the dot symbol is not a dictionary, or if it does not contain the specified key, the keyed element value is a null-value.
Keys can be specified as quoted strings, in this case they can specify non-alphanumeric symbols.
Example: the dataset contains the key `settings` and its associated value is the 2-element dictionary: `{OS = "Sun Solaris"; CPU = "sparc";}`. The value of the `settings.OS` expression is the `Sun Solaris` string, the value of the `settings."OS1"` expression is a null-value.

An expression followed by an index expression in square bracket symbols (`[index]`) is an indexed element. The expression before the square bracket is calculated, and its value should be an array or a dictionary. The index expression is calculated, and its value should be a number or a string representing a number. This number specifies which array element or dictionary key becomes the value of this indexed expression. If the value of the index expression is `0`, the first array element or the first dictionary key string is retrieved .
An index expression can be specified as a numeric constant.
If the value of the expression before the bracket symbol is not an array or a dictionary, or if the value of the index expression is not a number, or if the value of the index expression represents a number that is negative or is equal or greater than the number of array or dictionary elements, the value of the index expression is a null-value.

An alphanumeric string followed by the `(` symbol is a function call. Elements after the `(` symbol specify the function parameters, and they are followed by thes `)` symbol.
Function names are case-insensitive.
The list below specifies the available functions and their parameters.

Boolean expressions are two expressions separated with the `|` (OR) symbol, or with the `&` (AND) symbol, or with the `^` (XOR) symbol.
You can use parentheses to enclose expressions:

  `expression1 | expression2
  expression1 & expression2
  (expression1 & expression2) | expression3`

A boolean value of an expression is positive (true), if:

- the expression value is a string and it does not start with symbols `N`, `n`, `-`, or `0`, or
- the expression value is non-zero number.
- the expression value is a timestamp and it is not the "remote past" constant.

A string constant is a sequence of symbols enclosed into quote symbols. The quote symbols and the backslash symbols must be prefixed ("escaped") using the backslash `\` symbol: "My \"test\" string".

`SESSION(key)`
  This function can be used only in Session-based requests. The function value is the Session Dataset value associated with the string key. The key parameter can be specified as an alphanumeric string, or as a string constant.
  Example: the `SESSION(accountName)` expression value is the name of the CommuniGate Pro Account this session is opened for.
  The Session Dataset is case-insensitive. It contains the following keys and values:

  Key | Value
  --- | ---
  `ID` | a string with the unique identifier of this session
  `accountName` | a string with the session Account name
  `domainName` | a string with the name of the Domain the session Account belongs to
  `filesRef` | a string with the URL prefix needed to retrieve files from the session Skin
  `fullAccountName` | a string with the session Account full name: `accountName@domainName`
  `loginAddress` | a string specifying the network (IP) address the user was using when initiating this session
  `loginTime` | the timestamp with the session start time
  `selectableMailboxes` | an array with the names of all "selectable" Mailboxes
  `addressBooks` | an array with the names of all available Address Books
  `webFolders` | an array with the File Storage folder names
  `selectedMailbox` | a string with the name of the target Mailbox for the last Copy/Move operation
  `selectedAddressBook` | a string with the name of the currently selected Address Book.
  `selectedWebFolder` | a string with the name of the target File Storage folder for the last Store File In operation
  `webSiteEnabled` | this `"YES"` string element exists if the storage limit for the File Storage is not set to zero
  `openMailboxes` | a dictionary with all currently opened Mailboxes (each dictionary key is the Mailbox UTF8 name).

  CG/PL Web Applications can insert additional elements into the Session Dataset.
`SETTINGS(key)`
  This function can be used only in Session-based requests. The function value is the effective WebUser setting value associated with the string key. The key parameter can be specified as an alphanumeric string, or as a string constant.
`ACCOUNTSETTINGS(key)`
  This function can be used only in Session-based requests. The function value is the effective Account setting value associated with the string key. The key parameter can be specified as an alphanumeric string, or as a quoted string.
`INCLUDEARG(number)`
  This function can be used only inside an include file. The key should be a decimal number specifying the parameter number of the `<!--%%INCLUDE-->` element that invoked this include file.
  The first parameter has the number 0.
  If the `<!--%%INCLUDE-->` element did not specify enough parameters, the function value is a null-value.
`EXISTS(expression)`
  The parameter is an expression. Its value is calculated, and the function returns the string `"YES"` if the calculated value is not a null-value, or the string `"NO"` if the returned value is a null-value.
`DOESNOTEXIST(expression)`
  The parameter is an expression. Its value is calculated, and the function returns the string `"NO"` if the calculated value is not a null-value, or the string `"YES"` if the returned value is a null-value.
`YESNO(expression)`
  The parameter is an expression. Its boolean value is calculated, and the value is positive (true), the function returns the string `"YES"`, otherwise it returns the string `"NO"`.
`BOOLARRAY()`
  The value is a 2-element array, containing the strings `"NO"` and `"YES"`.
`NOT(expression)`
  The parameter is an expression. Its boolean value is calculated, and the function returns a null-value if the value is positive (true), otherwise the function returns the string `"YES"`.
`EQUALS(expression1 AND expression2)`
  Both expressions are calculated, and if the calculated values match (including the case when both expressions return a null-value), the function returns the string `"YES"`. Otherwise the function returns a null-value.
`EQUALSNOCASE(expression1 AND expression2)`
  Both expressions are calculated. The function returns the string `"YES"` if both calculated values are a null-value or if both values are strings and these strings match using the ASCII case-insensitive comparison operation. In all other cases the function returns a null-value.
`EQUALS(expression AND string)`
  The value of the expression is calculated and compared with the string, specified as a quoted string. If the value matches the string, the function returns the string `"YES"`. Otherwise the function returns a null-value.
`EQUALSNOCASE(expression AND string)`
  The value of the expression is calculated and compared with the string, specified as a quoted string. If the value matches the string using the ASCII case-insensitive comparison operation, the function returns the string `"YES"`. Otherwise the function returns a null-value.
`ISINDEX(expression IN scanner)`
  The scanner should be the name of the `<!--%%FOREACH scanner IN ...-->` construct surrounding the current portion of the script code. The expression value is calculated, and if its numeric value matches the current index in the array this scanner is used for, the function returns the string `"YES"`. Otherwise the function returns a null-value.
`ISFIRST(scanner)`
  The scanner should be the name of the `<!--%%FOREACH scanner IN ...-->` construct surrounding the current portion of the script code. If the current value of the array index is zero, the function returns the string `"YES"`. Otherwise the function returns a null-value.
`ISLAST(scanner)`
  The scanner should be the name of the `<!--%%FOREACH scanner IN ...-->` construct surrounding the current portion of the script code. If the current value of the array index is equal to the number of array or dictionary elements minus one, the function returns the string `"YES"`. Otherwise the function returns a null-value.
`ISEVEN(scanner)`
  The scanner should be the name of the `<!--%%FOREACH scanner IN ...-->` construct surrounding the current portion of the script code. If the current value of the index is even, the function returns the string `"YES"`. Otherwise the function returns a null-value.
`ISHALF(scanner)`
  The scanner should be the name of the `<!--%%FOREACH scanner IN ...-->` construct surrounding the current portion of the script code. If the current value of the index is equal to the number of array or dictionary elements divided by 2, the function returns the string `"YES"`. Otherwise the function returns a null-value.
`CHECKED(expression)`
  The parameter is an expression. Its boolean value is calculated, and if its positive (true), the function returns the string `"checked"`, otherwise the function returns a null-value.
`HASPARENTMAILBOX(expression)`
  The parameter is an expression. Its value is calculated, and the function returns the string `"YES"` if the calculated value is a string, representing a name of hierarchical Mailbox. Otherwise the function returns a null-value.
`ISSTRING(expression)`
  The parameter is an expression. Its value is calculated, and the function returns the string `"YES"` if the calculated value is a string. Otherwise the function returns a null-value.
`ISNUMBER(expression)`
  The parameter is an expression. Its value is calculated, and the function returns the string `"YES"` if the calculated value is a number. Otherwise the function returns a null-value.
`ISARRAY(expression)`
  The parameter is an expression. Its value is calculated, and the function returns the string `"YES"` if the calculated value is an array. Otherwise the function returns a null-value.
`ISDICTIONARY(expression)`
  The parameter is an expression. Its value is calculated, and the function returns the string `"YES"` if the calculated value is a dictionary. Otherwise the function returns a null-value.
`ISDATE(expression)`
  The parameter is an expression. Its value is calculated, and the function returns the string `"YES"` if the calculated value is a timestamp. Otherwise the function returns a null-value.
`ISDATA(expression)`
  The parameter is an expression. Its value is calculated, and the function returns the string `"YES"` if the calculated value is a datablock object. Otherwise the function returns a null-value.
`NULL()`
  The value of this function is a null-value.
`EMPTYSTRING()`
  The value of this function is an empty string.
`EMPTYARRAY()`
  The value of this function is an array with zero elements.
`EMPTYDICTIONARY()`
  The value of this function is an empty dictionary.
`CURRENTTIME()`
  This function value is a timestamp - the current global time.
`SELECTEDLANGUAGE()`
  This function value is a string - the currently selected language name.
`SELECTEDTIMEZONE()`
  This function value is a string - the currently selected time zone name.
`STRING(key)`
  The value of this function is the object associated with the key in the Skin Text Dataset. This object should be a string, otherwise the function returns a null-value. The key can be specified either as a quoted string literal, or as an expression - the expression value is calculated and used as the key.
`DICTIONARY(key)`
  The value of this function is the object associated with the key in the Skin Text Dataset. This object should be a dictionary, otherwise the function returns a null-value. The key can be specified either as a quoted string literal, or as an expression - the expression value is calculated and used as the key.
`ARRAY(key)`
  The value of this function is the object associated with the key in the Skin Text Dataset. This object should be an array, otherwise the function returns a null-value. The key can be specified either as a quoted string literal, or as an expression - the expression value is calculated and used as the key.
`TRANSLATE(string USING dictionary)`
  The string parameter is an expression that should return a string value; the dictionary parameter is an expression that should return a dictionary value. If the dictionary contains a string value for the key specified with the first parameter value, the function returns this string. Otherwise the value of the string parameter is returned;
  Example: the dataset contains the element `boxName` with the string value `INBOX`, and the element `boxNames` with the dictionary value `{INBOX = Incoming; Trash = "Trash Can";}`. The value of the `TRANSLATE(boxName USING boxNames)` expression is the `"Incoming"` string.
`CONTAINS(string IN array)`
  The function returns the string `"YES"` if the value of the array parameter is an array, and the string is equal to one of the array elements. Otherwise the function returns a null-value.
  The string can be specified either as a quoted string literal, or as an expression.
`RANDOMELEMENT(array)`
  The array parameter is an expression that should return an array value; The value of this function is a randomly-selected element from that array.
`MONTHNAMES()`
  The function returns a fixed array with 12 string elements: `("Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec")` .
`WEEKDAYS()` and `WEEKDAYS(expression)`
  If expression is not specified, the function returns a fixed array with 7 string elements: (`Sun`,`Mon`,`Tue`,`Wed`,`Thu`,`Fri`,`Sat`).
  If expression is specified, its result should be a string with one of the weekday names, and the function returns an array with 7 weekday names, starting with the specified weekday:
    `WEEKDAYS(startOfWeek)`
    returns `("Tue","Wed","Thu","Fri","Sat","Sun","Mon")` if the value of the startOfWeek variable is `"Tue"`.
`KNOWNCHARSETS()`
  The function returns a fixed array with string elements - names of character sets known to the system `("ISO-8059-1","ISO-2022-jp","KOI8-R", ...)` .
`KNOWNTIMEZONES()`
  The function returns a fixed array with string elements - names of time zones known to the system `("NorthAmerica/Pacific","Europe/Central","(+0900) Japan/Korea", ...)`
`REQUESTSECURE()`
  The function returns the string `"YES"` if the current HTTP request is secured (i.e. is sent via the HTTPS protocol), otherwise the function returns a null-value.

## Text Elements

Text elements are specified using double percent markers. The body of a text element is an expression with an optional prefix.

`%%expression%%`
  The expression is calculated. If the expression value is a string or a number, it substitutes substitutes the text element in the resulting markup code.
  Otherwise the entire text element is removed from the resulting markup code.
`%%HTML:expression%%`
  The expression is calculated. If the expression value is a string or a number, it substitutes substitutes the text element using HTML escape symbols. A string value is converted from the UTF-8 charset into the required charset.
  Otherwise the entire text element is removed from the resulting markup code.
  Example:
    if the expression result is the `">=GO=>"` string, the text element is substituted with:

        &gt;=GO=&gt;

`%%HTMLUTF8:expression%%`
  The expression is calculated. If the expression value is a string or a number, it substitutes substitutes the text element using HTML escape symbols (the string is not converted from the UTF-8 charset into the page charset).
  Otherwise the entire text element is removed from the resulting markup code.
  Example:
    if the expression result is the `>=GO=>` string, the text element is substituted with:

        &gt;=GO=&gt;

`%%URL:expression%%`
  The expression is calculated. If the expression value is a string or a number, it substitutes the text element using URL escape symbols.
  Otherwise the entire text element is removed from the resulting markup code.
  Example:
    if the expression result is the `"Stop It?"` string, the text element is substituted with:

        Stop%20It%3F

`%%MAILBOXRAWNAME:expression%%`
  The expression is calculated. If the value is not a string, then the entire text element is removed from the resulting markup code. If the result is a string, it is converted from the IMAP-specified Mailbox name encoding into the UTF-8 charset, then it is converted into the required charset, and the converted string substitutes the text element using HTML escape symbols.
`%%MAILBOXNAME:expression%%`
  The expression is calculated. If the value is not a string, then the entire text element is removed from the resulting markup code. If the result is a string X, the `TRANSLATE(X USING DICTIONARY("MailboxNames"))` expression is calculated. Then the prefix works in the same way as the `MAILBOXRAWNAME:` prefix.
`%%MAILBOXLASTNAME:expression%%`
  The expression is calculated. If the value is not a string, then the entire text element is removed from the resulting markup code. If the result is a string X, it is interpreted as a Mailbox name. If the Mailbox name is a hierarchical one, only the last part of the name is used, otherwise the entire name is used. The name (or its last part) is converted in the same way as for the `MAILBOXNAME:` prefix.
`%%URLMAILBOXPARENT:expression%%`
  The expression is calculated. If the value is not a string, then the entire text element is removed from the resulting markup code. If the result is a string X, it is interpreted as a Mailbox name. If the Mailbox name is a hierarchical one, the name of the parent Mailbox is used. It is converted in the same way as for the `URL:` prefix. If the Mailbox name is not a hierarchical one, the element is removed from the resulting markup code.
`%%JAVASCRIPT:expression%%`
  The expression is calculated. If the value is not a string or a number, then the entire text element is removed from the resulting markup code. If the result is a string or a number, it substitutes the text element using escape symbols needed for JavaScript strings. The result is converted into Unicode and all non-ASCII symbols are presented using the `\uhhhh` escape sequences.
  Note: this prefix does not put any quotation marks around the string.
  Example:
    if the expression result is the `'What do "they" think?'` string, the text element is substituted with:

        What do \"they\" think

`%%JSON:expression%%`
  The expression is calculated. The expression is converted to a string using JSON (JavaScript Object Notation) representation, and this string substitutes the text element. Timestamp objects are represented as RFC822-formatted date strings.
  Example:
    if the expression result is the `( 'What do "they" think?', #123)` array, the text element is substituted with:

        ["What do \"they\" think",124]

`%%SIZE:expression%%`
  The expression is calculated. If the value is not a string or a number, then the entire text element is removed from the resulting markup code.
  If the expression value is a string, it is converted into a numeric value (the number of bytes).
  The string should contain some number and, optionally, the `k` or `K` suffix (in this case the number is multiplied by 1024), or the `m` or `M` suffix (in this case the number is multiplied by 1048576).
  Alternatively, a string can start with a letter `u` or `U`, in this case the converted number of bytes is -1.
  If the expression value is a number, its numeric value is used.
  The resulting number is converted into a "size string", using the dictionary retrieved with the `DICTIONARY("SizePictures")` expression. If the number is negative, the dictionary is used to translate the string `unlimited`, and the result is used to replace this text element using the same conversions as used for the a text element with the `HTML:` prefix.
  The calculated number of bytes is checked to see if it represents an even number of Megabyte or Kilobytes, and that number is greater than one. Then a string value associated with the keys `"M"`, `"K"`, or `""` (empty string) is retrieved from the dictionary. The string is expected to contain the `^0` symbol combination which is replaced with the number of megabytes, Kilobytes, or bytes specified with the expression value. The resulting string is processed with the method used for the `HTML:` text element prefix.
  If the `DICTIONARY("SizePictures")` expression result is a null-value, or this dictionary does not contain a string value for the required key, the resulting string is built using the number and the key name (`20M`, `1345K`, `182345777`).
`%%ROUNDSIZE:expression%%`
  This prefix works in the same way as the `SIZE:` prefix, but the numeric expression value can be modified: if the value is equal or larger than 10000, then it is converted into "Kilo" (value = value / 1024 * 1024), and if the value is equal or larger than 10240000, it is converted to "Mega" (value = value / 1048576 * 1048576).
`%%TIME:expression%%`
  The expression is calculated.
  If the result is a null-value, then the entire text element is removed from the resulting markup code.
  If the result is a number, its value is interpreted as the number of seconds.
  If the result is a string, it is converted into a numeric value (the number of seconds):
  The string should contain some number and, optionally, the `s` or `S` suffix, or the `m` or `M` suffix (in this case the number is multiplied by 60), or the `h` or `H` suffix (in this case the number is multiplied by 3600), or the `d` or `D` suffix (in this case the number is multiplied by 86400).
  The resulting number is converted into a "time string", using the dictionary retrieved with the `DICTIONARY("TimePictures")` expression.
  The calculated number of seconds is checked to see if it represents an even number of weeks, days, hours, or minutes, and if that number is greater than 1. Then a string value associated with the keys `weeks`, `days`, `hours`, `minutes`, or `seconds` is retrieved from the dictionary. The string is expected to contain the `^0` symbol combination which is replaced with the number of weeks, days, hours, minutes, or seconds specified with the expression value. The resulting string is converted from the UTF-8 into the required charset and the converted string substitutes the text element using HTML escape symbols.
  If the `DICTIONARY("TimePictures")` expression result is a null-value, or this dictionary does not contain a string value for the required key, the resulting string is built using the number, a space, and the key name (`3 weeks`, `11 hours`, `5 seconds`).
  Example:
    If the data element `elapsedTime` is the `2400` string, then the text element

        %%TIME:elapsedTime%%

    will be substituted with the following string:

        40 minutes

    If the `DICTIONARY("TimePictures")` exists and contains the string `"^0mins"` as the `minutes` value, then the text element

        %%TIME:elapsedTime%%

    will be substituted with the

        40mins

    string.
`%%DATETIME(formatName):expression%%`
  The expression is calculated. If the value is not of the timestamp type, then the entire text element is removed from the resulting markup code. If the value is a timestamp, it is converted into a text string using the specified format.
  The format parameter can be specified as an alphanumeric atom, or as a quoted string.
  The format string is the result of the `DICTIONARY("DatePictures").formatName` expression. If this expression does not result in a string value, the `((^h:^m:^s ^W ^D-^M-^Y))` string is used instead.
  The format string is processed by replacing the following symbol combinations with the actual timestamp value parts:

  symbols | substituted with
  `^D` | the day of month (2-digit)
  `^d` | the day of month (1- or 2-digit)
  `^M` | the month name (one of those returned with the MONTHNAMES() function), translated using `DICTIONARY("DatePictures")`
  `^N` | the month number (2-digit, from `01` to `12`)
  `^Y` | the year number (2-digit)
  `^y` | the year number (4-digit)
  `^s` | the seconds value (2-digit)
  `^m` | the minutes value (2-digit)
  `^H` | the hours value (2-digit), from `00` to `23`
  `^h` | the hours value (1- or 2-digit), from `12`,`1` to `11`
  `^t` | the `AM` or `PM` string, translated using `DICTIONARY("DatePictures")`
  `^w` | the weekday number (Sun - 0)
  `^W` | the weekday name (one of those returned with the WEEKDAYS() function), translated using `DICTIONARY("DatePictures")`

  The resulting string is placed into the markup code using the `HTML:` prefix processing.
`%%LOCALDATETIME(formatName):expression%%`
  Processing is the same as for the `DATETIME(formatName)` prefix, but the timestamp value is converted into the local time first.
`%%DATETIMEAS(format):expression%%`
  The expression is calculated. If the value is not of the timestamp type, then the entire text element is removed from the resulting markup code. If the value is a timestamp, it is converted into a text string using the specified format.
  The format parameter should be a quoted string or an expression with a string value. This string is used as the format string.
`%%LOCALDATETIMEAS(format):expression%%`
  Processing is the same as for the `DATETIMEAS(format)` prefix, but the timestamp value is converted into the local time first.
`%%DATE:expression%%`
  Processing is the same as for the `DATETIME("dateOnly")` prefix.
`%%LOCALDATE:expression%%`
  Processing is the same as for the `LOCALDATETIME("dateOnly")` prefix.
`%%DATEWEEK:expression%%`
  Processing is the same as for the `DATETIME("dayAndDate")` prefix.
`%%DATETIME:expression%%`
  Processing is the same as for the `DATETIME("dateAndTime")` prefix.
`%%LOCALDATETIME:expression%%`
  Processing is the same as for the `LOCALDATETIME("dateAndTime")` prefix.
`%%DATETIMESHORT:expression%%`
  Processing is the same as for:
  - the `DATETIME("timeOnly")` prefix if the timestamp value specified with the expression is "very close" to the current time (the absolute difference is less than 22 hours),
  - the `DATETIME("monthDate")` prefix if the timestamp value specified with the expression is "close" to the current date (the absolute difference is less than 180 days),
  - the `DATETIME("dateOnly")` prefix in all other cases.
`%%LOCALDATETIMESHORT:expression%%`
  Processing is the same as for the `DATETIMESHORT:` prefix, but the the expression value is converted into the local time first.
`%%HTMLTRUNCATED(number):expression%%`
  The expression is calculated. If the value is not a string, then the entire text element is removed from the resulting markup code. If the result is a string, the string is truncated, then it is converted from the UTF-8 charset into the required charset, and the converted string substitutes the text element using HTML escape symbols. Not more than the number of symbols ("glyphs") are substituted. If the string has more glyphs, the `..`symbols are added after the string.
  Example: if the expression result is the `"Test Subject"` string, the text element substituted with the HTMLTRUNCATED(10) prefix is

      Test Subje..

`%%HTMLTRUNCATED(expression1):expression%%`
  The same as the above, but the expression1 parameter is an expression that is calculated. The expression1 should have a numeric value. This value specifies the number of glyphs to be taken from the expression string.
  Example: `HTMLTRUNCATED(STRING("FieldLength")):theField`
`%%HTMLSUBST(parameter0,parameter1,...):expression%%`
  The all parameterN expressions and the expression is calculated. If the value of the expression is not a string, then the entire text element is removed from the resulting markup code. If the result is a string, all its ^N substrings are replaced with the string values of parameterN expression (`^0` substrings are replaced with the value of parameter0, `^1` substrings are replaced with the value of parameter1, etc.). If the parameter value is not a string, the ^N substring is removed.
  The resulting string is converted from the UTF-8 charset into the required charset, and the converted string substitutes the text element using HTML escape symbols.
  Example: if the `text1` element of the Text Dataset is the `"My String1"` string, the var2 element of the Result Dataset is `My Var2`, and the `text2` element of the Text Dataset is the `"comparing ^0 & ^1"` string, then the following code:

      %%HTMLSUBST(STRING("text1"),var2):STRING("text2")%%

  will be substituted with

      comparing My String1 &amp; My Var2

  .
`%%URLSUBST(parameter0,parameter1,...):expression%%`
  The same as the above, but the resulting string substitutes this text element using URL escape symbols.
`%%INDEX:scanner%%`
  The scanner should be the name of the `<!--%%FOREACH scanner IN ...-->` construct surrounding the current portion of the script code. The scanner index decimal value substitutes this text element. For the first element the value 0 is used.
`%%INDEX1:scanner%%`
  The scanner should be the name of the `<!--%%FOREACH scanner IN ...-->` construct surrounding the current portion of the script code. The scanner index decimal value substitutes this text element. For the first element the value 1 is used.
`%%DUMP:expression%%`
  The expression is calculated. And the value textual representation substitutes this text element.
`%%LENGTH:expression%%`
  The expression is calculated.
  If the value is a string, the string length (in bytes) substitutes this text element.
  If the value is an array, the number of array elements substitutes this text element.
  If the value is a dictionary, the number of dictionary key-value pairs substitutes this text element.
  Otherwise, this text element is removed
`%%CENTS:expression%%`
  The expression is calculated. Its numeric value is converted into a numeric string with at least 3 decimal digits, and the period (`.`) symbol is inserted before the last 2 decimal digits. The resulting string substitutes this text element.

## Structural Elements

The structural elements start with the `<!--%%` symbols and end with the `-->` symbols. The structural elements themselves are always removed from the resulting markup code.

`<!--%%IF expression-->`
  This structural element may be followed with one or more
  `<!--%%ELIF expression-->`
  element(s), then it may be followed with the
  `<!--%%ELSE-->`
  element, and then it must be followed with the
  `<!--%%ENDIF-->`
  element.
  The boolean value of the expression in the IF element is calculated, then the values of the expressions in the ELIF elements (if any exists) are calculated, till one of those values is positive (true).
  If an element with such a value is found, the portion of the script between this element and the following ELIF, ELSE, or ENDIF element is processed.
  If an element is not found, and there is no ELSE element, the script between the IF and ENDIF elements is removed completely, otherwise the portion between the ELSE and ENDIF elements is processed.
  Example:

        <!--%%IF EXISTS(lastLogin)-->We have not seen you since <i>%%HTML:lastLogin%%<iI>
        <!--%%ELSE-->Welcome, new user!
        <!--%%ENDIF-->

    In this example, if the dataset contains the `lastLogin` element with the `20-Apr-2007` string value, this script portion will produce
    `We have not seen you since <i>20-Apr-2007</i>`
    If the dataset does not contain the `lastLogin` element, this script portion will produce
    `Welcome, new user!`
`<!--%%FOREACH scanner in expression-->`
or
`<!--%%FORALL scanner in expression-->`
  This structural element can be followed with the
  `<!--%%EMPTYFOR scanner-->`
  element, and must be followed with the
  `<!--%%ENDFOR scanner-->`
  element. All elements should have the same scanner alphanumeric string.
  The value of the expression is calculated. The resulting value should be an array or a dictionary.
  The portion of the script between the `<!--%%FOREACH scanner` ...`-->` and `<!--%%EMPTYFOR scanner-->` elements or (if the `<!--%%EMTPYFOR scanner-->` element does not exist) the portion of the script between the `<!--%%FOREACH scanner` ...`-->` and `<!--%%ENDFOR scanner-->` elements is processed repeatedly, for each array or dictionary element.
  Expressions specified in that portion of the script (called the "loop body") can use the `scanner[]` scanner reference to access the current element of the expression value.
  If the expression is a dictionary, then the `scanner[*]` key reference can be used to access the current element key.
  If the expression value is not an array or dictionary, or if it is an empty array or dictionary, and the `<!--%%EMPTYFOR scanner-->` element is specified, the portion of the script between the `<!--%%EMPTYFOR scanner-->` and `<!--%%ENDFOR scanner-->` elements is processed.
  Example:

        <table border="1">
        <tr><td>File Name</td><td>File Size</td></tr>
        <!--%%FOREACH elem in fileList-->
        <tr><td>%%HTML:elem[].name%%</td><td>%%elem[].size%%</td></tr>
        <!--%%EMPTYFOR elem-->
        <tr><td colspan="0">&nbsp;</td></tr>
        <!--%%ENDFOR elem-->
        </table>

    In this example, the data element `fileList` is expected to be an array of dictionaries. Each dictionary is expected to contain string values for keys `name` and `size`.
    If the `fileList` value is
    `({name=MyReport; size=2300;},{name="My Old Report"; size=4000;})`
    then this portion of the script will produce the following HTML code:

        <table border="1">
        <tr><td>File Name</td><td>File Size</td></tr>
        <tr><td>MyReport</td><td>2300</td></tr>
        <tr><td>My Old Report</td><td>4000</td></tr>
        </table>

  The `<!--%%IF` ...`-->` ...`<!--%%ELSE-->` ...`<!--%%ENDIF-->` constructs and the `<!--%%FOREACH` ...`-->` ... `<!--%%ENDFOR` ...`-->` constructs can be nested.
`<!--%%FOREACHINC scanner in expression-->`
  The same as the `<!--%%FOREACH` construct, but it repeats the "loop body" code portion one time more than the number of elements in the expression value array or dictionary.
  For this additional run, the `scanner[*]` and `scanner[]` values are null-values.
  If the expression value is not an array or a dictionary, the loop body is not repeated, and the portion between the `<!--%%EMPTYFOR scanner-->` and `<!--%%ENDFOR scanner-->` elements (if any) is processed.
`<!--%%FOREACHREV scanner in expression-->`
  The same as the `<!--%%FOREACH` construct, but it repeats the "loop body" code portion for each element in the expression value array or dictionary, taken in the reversed order (the last element first).
`<!--%%INCLUDE filename`[`( parameter1` [`, parameter2 ...` ]`)`]`-->`
  filename should be a quoted string or an expression with a string value.
  The file with the filename name is retrieved from the same Skin this script is retrieved from. The file should contain some WSSP code. This code is executed within the current context (using the same dataset).
  The resulting markup code is used to replace this structural element.
  It is recommended to use the `.wssi` file name extension for files designed to be used with the INCLUDE element.
  The INCLUDE elements can be nested, this means that `.wssi` files can include other `.wssi` files.
  Unlike the `#include` operators in the C and C++ languages, this operator is a real operator, not a pre-processor operator. As a result, if an `<!--%%INCLUDE filename-->` element is used within a `<!--%%FOREACH` ...`-->` ... `<!--%%ENDFOR` ...`-->` construct, the filename code can be executed several times, once for each element of the array used in the FOREACH construct.
  You can specify one or more parameters, enclosing them into parentheses and separating them with the comma symbol. Each parameter is an expression that is evaluated before the filename code is executed.
  The filename code can reference its parameter values using the `INCLUDEARG` function.
`<!--%%NUMERICMENU selected` [`DEFAULT selectedDefault` ]`IN (number1,number2,....,numberN)` [`DISPLAY dictionary`]`-->`
  This element is substituted with a sequence of the `<option value="value">presentation` string elements.
  >The number of elements and the value used for each element are defined by the list of numeric numbers - number1,number2,....,numberN. These numbers should be specified in the ascending order, and these numbers should not be less than -1.
  The selected expression is calculated, and its value should be a string. The string numeric value is used to add the keyword `selected` to the `<option value="value">` element that has the same value.
  The `DISPLAY` keyword and the dictionary expression can be omitted. In this case, the presentation strings are the same as the value strings, this means that these strings are numbers.
  Example:
    The dataset element `sizeLimit` is the `200` string.
    The element:

        <!--%%NUMERICMENU sizeLimit IN (-1,0,100,200,300)-->

    will be substituted with the following markup text:

        <option value="-1">-1<option value="0">0
        <option value="100">100<option value="200" selected>200<option value="300">300

  If the `DISPLAY` keyword and the dictionary expression are specified, the expression is calculated. If the expression value is a dictionary, then the presentation strings are the numeric values "translated" using this dictionary, the results are converted into the required charset and placed using the HTML escape symbols.
  Example:
    The dataset element `sizeLimit` is the `200` string.
    The Skin Text Dataset contains the `Limits` dictionary: `{"-1" = Unlimited; 0 = "Off & Shut";}`.
    The element:

        <!--%%NUMERICMENU sizeLimit IN (-1,0,100,200,300) DISPLAY DICTIONARY("Limits")-->

    will be substituted with the following markup text:

        <option value="-1">Unlimited<option value="0">Off &amp; Shut
        <option value="100">100<option value="200" selected>200<option value="300">300

  If the keyword `DEFAULT` with the selectedDefault expression are specified, an additional `<option value="-2">defaultPresentation` string is added before the sequence. If the selected expression value is a null-value, this string element will have the keyword `selected` added.
  The defaultPresentation string is the `DefaultValuePicture` string retrieved from the Skin Text Dataset. This string should contain the `^0` symbol combination. This symbol combination is substituted with the selectedDefault expression value. If the DISPLAY dictionary is specified, the selectedDefault expression value is translated first.
  Example:
    The dataset element `sizeLimit` is the `200` string.
    The dataset element `defLimit` is the `-1` string.
    The Skin Text Dataset contains the `DefaultValuePicture` string: `default(^0)`.
    The Skin Text Dataset contains the `Limits` dictionary: `{"-1" = Unlimited; 0 = "Off & Shut";}`.
    The element:

        <!--%%NUMERICMENU sizeLimit DEFAULT defLimit IN (-1,0,100,200,300) DISPLAY DICTIONARY("Limits")-->

    will be substituted with the following markup (HTML) text:

        <option value="-2">default(Unlimited)
        <option value="-1">Unlimited<option value="0">Off &amp; Shut
        <option value="100">100<option value="200" selected>200<option value="300">300

`<!--%%TIMEMENU selected` [`DEFAULT selectedDefault` ]`IN (time1,time2,....,timeN)` [`DISPLAY dictionary`]`-->`
  This element is processed in the same way as the NUMERICMENU element. The timeN units specify time intervals converted to numeric values (the number of seconds) using the same algorithm as the algorithm used for the `TIME:` text elements.
  The selected and selectedDefault expressions should return strings. Each string is converted into a numeric value (the number of seconds) using the same algorithm as the algorithm used for the `TIME:` text elements.
  Values are translated using the specified `DISPLAY` dictionary. If the `DISPLAY` dictionary is not specified or it does not contain a string for the given value, the presentation time strings are composed using the same method as the method used for the `TIME:` text elements.
`<!--%%SIZEMENU selected` [`DEFAULT selectedDefault` ]`IN (size1,size2,....,sizeN)` [`DISPLAY dictionary`]`-->`
  This element is processed in the same way as the NUMERICMENU element. The sizeN units specify data sizes converted to numeric values (the number of bytes) using the same algorithm as the algorithm used for the `SIZE:` text elements.
  The selected and selectedDefault expressions should return strings. Each string is converted into a numeric value (the number of bytes) using the same algorithm as the algorithm used for the `SIZE:` text elements.
  Values are translated using the specified `DISPLAY` dictionary. If the `DISPLAY` dictionary is not specified or it does not contain a string for the given value, the presentation size strings are composed using the same method as the method used for the `SIZE:` text elements.
`<!--%%ENUMMENU selected` [`DEFAULT selectedDefault` ]`IN valueSet` [`DISPLAY dictionary`]`-->`
  This element is substituted with a sequence of the `<option value="value">presentation` string elements.
  The number of elements and the value used for each element are defined by the value of the valueSet expression. This value should be an array of strings. The value in each element is the string index in the valueSet array result.
  The selected expression is calculated, and its value should be a string. The keyword `selected` is added to the `<option value="value">` element created for the the valueSet array element that matches the selected expression result.
  The `DISPLAY` keyword and the dictionary expression can be omitted. In this case, the presentation strings are the same as the valueSet result elements.
  Example:
    The dataset element `color` is the `"Green"` string.
    The dataset element `colors` is the `("Blue", "Green", "Red")` array.
    The element:

        <!--%%ENUMMENU color IN colors-->

    will be substituted with the following markup (HTML) text:

        <option value="0">Blue<option value="1" selected>Green<option value="2">Red

  If the `DISPLAY` keyword and the dictionary expression are specified, the expression is calculated. If the expression value is a dictionary, it is used to "translate" the valueSet array strings before converting them into the required charset and placing into the resulting markup text using the HTML escape symbols.
  Example:
    The dataset element `color` is the `"Green"` string.
    The dataset element `colors` is the `("Blue", "Green", "Red")` array.
    The Skin Text Dataset contains the `Colors` dictionary: `{Blue = "Night Blue"; Green = "Grass Green";}`.
    The element:

        <!--%%ENUMMENU color IN colors DISPLAY DICTIONARY("Colors")-->

    will be substituted with the following markup (HTML) text:

        <option value="0">Night Blue<option value="1" selected>Grass Green<option value="2">Red

  If the keyword `DEFAULT` with the selectedDefault expression are specified, an additional `<option value="-1">defaultPresentation` string is added before the sequence. If the selected expression value is a null-value, this string element will have the keyword `selected` added.
  The defaultPresentation string is the `DefaultValuePicture` string retrieved from the Skin Text Dataset. This string should contain the `^0` symbol combination. This symbol combination is substituted with the selectedDefault expression value. If the `DISPLAY` dictionary is specified, the selectedDefault expression value is translated first.
  Example:
    The dataset element `color` is the `"Green"` string.
    The dataset element `defColor` is the `"Blue"` string.
    The dataset element `colors` is the `("Blue", "Green", "Red")` array.
    The Skin Text Dataset contains the `DefaultValuePicture` string: `default(^0)`.
    The Skin Text Dataset contains the `Colors` dictionary: `{Blue = "Night Blue"; Green = "Grass Green";}`.
    The element:

        <!--%%ENUMMENU color DEFAULT defColor IN colors DISPLAY DICTIONARY("Colors")-->

    will be substituted with the following HTML text:

        <option value="-1">default(Night Blue)<option value="0">Night Blue
        <option value="1" selected>Grass Green<option value="2">Red

`<!--%%BOOLMENU selected` [`DEFAULT selectedDefault` ]`` [`DISPLAY dictionary`]`-->`
  This element is substituted with a sequence of the `<option value="value">presentation` string elements in the same way the ENUMMENU element is processed.
  Unlike the ENUMMENU element, this element does not contain the `IN valueSet` part: the built-in array `("NO","YES")` array is used instead.
`<!--%%MAILBOXMENU selected` [`DEFAULT selectedDefault` ]`IN mailboxList` [`NOINBOX` ]`-->`
  This element is substituted with a sequence of the `<option value="value">presentation` string elements in the same way the ENUMMENU element is processed.
  The values of the selected and selectedDefault expressions are converted in the same way as they are converted for a text element with the `MAILBOXNAME:` prefix, using the `MailboxNames` dictionary from the Skin Text Dataset, this is why MAILBOXMENU elements do not have the DISPLAY part.
  If the NOINBOX keyword is specified, the INBOX Mailbox (if exists in mailboxList) is not displayed.
`<!--%%DAYTIMEMENU selected` [`DEFAULT selectedDefault` ] [`PERIOD timePeriod` ] `-->`
  This element is substituted with a sequence of the `<option value="value">presentation` string elements to form a time-of-day menu. Each value is the time in seconds, and presentation is a string presenting this time using the "hourMinute" format (or the "^H:^m" format string, if the "hourMinute" element is not found in the `DICTIONARY("DatePictures")` data.
  The time values are generated from the midnight (`00:00`) till 23:59 with the timePeriod step (specified in minutes).
  If the PERIOD keyword and the timePeriod value are not specified, the 30 minutes (1800 seconds) step is used.
  If the PERIOD keyword is specified, the timePeriod value can be either a numeric constant specifying the period in minutes, or an expression. The expression value is calculated and converted to a number. This number specifies the period in seconds.
  The selected and selectedDefault expressions should have numeric values - the currently selected (and the default) time-of-day (seconds from midnight).
`<!--%%CALENDARTIMEMENU selected` [`PERIOD timePeriod` ] `-->`
  This element creates the same HTML menu as the DAYTIMEMENU element.
  The selected expression value should be a timestamp. The time part of that value is used as the currently selected time-of-day value.
`<!--%%LOCALCALENDARTIMEMENU selected` [`PERIOD timePeriod` ] `-->`
  This element creates the same HTML menu as the DAYTIMEMENU element.
  The selected expression value should be a timestamp value. The value is converted to the local time zone, and time part of the converted value is used as the currently selected time-of-day value.
`<!--%%STRINGMENU selected` [`DEFAULT selectedDefault` ]`IN valueSet` [`DISPLAY dictionary`]`-->`
  This element works in the same way as the ENUMMENU element, but the values used are the actual data values, not their numbers as in the ENUMMENU element. The default value has the string value `default`.
`<!--%%CALENDARDATECONTROL selected NAME name` [`DAYSBEFORE before`] [`DAYSAFTER after`] [`CANNEVER` ] `-->`
  This element composes a control or set of controls for a calendar date specified using the selected expression. The expression value should be a timestamp, otherwise the whole element is removed from the resulting markup code.
  If the specified time is more than before days earlier than the current date or if it is more than after days later than the current date, then this element is substituted with a text with several text controls. Otherwise a menu control is composed.
  The before and after values should be specified as numbers.
  If the before value is not explicitly specified, it is set to 7.
  If the after value is not explicitly specified, it is set to 31.
  If the CANNEVER keyword is used, the control menu displays the `Never` item with the remote future value. If the selected value is equal to the remote future value, a menu control is composed.
  The name element should be a string.
  To compose text controls, the `dateOnly` format string is taken from the `DatePictures` dictionary, and the text control codes are used to substitute its `^D`, `^M`, `^Y`, and `^y` symbol combinations. Each control has the specified name with a prefix: the day control has the `name-D` name, the month control has the `name-M` name, the 2-digit year control has the `name-Y` name, and the 4-digit year control has the `name-y` name.
  If a menu is to be composed the `select` markup language element is generated. It has the specified name name. The menu contains an element for the current date, before elements for the previous dates, and after elements for the future dates. The elements are formatted using the `dayAndMonthDate` format string from the `DatePictures` dictionary.
  An additional element with the `...` text is added for the "after+1" date. When this element is selected, the selected date value moves outside the "menu-covered" range, allowing the user to use text controls and select an arbitrary date.
`<!--%%LOCALCALENDARDATECONTROL selected NAME name` [`DAYSBEFORE before`] [`DAYSAFTER after`] `-->`
  This element creates the same markup code as the CALENDARDATECONTROL element.
  The selected expression value should be a timestamp. The value is assumed to be expressed in the global (GMT) terms, so the value is converted to the local time first.

CommuniGate® Pro Guide. Copyright © 1998-2012, Stalker Software, Inc.