This document explains how to use expressions and available functions in WIZML.
A limited set of functions is available in WIZML, most of them (loosely) based on equivalent ColdFusion functions. Currently there are mostly string functions and a few runtime functions, introduced in HomeSite 3.0 and ColdFusion 3.1. With the new 4.0 versions of these programs, two numeric functions have been added.
While most of these functions are modeled after their ColdFusion namesakes, there can be significant differences which could confuse a ColdFusion programmer. Where this is the case, the differences are clearly described.
The following subjects are treated in this document:
Related information about VTML and WIZML:
|
To output the value of a variable within a template, a double dollar sign escape sequence ($$VariableName) is utilized. For example, to output the value of a variable named Color you would use the following syntax: $$Color. It may be necessary to delimit the variable name from literal text following it (the $$ sequence itself serves as a delimiter for whatever comes before it); in such a case the variable name can be enclosed in braces ( { } ) serving as delimiters (effectively turning it into an expression).
In addition to outputing and manipulating simple parameter values, an expression syntax which includes support for a number of functions is also provided for WIZML. (Expressions can also be used in Wizard profile files.) To output the value of an expression instead of just a variable you add a set of curly braces to the $$ and include the expression within the braces, for example:
$${ 'This is ' & Color } $${ 'The result of 7 divided by 22 is ' & 7/22 } $${ Left( 'FooBar', 3 ) }
Expressions can be built using literals (strings and numbers), variables, and operators and functions.
To output the value of an expression you add a set of curly braces to the $$ and include the expression within the braces.
Anywhere you can use a string, you can use an expression that returns a string; anywhere you can use a number you can use an expression that returns a number; and anywhere you can use a boolean ('true' or 'false') you can use a boolean expression. (Well, almost everywhere - where this is not the case it has been indicated in this set of documentation files.)
The operators than can be used to form expressions in WIZML are listed below.
Operators | |
---|---|
Arithmetical operators (Result: number ) | |
+ - * / | Standard arithmetical operators |
Concatenation (Result: string ) | |
& | String concatenation operator |
Comparison operators (Result: boolean ) | |
LT | Less than |
LTE | Less than or equal |
GT | Greater than |
GTE | Greater than or equal |
EQ | Equal |
NEQ | Not equal |
Boolean (logical) operators (Result: boolean ) | |
AND, OR, NOT | And, Or, Not |
The available functions fall into three groups:
The following string functions can be used and are documented below:
Chr( number )
number | Any ASCII value (a number in the range 0 to 255 inclusive):
number or numerical expression that evaluates to a number in this range. (A negative value will result in an error message, a too-large value will wrap around! I'm not sure if the latter is a bug but that's what it does.) |
Numbers from 0 to 31 are the standard, non-printable ASCII codes. For example, Chr(10) returns a linefeed character and Chr(13) returns a carriage return character. Therefore, the two-character string Chr(13) & Chr(10) is the newline string.
Sample code | Result |
---|---|
Chr(97) | "a" |
Chr(65) | "A" |
Chr(65+1) | "B" |
<WIZSET val = 52> Chr(val+1) |
"5" |
Chr(268) | "." (character 12, or 0C in hex: 268-256=12) |
Chr(-2) | Error |
Performs a case-sensitive comparison of two strings. Returns -1 if string1 is less than string2; 0 if string1 is equal to string2; or 1 if string1 is greater than string2.
See also CompareNoCase and Find.
Compare( string1, string2 )
string1, string2 | Strings to be compared. |
The comparison is performed on the ASCII values (character codes) of corresponding characters in Str1 and Str2.
Sample code | Result |
---|---|
Compare("b", "boo") | -1 |
Compare("boo", "foo") | -1 |
Compare("Boo", "Boo") | 0 |
Compare("boo", "Boo") | 1 |
Performs a case-insensitive comparison of two strings. Returns a negative number (-1) if string1 is less than string2; 0 if string1 is equal to string2; or a positive number if string1 is greater than string2.
See also Compare and FindNoCase.
CompareNoCase( string1, string2 )
string1, string2 | Strings to be compared. |
Sample code | Result |
---|---|
CompareNoCase("boo", "foo") | -1 |
CompareNoCase("Boo", "Boo") | 0 |
CompareNoCase("boo", "Boo") | 0 |
Returns the first index of an occurrence of a substring in a string. Returns 0 if substring is not in string. The search is case-sensitive.
See also FindNoCase, Compare, and CompareNoCase.
Find( string, substring )
Note: the order ( string, substring )
needed here is the
exact opposite of what is found for the equivalent function in the ColdFusion documentation. Also, the optional third parameter
start
in the CF version is not implemented in WIZML.
string | String being searched. |
substring | String being sought. |
Sample code | Result |
---|---|
Find("abcdefghij", "def") | 4 |
Find("abcdefghij", "deg") | 0 |
Find("abcdefghij", "Def") | 0 |
Find("abcdefghij", "def") | 4 |
Find("abcdefghij", "") | 0 |
Returns the first index of an occurrence of a substring in a string from a specified starting position. Returns 0 if substring is not in string. The search is case-insensitive.
See also Find, and CompareNoCase.
FindNoCase( string, substring )
Note: the order ( string, substring )
needed here is the
exact opposite of what is found for the equivalent function in the ColdFusion documentation. Also, the optional third parameter
start
in the CF version is not implemented in WIZML.
string | String being searched. |
substring | String being sought. |
Sample code | Result |
---|---|
FindNoCase("abcdefghij", "def") | 4 |
FindNoCase("abcdefghij", "DEF") | 4 |
FindNoCase("abcdefghij", "deg") | 0 |
FindNoCase("abcdefghij", "") | 0 |
Returns string with leading spaces removed.
LTrim( string )
string | String being left-trimmed. |
Sample code | Result |
---|---|
LTrim(" Boston") | "Boston" |
LTrim(" Boston ") | "Boston " |
LTrim(" ") | "" |
Ltrim("") | "" |
Returns string with removed trailing spaces.
RTrim( string )
string | String being right-trimmed. |
Sample code | Result |
---|---|
RTrim("Amsterdam ") | "Amsterdam" |
RTrim(" Amsterdam ") | " Amsterdam" |
RTrim(" ") | "" |
Rtrim("") | "" |
Returns string with both leading and trailing spaces removed.
Trim( string )
string | String being trimmed. |
Sample code | Result |
---|---|
Trim(" Hello ! ") | "Hello !" |
Returns string converted to lowercase.
See also UCase and DefaultCase.
LCase( string )
string | String being converted to lowercase. |
Sample code | Result |
---|---|
LCase("Allaire HomeSite") | "allaire homesite" |
LCase("ABCDEF12345") | "abcdef12345" |
Returns string converted to uppercase.
See also LCase and DefaultCase.
UCase( string )
string | String being converted to uppercase. |
Sample code | Result |
---|---|
UCase("This is a String") | "THIS IS A STRING" |
Returns the length of a string.
See also Left, Right, and Mid.
Len( string )
string | Any string. |
Sample code | Result |
---|---|
Len("Nick Bradbury") | 13 |
Len("12345" & "67890") | 10 |
Len("") | 0 |
Returns the count of characters from the beginning of a string argument. If the number of characters requested is longer than the original string, the result is truncated to the original string (i.e., no spaces are added at the end).
Left( string, count )
string | String from which the leftmost characters are retrieved. |
count | Positive integer indicating how many characters to return: number or numerical expression; a broken number is automatically rounded to the nearest integer. |
Sample code | Result |
---|---|
Left("Nick Bradbury", 4) | "Nick" |
Left("Nick Bradbury", 1) | "N" |
Left("Nick Bradbury", 20) | "Nick Bradbury" |
<WIZSET Length = 4> Left("Nick Bradbury", Length) | "Nick" |
<WIZSET Length = 1.8 * 2> Left("Nick Bradbury", Length) | "Nick" |
Returns the rightmost count characters of a string. If the number of characters requested is longer than the original string, the result is truncated to the original string (i.e., no spaces are added at the start).
Right( string, count )
string | String from which the rightmost characters are retrieved. |
count | Positive integer indicating how many characters to return: number or numerical expression; a broken number is automatically rounded to the nearest integer. |
Sample code | Result |
---|---|
Right("Marjolein Katsma", 6) | "Katsma" |
Right("Marjolein Katsma", 1) | "a" |
Right("Marjolein Katsma", 20) | "Marjolein Katsma" |
<WIZSET Length = 6> Right("Marjolein Katsma", Length) | "Katsma" |
<WIZSET Length = 11.4 / 2> Right("Marjolein Katsma", Length) | "Katsma" |
Returns count characters from string beginning at start position. If the number of characters requested would go past the end of the original string, the result is truncated to the original string (i.e., no spaces are added at the end). Negative values are also treated sensibly - see the examples below.
See also Left, Len, and Right.
Mid( string, start, count )
string | Any string or string expression. |
start | Starting position for count: number or numerical expression; a broken number is automatically rounded to the nearest integer. |
count | Number of characters being returned: number or numerical expression; a broken number is automatically rounded to the nearest integer. |
Sample code | Result |
---|---|
Mid("1234567890", 3, 4) | "3456" |
Mid("1234567890", 3, 0) | "" |
Mid("1234567890", 3, -2) | "" |
Mid("1234567890", 4, 15) | "4567890" |
Mid("1234567890", -2, 15) | "1234567890" |
<WIZSET String = "123123123"> <WIZSET Start = 2> <WIZSET Length = 5> Mid(String, Start, Length) |
"23123" |
<WIZSET String = "123123123"> <WIZSET Start = 1.8> <WIZSET Length = 2.4 * 2> Mid(String, Start, Length) |
"23123" |
Returns a string created from a string being repeated a specified number of times.
RepeatString( string, count )
string | String being repeated. |
count | Number of repeats: number or numerical expression; a broken number is automatically rounded to the nearest integer. |
Sample code | Result |
---|---|
RepeatString("-", 10) | "-----------" |
RepeatString("<BR>", 3) | "<BR><BR><BR>" |
RepeatString("", 5) | "" |
RepeatString("abc", 0) | "" |
<WIZSET Spaces = 5> RepeatString(" ", Spaces) | " " |
<WIZSET Spaces = 6.6 - 3> RepeatString(" ", Spaces) | " " |
Decides between two possible values to be returned depending on a condition. If the result of evaluating the boolean expression is TRUE, it returns the value of Evaluate(string_expression1); otherwise, it returns the value of Evaluate(string_expression2).
iif( condition, string_expression1, string_expression2 )
Condition | Boolean expression to be evaluated |
String_expression1 | Valid string expression to be evaluated and result returned if condition is TRUE. |
String_expression2 | Valid string expression to be evaluated and result returned if condition is FALSE. |
Note: the function is listed as a string function here since it returns a string; however, since it internally uses Evaluate() it might also be regarded as a runtime function.
This function is used for safe variable evaluation. In many cases you can do a conditional check for the existence of a variable with a function like ParameterExists() and use the variable in an expression only if this conditional check returns TRUE: without such a conditional check a direct reference to the variable would result in an error if it doesn't exist. But where the variable is to be directly embedded in an expression such a conditional check for variable existence cannot be used. SafeValue() provides a way around this by checking if the variable exists and returning its value if it does, or returning defaultvalue if it doesn't.
SafeValue ( expression, defaultvalue )
Expression | String expression to be evaluated; its value will be returned if it is defined. |
Defaultvalue | Value to be returned if the value of Expression is not defined. |
The following numeric functions are documented below:
This function will test whether the supplied string parameter is numeric, i.e, represents a number. The function takes account of the Windows setting for the decimal separator. Thousands separators are not handled but hardly relevant in the context of Tag Editors and Wizards where values larger than 1000 are rarely needed.
IsNumeric( string )
String | String to be inspected. |
Sample code | Result for '.' set as decimal separator | Result for ',' set as decimal separator |
---|---|---|
<WIZSET testval = 'A'> <WIZIF IsNumeric(testval)> $${testval} is numeric <WIZELSE> $${testval} is not numeric </WIZIF> | A is not numeric | A is not numeric |
<WIZSET testval = '-5.2'> <WIZIF IsNumeric(testval)> $${testval} is numeric <WIZELSE> $${testval} is not numeric </WIZIF> | -5.2 is numeric | -5.2 is not numeric |
<WIZSET testval = Evaluate("5/2")> <WIZIF IsNumeric(testval)> $${testval} is numeric <WIZELSE> $${testval} is not numeric </WIZIF> | 5.2 is numeric | 5,2 is numeric (Note the decimal comma in the output!) |
<WIZSET testval = '1,000,000.05'> <WIZIF IsNumeric(testval)> $${testval} is numeric <WIZELSE> $${testval} is not numeric </WIZIF> | 1,000,000.05 is not numeric | 1,000,000.05 is not numeric |
This function will round the number supplied to the nearest integer, using "statistical" or "bankers'" rounding. (This seems to be the default rounding method in Delphi, in which HomeSite and ColdFusion Studio are written.) Internally, IsNumeric is applied first; if the parameter is not numeric, Round() returns a zero.
Note: it's debatable whether statistical rounding, where a .5 fraction is always rounded to the nearest even number, is really appropriate in this context. No repeated rounding would be taking place (where statistical rounding could be useful to avoid compounding errors). We're rounding numbers of pixels, percentage values, maybe font sizes: such units as used on a web page or in the lay out if a tag editor don't need to be protected from statistical errors. A disproportionate number of even results might in fact lead to undesirable artifacts in lay out. The documentation for the Round() function in ColdFusion mentions only rounding to the nearest integer; the method is not specified, nor do the examples show whether normal mathematical rounding or statistical rounding is being used.
Round( number )
Number | Number to be rounded. |
If you want to be sure of normal rounding and not end up with a disproportionate number of even numbers, see the examples below for a correction. This correction term should have the exact number of decimals shown here. Also note that the correction should be negative for negative parameters to obtain normal rounding!
Rounding strings:
Sample code | Result for '.' set as decimal separator | Result for ',' set as decimal separator |
---|---|---|
Round("word") | 0 (Indicates error) | 0 (Indicates error) |
Round("3.5") | 4 | 0 (Indicates error) |
Round("3,5") | 0 (Indicates error) | 4 |
Round("-5.3") | -5 | -5 |
This series of examples (no correction) would result in 9 odd and 11 even numbers.
Sample code no correction |
Result |
---|---|
Round(2.0) | 2 |
Round(2.1) | 2 |
Round(2.2) | 2 |
Round(2.3) | 2 |
Round(2.4) | 2 |
Round(2.5) | 2 (effect of statistical rounding) |
Round(2.6) | 3 |
Round(2.7) | 3 |
Round(2.8) | 3 |
Round(2.9) | 3 |
Round(3.0) | 3 |
Round(3.1) | 3 |
Round(3.2) | 3 |
Round(3.3) | 3 |
Round(3.4) | 3 |
Round(3.5) | 4 |
Round(3.6) | 4 |
Round(3.7) | 4 |
Round(3.8) | 4 |
Round(3.9) | 4 |
This series of examples (with correction) would result in 10 odd and 10 even numbers:
Sample code with correction |
Result |
---|---|
Round(2.0 + 0.00000000000001) | 2 |
Round(2.1 + 0.00000000000001) | 2 |
Round(2.2 + 0.00000000000001) | 2 |
Round(2.3 + 0.00000000000001) | 2 |
Round(2.4 + 0.00000000000001) | 2 |
Round(2.5 + 0.00000000000001) | 3 (normal rounding) |
Round(2.6 + 0.00000000000001) | 3 |
Round(2.7 + 0.00000000000001) | 3 |
Round(2.8 + 0.00000000000001) | 3 |
Round(2.9 + 0.00000000000001) | 3 |
Round(3.0 + 0.00000000000001) | 3 |
Round(3.1 + 0.00000000000001) | 3 |
Round(3.2 + 0.00000000000001) | 3 |
Round(3.3 + 0.00000000000001) | 3 |
Round(3.4 + 0.00000000000001) | 3 |
Round(3.5 + 0.00000000000001) | 4 |
Round(3.6 + 0.00000000000001) | 4 |
Round(3.7 + 0.00000000000001) | 4 |
Round(3.8 + 0.00000000000001) | 4 |
Round(3.9 + 0.00000000000001) | 4 |
A limited number of runtime functions is also available.
The following run-time functions are documented below:
Functionally this is a string function but since it it really goes "outside" the context of a visual tag editor to query a setting in the program's environment it's classified as a runtime function here.
Returns a string in the case as set by the Setup option "lowercase all inserted tags" (lowercase if on, uppercase if off).
See also Lcase and UCase.DefaultCase( string )
string | String being converted. |
Sample code for "lowercase all inserted tags" ON | Result |
---|---|
DefaultCase("VTML") | "vtml" |
DefaultCase("ABCDEF12345") | "abcdef12345" |
The function evaluates its argument and returns the result. The result type is expression.
Evaluate( string_expression )
string_expression | Valid expression to be evaluated. |
Since the result type of Evaluate() is an expression, this function can be used anywhere in WIZML where
an expression can be used. If the result of the evaluation is the name of a (pre-existing) variable,
the function can be used anywhere where that variable could be used. This makes it possible to use variable
variable names; this is useful in loops (see WIZLOOP)
where the contents of a series of variables needs to be written with variable names containing consecutive
numbers. The third example below indicates this usage.
That Evaluate() returns an expression also implies it cannot be used where a constant (literal) is
expected, like for the FROM and TO attributes in an Index WIZLOOP.
If you need fractions in numerical values, you should always use decimal points in Evaluate(), regardless of the Windows setting for decimal separator: a comma (unless inside an explicit string) will make it look like two "things" to the parser rather than a single number.
The string expression can be arbitrarily complex. Note, however, that these are somewhat complicated to write because they are inside a string. In particular, if the string expression itself is double-quoted, double-quotes inside the expression must be escaped by doubling them. (Replacing a set of double quotes by single quotes currently confuses the WIZML interpreter.) This is illustrated by the fourth example below. Note that when this evaluate statement is used in its turn as part of written output, the resulting expression ("Hello !") is evaluated again : when you try this, what you'll see is just Hello ! - without the quotes! (Yes, that confused me, too. :-))
Note: The implementation of this function in WIZML is rather different than what is indicated by the ColdFusion documentation: unlike in ColdFusion where the number of arguments is arbitrary (and the arguments can be sequentially dependent on each other), in WIZML the function takes only a single argument, rendering it much less powerful.
Sample code | Result |
---|---|
Evaluate("1+1") | 2 |
Evaluate('ImageContent' & i) | (If i=3): ImageContent3 |
Evaluate('ImageContent' & Evaluate("4/2")) | ImageContent2 |
Evaluate("Trim("" Hello ! "")") | "Hello !" |
The function sets the variable specified by name_expression to value.
SetVariable( name_expression , value )
name_expression | Expression that evaluates to a valid variable name. |
value | String or number assigned to the variable. |
When setting variables, it is required that the variable exists prior to the use of this function.
Note: Unlike the documentation for ColdFusion suggests, SetVariable does not return the value the variable is being set to; but it can certainly be used to set a variable's value. And where the ColdFusion documentation suggest the first parameter can only be a name, it can in fact (more usefully!) be an expression that evaluates to a variable name. This makes SetVariable() to the counterpoint of Evaluate(): where the latter can be used to get the value of a variable with a variable name, SetVariable() can be used to set a variable with a variable name. The third example illustrates this.
Sample code | Result |
---|---|
SetVariable("i", 25) | 25 assigned to variable i |
SetVariable("Hits", 1) | 1 assigned to variable Hits |
<WIZSET i = 3> SetVariable('Target' & 'i', "Content") | "Content" assigned to the variable Target3 |
Returns True if the specified parameter has been already created during execution of the current template or been given a value in during execution of a Wizard. Otherwise returns False.
ParameterExists( parameter )
parameter | String containing a syntactically valid variable (or parameter) name or a variable containing such a string. |
Note: Unlike the same-named function in ColdFusion, ParameterExists needs a string to reference a variable name rather than a direct variable reference.
This function is mostly seen used in Wizards as they come with HomeSite and ColdFusion Studio.
Of course, it's also useful in a visual Tag Editor: It's used in Container.vtm to work around a recursion problem (using a TabPage to decide
which type of container was selected somehow causes the condition containerType EQ 'TabPage'
to be always true so it cannot be queried
directly). However, it will become even more useful once WIZINCLUDE will work for visual Tag Editors as well.
Sample code | Result |
---|---|
<WIZSET Age = 48> <WIZIF ParameterExists(Age)> You are $$Age years old. <WIZELSE> Your age is not known ... </WIZIF> |
"Your age is not known ..." (There is no variable named '48' defined) |
<WIZSET Age = 50> <WIZIF ParameterExists("Age")> You are $$Age years old. <WIZELSE> Your age is not known ... </WIZIF> |
"You are 50 years old." |
<WIZSET Var = "Age"> <WIZSET Age = 60> <WIZIF ParameterExists(Var)> You are $$Age years old. <WIZELSE> Your age is not known ... </WIZIF> |
"You are 60 years old." |