By default, the TCM application includes a set of email templates that are used to generate the email notifications for teamspace invitations, task assignments, meeting notices, and other events. You can modify templates as needed.
An email template contains text and template “instructions.” Common instructions include adding a date or setting up the subject of the email message. For each instruction in the template, the template engine places a value in the resulting email, or in some way modifies the resulting email. The resulting email contains text merged with the result of the instructions.
This section describes the syntax of template instructions. You can customize the email templates to create email notifications with information from the Content Java API, Process Engine and other Java objects.
See Formal BNF for email templates for the formal template syntax. See Customizing email templates for a list of the templates provided by default and the associated notifications.
There are two types of template instructions: substitutions and commands. Substitutions exchange the instruction in the template with the value of some passed-in information. Commands cause the template engine to perform an action, such as setting the subject line, beginning an HTML section, or including text from another file into the resulting email.
Template instructions are delimited by angle brackets or curly braces. For example, <$pe_style> and {$pe_style} are both valid template instructions. A mix of delimiter style within an instruction is not supported. For example, <$pe_style} and {$pe_style> are invalid.
TCM supports these two styles of delimiters to:
An email template works with a Java Map containing template parameter information specific to the type of notification that triggered the email. The template parameter map has entries that are keyed by a string name and that have a value of any kind of object (String, HashMap, ArrayList, CustomObject, or VWStepElement). Template parameter names must conform to the following:
The simplest template instruction is a substitution in the form: {$x}, where x is the name of one of the template parameters. In this case the string value of the x parameter replaces the {$x} characters in the template.
For example, if an entry named "foo" was in the template parameter map and it had a value of a string "bar", then simply using {$foo} in the template would substitute that with its value bar in the resulting email message.
The template parameter name, x, is called an “identifier” and must start with a letter or underscore and is followed by any number of letters, digits, underscores, and hyphens. Template parameter names are not case sensitive.
If a template parameter is a container (such as a Java Map or List or a Java API’s Document class, for example) the parameter may use name selection of the form: {$x.y}, where x is a template parameter and y is a "selector." Object classes that can use name selection are: HashMap, Folder, Document, CustomObject, VWStepElement or VWWorkObject or anything that implements java.util.Map. or ReadableMetadataObject interfaces, with special cases for the VW objects.
A Map-like container, also known as an associative array, uses keys or field names to select items out of the container. Usually these selectors are string names, although in some cases, with Map, the selectors may be integer values or even other objects depending on the type of keys used in the map. The classes that are supported by templates are: Map (anything implementing this interface, such as HashMap or TreeMap), Set (implemented by HashSet or TreeSet), ReadableMetadataObject (implemented by Java API’s Document, Folder and CustomObject classes), Values (another Java API class), VWStepElement and VWWorkObject. Collaboration objects which reference underlying Java API objects are also handled if they implement the PersistentBaseObject class (which Teamspace, Poll, Task, etc. do). Examples: {$mymap[ "foo" ]}, {$doc[ "id" ]}.
A List-like container, also known as an array, uses numeric indexes to select items. These selectors are always integers and normally will be base-0 for a normal List (meaning the first element is referenced by 0, the second by 1, the third by 2, etc.), which includes ArrayList and LinkedList classes. The special Java API classes that are List-like containers ( ReadableMetadataObjects and Values) are base-1 (meaning the first element is referenced by 1, the second by 2, the third by 3, etc.). Examples: {$myarray[2]}, {$versionseries[5]}.
Selectors may be cascaded so that {$myversionseries[2][ "id" ]} first gets the second element from a Java API VersionSeries parameter and then gets the ID from that second element. Selector cascading is always from left to right.
Selectors may be of several different types:
There is a shortcut form, {$x.y}, that can be used for literal numeric and most string selectors, where x is the template parameter and y is the selector. Rather than {$document[ "name" ]} the more readable {$document.name} can be used instead. Similarly, {$myversionseries[2][ "id" ]} can be replaced with {$myversionseries.2. id }. This shortcut form does not use quotes and, in fact, cannot be used with literal string selectors that do not look like identifiers (i.e., start with a letter or underscore and are followed by any number of letters, numbers, underscores and hyphens). For instance, {$mymap.123X} will not work since 123X is neither an integer nor a valid identifier-like name. This form should be used carefully with selectors that should use the value of another template parameter. For example, {$mymap.myvalue} should not be used if myvalue is a template parameter. Use {$mymap[myvalue]} instead.
Depending on the class of the object, x, the type of the selector, y, will often be limited to either numeric or string values for the {$x[y]} and {$x.y} forms. Following is a list of allowed selector types and their classes/interfaces (interfaces shown in italics).
com.filenet.bso.api.collaboration.PersistentBaseObject
(implemented by most collaboration classes: Comment, Poll, Teamspace, Task, etc.)
com.filenet.wcm.api.ReadableMetadataObject
(implemented by such Java API classes as: Document, Folder and CustomObject)
filenet.vw.api.VWStepElement
filenet.vw.api.VWWorkObject
java.util.List(implemented by ArrayList and LinkedList)
com.filenet.wcm.api.ReadableMetadataObjects(implemented by Java API classes, such as: Documents, Folders and CustomObjects)
com.filenet.wcm.api.ValuesJava API interface
java.util.Map(implemented by HashMap and TreeMap)
java.util.Set(implemented by HashSet and TreeSet)
Containers will normally return the selected element, if any, and generate an error if none exists. The Set classes (HashSet and TreeSet) are different in that they return an integer 0 if the selector is not found in the set and a 1 if it is. The Map classes (HashMap and TreeMap) are different in that, if the selected element cannot be found, then the “default”, the value which has a null key will be returned; if is no null key then an error is generated.
In addition to general lookups/indexing, there are a number of built-in selectors that may be used on objects of certain classes. For these, both forms of selection may be used (i.e., {$x.size} is equivalent to {$x[ "size" ]}. Following are the built-in selectors and what classes/interfaces they can be applied to (with interfaces in italics).
Name |
Java Class/Interface |
Description |
collabid |
com.filenet.wcm.api. ReadableMetadataObject |
Returns the “Collaboration ID” of the Java API object. This will normally be the GUID of a Content Java API object, but will return the GUID of a Document’s VersionSeries for document objects that are not specifically Collaboration-type objects. This is normally used to construct HTML links to Collaboration objects. |
collabsymname |
com.filenet.wcm.api. ReadableMetadataObject |
Returns a string representing the “Collaboration Symname” of the object. For example, {$doc.collabsymname} where doc is a Collaboration Task object, will return task. This is normally to construct HTML links to Collaboration objects. |
collabtitle |
com.filenet.wcm.api. ReadableMetadataObject |
Returns a string representing the title of a Collaboration object. Depending on the type of the object, this might return the DocumentTitle, CollaborationTitle, TextSummary or FolderName property for that object. This is normally used to generate HTML links to Collaboration objects. |
containeedocuments |
com.filenet.wcm.api. Folder |
Returns a list of Document objects within a Folder object. Example: {$folder.containeedocuments[1]} |
containeefolders |
com.filenet.wcm.api. Folder |
Returns a list of subfolders within a Folder object. |
containees |
com.filenet.wcm.api. Folder |
Returns a list of everything ( Folders, Documents and CustomObjects) within a Folder object. |
containers |
com.filenet.wcm.api. Document or CustomObject |
Returns a list of all the folders that this object has been filed in. |
content |
com.filenet.wcm.api. Document |
Returns the content of a document in the form of a TransportInputStream, which may be used by the attachment command covered later. This is special in that it may be optionally followed by an [n] to retrieve the nth content element if the first, [1], is not desired. Example: {$attachment doc.content} is equivalent to {$attachment doc.content[1]} |
contentutf8 |
com.filenet.wcm.api. Document |
Similar to content, but assumes the content is UTF-8 encoded. |
id |
com.filenet.wcm.api. BaseObject |
Returns the GUID of this Java API object. Example: {$folder.id} |
javaclass |
Any |
Returns the full Java path name of the class of this object. Example: {$mylist.javaclass} |
javashortclass |
Any |
Returns the short name (not the full Java path) of the class of this object. Example: {$myobj.javashortclass} |
key |
java.util.Map.Entry |
Returns the key of this map entry. Example: {$x.key} |
length |
Any |
Returns the length of the string version of the object (i.e., it uses the toString() method on the object). |
name |
com.filenet.wcm.api. BaseObject |
Returns the name of this Java API object. Example: {$doc.name} |
objectstore |
com.filenet.bso.api. collaboration. PersistentBaseObject |
Returns the object store of a collaboration object ( Comment, Task, Teamspace, etc.) |
objectstoreid |
com.filenet.wcm.api. BaseObject |
Returns the GUID of the object store that this Java API object belongs to. Example: {$ceobject.objectstoreid} |
objecttype |
com.filenet.wcm.api. BaseObject |
Returns an integer value for the Java API object type of the object. |
parentfolder |
com.filenet.wcm.api. Folder |
Returns a Folder parent object that is the parent of this folder. |
size |
java.util.Collection or java.util.Map |
Returns the size of the collection or map. Example: {$mymap.size} |
value |
java.util.Map.Entry |
Returns the value of this map entry. Example: {$x.value} |
The result of a parameter substitution may be modified using this form of substitution: {$x|m}, where x is a parameter-reference and m is the name of some modifier that should change x’s value. For example, in {$foo|upper}, upper is a modifier which will change the result of foo to its upper-case equivalent. The modifiers may be cascaded (like selectors) and combined with selectors. These cascades will operate from left to right so that {$foo|upper|url_encode} would first uppercase the string value of foo and then URL encode it. Modifier names are not case sensitive.
Some modifiers may also take an argument, which is represented by the form {$x|m(a)}, where x is a parameter-reference, m is the name of a modifier and a is an argument to m. If the modifier takes more than one argument, the more general form is {$x|m(a,b,c,d)}, where each argument is separated from the others by a comma ( ,). Each argument might be one of the following:
Examples: {$foo|replace( " first ", " last ")|upper } and {$doc.datecreated|date_format( "dd MMM yyyy") }.
Modifiers without arguments can also use the parentheses around an empty argument list. For example: {$foo|upper()}.
The following table lists the modifiers, their arguments and descriptions. Optional arguments are enclosed in brackets (e.g., [ number ]).
Modifier, Arguments |
Description |
cat ( str1 [ , str2 [ , str3 [ , … ] ] ] ) |
Concatenates the string value of the current object with those of the arguments. This allows several pieces to be assembled for a following modifier. Example: If foo has the value “ x” and bar has the value “ y”, then {$foo | cat (bar, " -abc " ) | upper} will return the value “ XY-ABC ” |
date_format [ ( format [,timezone ] ) ] |
This requires a java.util.Date as its object and formats the string for the specified time zone using java.text.SimpleDateFormat. Examples: {$doc.creationdate|date_format( "ddd, dd MMM yy ") } {$a_date|date_format( " yyyyMMdd ' T ' HHmm ' Z '" , " UTC " )} |
html_encode
|
Replaces all ' < > & characters with the HTML entity forms: < > & '. |
id_to_email_address ( idnumber ) | Converts an ID value, idnumber, into an email address for that user. This modifier requires the current object be either a Teamspace or a VWSession object. If a Teamspace, then idnumber should be a SID unique identifier. If a VWSession, then idnumber should be an integer value representing a Process Engine ID. Example: {$ts | id_to_email_address(doc.taskassignee)} |
id_to_user ( idnumber ) | Converts an ID value, idnumber, into a display name for the user. This modifier requires the current object be either a Teamspace or a VWSession object. If a Teamspace, then idnumber should be a SID unique identifier. If a VWSession, then idnumber should be an integer value representing a Process Engine ID. Example: {$teamspace | id_to_user(doc.taskassignee)} |
int | Converts an object into a java.lang.Integer object. Example: {$ "-123" | int } |
list_to_string [ ( separator ) ] | Converts a list or array into a single string value with separator strings concatenated between the elements. If separator is not given, then a single space character will be used. Example: {$foo-list | list_to_string( ", " )} |
lower
|
Converts the string value for the current object to lower case. The current locale influences this (see _app.locale). |
message_format [ ( obj1 [ , obj2 [ , obj3 [ ,… ] ] ] ) ] | Uses a java.text.MessageFormat type format string as its object to build a formatted message using the obj N arguments for substitutions, if given. See the Java class for details on how this format string works. Example: {$ "On {1,date} at {0,time} O''clock" | message_format(timethen, datewhen)} |
nl_to_br | Converts line ends (LF, CR, CRLF) into HTML <br> codes. This is useful within the HTML part of a message to display a field with significant new lines inside. Example: {$foo|nl_to_br} |
obj_to_email [ ( number ) ] | Creates the local part of an email address (the part before the ‘@’) addressing the object. Currently this is only supported for CE Folder class objects which reference a collaboration teamspace. If the number argument is 2, then the “long” address form is used rather than the default “short” form. Example:{$ts|obj_to_email(2)}@foo.com |
replace ( from, to ) | Replaces all instances of the from string to the to string in the string value of the current object. This is case sensitive. Example: {$foo|replace( " first "," last ") } |
sort | Sorts a java.util.Collection into its “natural” ordering returning an ArrayList of the sorted elements. This can also sort a java.util.Map to put its keys in the “natural” order returning a TreeMap. Example: {$loop i, mylist|sort} |
string | Converts an object into its java.lang.String representation. Example: {$mymap[ 123 | string] } |
truncate [ ( length [ , mark ] ) ] | Truncates the string value of the object so that it is no longer than a specified length (default = 80). If the string was truncated, replace the last few characters with a mark (by default "..."). Example: {$subjectline|truncate(40, ">>") } |
upper [ ( number ) ] | Converts the string value of the current object to upper case. The current locale influences this (see _app.locale). If upper(1) is given, then only the first character of the string value is converted to upper case, otherwise (either upper(0) or upper) the entire string is converted. Example: {$warning | upper} {$document.collabsymname | upper(1)} |
url_decode [ ( number ) ] | Decodes a URL encoded string object. This effectively undoes the encoding performed by the url_encode modifier. The default form, without a numeric argument, decodes %xx escapes. If number is given, then it will change the decoding so that: url_decode(0)/ url_decode(1) are equivalent to url_decode |
url_encode [ ( number ) ] | URL encode the string value of the current object. The default form, with a numeric argument, replaces spaces with ‘+’ and adds %xx escapes for characters that are not the “safe” characters, which are either alphanumeric or not a period (.), hyphen (-) or asterisk (*) (this is application/x-www-form-urlencoded). For an “unsafe” character, the character is first UTF-8 encoded and then the resulting byte(s) converted to one or more %XXs. If number is given, then it will change the encoding so that: url_encode(0) is equivalent to url_encode url_encode(1) will act as url_encode, but will escape spaces as %20 rather than ‘+’ url_encode(2) will “label encode” the object url_encode(3) will “path encode” the object (The latter two forms are used when constructing FileNet P8 or Collaboration HTML links.) |
Normally a substitution in one of its forms: {$x}, {$x[y]} or {$x|m}, will have an x that is a parameter identifier. X is not restricted, however, to just an identifier and may be a literal of some kind, such as is allowed as an argument for a modifier. This means that {$123} or {$ " first "|upper } are valid, albeit trivial, substitutions. The usefulness of this feature is in using two additional types of literals, lists and maps.
A list literal is of this form:
[[ elem0 [ ,elem1 [ ,elem2 … ] ] ] ]
For example, a simple [ ] is an empty list, while [ 1, 2, 3 ] and [ " first ", " second ", " third " ] are both lists with three elements.
A map literal is in this form:
[key0 :elem0 [ ,key1 :elem1 [ ,key2 :elem2 …[ , : defaultelem ] ] ] ]
For example, [ 1: " first ", 2:" second ", 3:" third ", : " otherwise " ] is a map keyed with the integer values: 1, 2 and 3 with values “first”, “second” and “third”; it also has a default value “otherwise” that will be used for other keys. As special cases, [:] represents an empty map, and [:defaultelem ] represents a map which always returns its default element with any selector.
The elements and keys may be any valid substitution expression, which includes identifiers, literals (including list and map literals) optionally followed by selectors and/or modifiers.
The map and list literals are very powerful ways to create localizable information, particularly when used with the set command covered later. The map literal can also be used to conditionally perform a substitution, as in this example:
{$[ "foo" : "bar", : val][val] }.
Explanation: the first set of brackets creates a map with two elements: the first with a key of “foo” and a value “bar”, and the second with a default value of the val parameter. After making the map literal, the second set of brackets “selects” using the value of the val as a key into the map and finally uses the looked up value for the substitution. This all effectively substitutes val’s value, unless its value happens to be “foo”, in which case “bar” is substituted instead. This is a somewhat advanced use of a template substitutions as a more straight-forward {$val | replace( "foo", "bar") } would do almost the same thing.
A template instruction may also be a command rather than substitution. The command form, is {$c}, where c is the name of a command. A command can also have arguments in these forms: {$c a} or {$c a,b} or {$c a,b,d}, etc., where a, b and d are arguments as previously discussed. Examples include:
{$subject "An interesting notification" }, {$plain}, {$html ' utf-8 ' }.
Parentheses may be used around the argument list, for example: {$c(a)}, {$c(a,b)} , {$c(a,b,d)}
Commands usually specify the different parts of an email message. This includes the headers, a plain part, an HTML part and attachments. The order of these commands is important and must be in this order (if they appear at all):
subject, header, plain, html and attachment/ attachment_text
The commands subject, plain and html can only be used once (if at all). The commands header, attachment and attachment_text may be used multiple times. Once a new command is encountered, this usually ends the last email message part.
If the plain and html commands are not used, then text after the subject / header commands and before the first attachment is considered to be the body of the message. Consistent with current Process Engine templates, the type of the message body is “text/html” if the first text is “<html>” and “text/plain” otherwise.
There are nine commands, encoding, if, if_def, include, loop, endloop, set, set_default, and the empty instruction, that do not specify a particular part of the message. Include allows text and instructions from another file to be included in the template, while the empty instruction does nothing and is perhaps just a comment. The if and if_def commands can e used to conditionally use text or instructions. Encoding is special in that it specifies the charset encoding used within the template file itself and should appear as the first line in the file, if it appears at all. Loop and endloop control sections of the template that are to be repeated. Set commands allow template parameters to be set dynamically.
After processing, the command is removed from the message that is being constructed. If it is the only thing on a line, then the surrounding white space (including the line end) is removed as well so that extra blank lines are not added to the message. If non-white space characters appear around the command on the same line, then the surrounding white space is left alone.
The following table lists the commands, their arguments and descriptions. Optional arguments are enclosed in [ brackets].
Command | Description |
{$} | The empty command. Other than being removed from the finished message, it does nothing and is usually used for its comment. This may appear anywhere and any number of times. Example: {$ // just a simple comment} |
{$encoding charset } | Specifies the charset encoding of the template file. If present, then either this must be the first template instruction or this must specify the same encoding as a previous encoding command (which is useful within included files). If not present, then the default encoding for the server is assumed. Example: {$encoding "utf-8"} |
{$subject text } | Sets the subject header for the email. This should only appear once in a template if it appears at all. Note that multiple templates can be combined together to form a single message using the include command (covered later in this section). In this case, subject commands after the first are simply ignored. Example: {$subject "Notification of {$why}"} |
{$header name , value } |
Specifies an additional header to be used in the email. There may be several of these if desired. Note that multiple templates can be combined together to form a single message using the include command (covered later in this section). In this case, header commands in templates after the first are simply ignored. Example: {$header "reply-to", "joe@myco.com"} |
{$plain [encoding ] } | Begins the plain text part of the message, which has no particular formatting other than the use of spaces, tabs and new lines. If encoding is not specified then UTF-8 is used. Normally, a message will only have one plain command, if it has one at all, however, there may be multiple localized templates using the include command with an “app” argument (covered later) and the plain commands of each will then be combined together to form a single plain text part for the entire message. The first (or only) plain command will start with the text found in _app.plain-start; the text in _app.plain-separator will separate each command; and the last (or only) plain command will have _app.plain-end text appended at the end. Example: {$plain "8859-1"} |
{$html [encoding ] } | Begins the HTML part of the message. This part may use HTML formatting tags. Beware of the use of certain lone characters ( < > &) within this part. If encoding is not specified then UTF-8 encoding is used. Normally, a message will only have one html command, if it has one at all, however, there may be multiple localized templates using the include command with an “app” argument (covered later) and the html commands of each will then be combined together to form a single HTML text part for the entire message. The first (or only) html command will start with the text found in _app.html-start; the text in _app.html-separator will separate each command; and the last (or only) htmlcommand will have _app.html-end text appended at the end. Example: {$html} |
{$attachment source [ , mimetype [ , filename [ , encoding ] ] ] } | Adds a new attachment to the message using source, which must be either an InputStream or a TransportInputStream object. Mimetype (optional for a TransportInputStream) is the content-type of the attachment. Filename (also optional for a TransportInputStream) is a suggested filename for the attachment. Encoding is optional and specifies what character set the stream is encoded in. This command may appear any number of times in a template, with each appearance defining a new attachment. Example: {$attachment doc.content} |
{$attachment_text mimetype , filename [ , encoding ] } |
Starts a text attachment that is in the template following this command. This can be very useful for iCalendar and vCard attachments since they can then be constructed in place. This command may appear any number of times in a template, with each appearance defining a new attachment. Example: {$attachment_text "text/directory","joes.vcs"} … followed by the text of the attachment |
{$if expr , then [ , else ] } | Conditionally substitutes the then expression if expr is “true” or the else expression if it is “false.” If else is not given, then an empty string will be substituted if expr is “false”. Expr may be any valid template substitution expression, i.e., an identifier or a literal followed by any number selectors and modifiers. The truth of expr is this: it will be “false” if there is any error (other than a syntax error) encountered when evaluating expr (such as it not being defined) or if it evaluated to an integer 0 , an empty string ( " " ), an empty Map / List / Set or a null ; in any other case, it is “true.” Usually both the then and else arguments are evaluated immediately, even if they are not going to be substituted. This can result in template errors if one of these clauses is not valid. For example, the following if command will cause an error: {$if foo, "foo is {$foo}"} if foo is not a defined template parameter when the {$foo} inside the string is encountered. To avoid this, use “triple-quoted” strings, which defer the interpretation of embedded substitutions like this… {$if foo, " " "foo is {$foo}" " "} This works because the offending {$foo} is not processed in this case until the then cause is actually substituted. This triple-quoting is not needed for strings that do not have embedded template substitutions. Note that the then and else expressions do not need to be string literals, but watch for errors when evaluating them (e.g., {$if foo, foo} would fail if foo was not defined). Example: {$if task.taskdatereminder, " " "Reminder date: {$task.taskdatereminder}" " ", "No reminder date"} |
{$if_def variable , then [ , else ] } | A special case of the if command that makes a substitution depending on whether variable is defined or not, no matter what its value. If it is defined, then the then argument is used for the substitution. If it is not defined, then the else argument is used. Variable may have selectors. Example: {$if mymap.key1, "defined!", "not defined!"} |
{$include name [ , applicationMap ] } | Includes text from somewhere else into the template and processes that for instructions. This uses a callback mechanism to fetch the included text called name and will throw an exception if this callback has not been set. Example: {$include "extra.tpl"} If the optional applicationMap argument is given, then it will temporarily be used for the _app value during the processing of the include text. Also during the processing of the include text, the values of _group_apps and _other_apps will be undefined. This form of the include command is used to switch the application information temporarily from the current one to another, perhaps to change locales. To process each application in a group of applications, place the following code at the end of each localized version of a particular template: {$if _group_apps, ''' This works as follows: The if command causes the following code between the ' ' '’s to only be done once in the “main” application’s template (not in the included ones). The loop iterates over all of the other applications that are in the same application group, if any. The include retrieves the template of the same name from another application (i.e., from a different locale) and includes it. During these include commands, the _app value will be set to each different successive application. Note that including multiple localized templates using this second form of the include command affects the interpretation of subject, header, plain and html commands. The subject and header commands in templates after the first are simply ignored, while the plain and html commands in all templates are combined into larger plain/HTML text parts. |
{$set variable , value } | Sets a given variable name to a value, possibly overwriting a previous value for variable. After this, variable name may be used as a template parameter if it was not previously set. Variable may have selectors and, if it does, will create the new element with a new key if needed. Examples: {$set x.sorted-list, mylist | sort} |
{$set_default variable , value } | Sets the default value for a variable that has not yet been assigned one. This acts like the set command if variable has no value already. If variable has previously been assigned a value, then nothing happens. Example: {$set_default sline, "My Default subject line" } |
{$loop variable , container } | Sets up a loop that repeats a section of the template for each element in container . Container should be a class that implements either java.util.Collection or java.util.Map. Examples of the classes that do this are: HashMap, ArrayList, Documents, Folders, etc. Each iteration sets variable to the value for the current element. Variable must not be the name of an existing template parameter or an error will be generated (this is to enforce the restriction that a loop variable only be used within its loop). Variable may also include one or more selectors and works like a set command in that it might create a new map element if needed. A loop command must have a matching following endloop command. If container is empty, then the template from the line of the loop up to the endloop is skipped. Example for a Collection: If container is a Map, then variable will be set to a series of Map.Entry objects. Example for a Map: |
{$endloop} | Ends a loop command. |
Comments may be added to any substitution or command in two C++ language-like forms: // on to the end of line or end of the instruction (whichever comes first) and /* comments */ that continue from the /* on until the first */ is encountered. /*-style comments may not be nested. Instructions within the comments may be ignored, but watch for the trailing lead-out for // comments.
There are a number of template parameters that are normally defined for use within templates. These may be accessed like user supplied template parameters in the {$x}, {$x[y]}, etc., forms covered earlier (e.g., {$_from_address | url_encode}).
Name |
Description |
A map of values associated with the current application ID. Following are normally used values within this map, but additional values may also be appear if defined in the application ID definition (e.g., _app.foo ). |
|
_app.id |
The ID currently in effect. For example, “TCM”. |
The locale currently in effect. This is a string in the form “<language>” or “<language>_<country>” using language/country values as defined in the java.util.Locale class. For example, “fr” or “de_CH”. This setting is used when displaying java.util.Date objects and by the lower, upper, date_format and message_format modifiers. This may be changed within the template with something like {$set _app.locale, "en" }. |
|
_app.time-zone |
The time zone currently in effect. This is a string as defined by the java.util.TimeZone. E.g., “PST” or “Europe/Rome”. This setting is used when displaying java.util.Date objects and by the date_format and message_format modifiers. This may be changed within the template with something like {$set _app.time-zone, "EST" }. |
_app.group |
The name of the current application group. All the application IDs within this group should all be part of the larger “application” and differ by locale. |
_app.html-start |
The text that is placed before the first html command section in the message. |
_app.html-separator |
The text that is used to separate multiple html command sections. |
_app.html-end |
The text that is placed after the last html command section in the message. |
_app.plain-start |
The text that is placed before the first plain command section in the message. |
_app.plain-separator |
The text that is used to separate multiple plain command sections. |
_app.plain-end |
The text that is placed after the last plain command section in the message. |
_app.email-domain |
The name of the email domain (the part after the @) to use for special teamspace addresses (which will be used to archive email). For example, collab.company.com. |
_app.url |
The URL of the home page of the application. For example, |
_app.base-url |
The URL path of the application. For example, |
_app.process-engine-application-id |
The Process Engine default web application id number (For example, 201). |
_app.email-sent-by |
The default email address to use for TCM generated email notifications. For example, “TCM-notification@company.com”. |
_debug |
Controls whether debugging mode is enabled (set to 1) or not (set to 0). This may be set within the template by a command like {$set _debug, 1}. |
_from |
The name of the user sending the notification. |
_from_address |
The email address of the user sending the notification. |
_group_apps |
A map of all the application ID information for all applications in the current group (i.e., all the apps that have the same _app.group value). The map is keyed by the name of the locale. This will be undefined in a include “app” command. |
_other_apps |
Similar to _group_apps, but this map will not have the current application ID in it and so will have one less application. This will be undefined in a include “app” command. |
_all_parameters |
This is a map that includes all of the template parameters and is useful in template commands like {$loop x, _all_parameters} |
Substitutions may be nested inside of other template instructions to any arbitrary depth and nested substitutions can affect outer ones. So that if bar = " fee ", then {$foo{$bar}} would be the same as the instruction {$foofee}.
As a security feature, template substitutions in general will not be reinterpreted for template instructions within the substitutions. This means that if bar = " {$fee} " and fee = " foo ", then {$bar} at the highest level within a template would be substituted with the text {$fee} within the template and not foo, as would be expected if the substitution were reinterpreted. There are exceptions to this, however, in that the result of an if command will be reinterpreted and possible template substitutions found within its then or else argument. This means that the following command will work as you might expect…
{$if task.taskreminderdate, '''{$task.taskreminderdate|date_format}''', 'No Date'}
White space (spaces, tabs, formfeeds and returns) may be used inside of template instructions, but should only appear before or after identifiers, strings and punctuation characters ( . , ( ) [ ] |). White space cannot be used, for instance, in the middle of identifiers, numbers, or a template instruction delimiter.
A comment is treated as if it were a single white space character. If there’s only a comment in a template instruction, then this is an empty instruction, which is ignored.
There are 4 namespaces for identifiers: 1) template parameters, 2) keys/properties/fields, 3) modifiers and 4) commands. The same identifier might be used in any of these 4 namespaces and would mean different things depending on the context. All of the namespaces are case insensitive, with the exception of key/property/field names, whose case sensitivity depends on the object being referenced.
Nested template instruction lead-ins and outs have special rules within quoted strings. The lead-out of a template instruction (the > } or ?>) is “escaped” within a quoted string. For instance, {$foo|bar( "}")} works, since the first } is within quotes. However, a nested instruction can be within a quoted string, like this: {$foo[ "{$bar}"]}, which is equivalent to {$foo[ bar]}. Also a nested lead-out can be escaped using backslash: {$foo[ "\{$bar}"]}, which would not expand the {$bar} as usual.
Locales and to a certain extent time zones are controlled by application IDs. An application ID is an identifier set globally by the web application as it initializes and this identifier provides information about that particular application, such as the locale and the default time zone. The current set of information for this application ID is found in the built-in template parameter, _app, described earlier.
Language and date formatting, for example, rely on the locale of the server running the collaboration application and that of the recipient(s) of the message. The server’s locale determines parsing of such things as which letters and digits are allowed in identifier names and how case-insensitive matching is done for identifier lookups. The recipient’s locale (which should be set using an API call unless it is the same as the server’s), could affect the template lookup and will affect the following modifiers: date_format, lower and upper.
The time zone of the recipient(s) will affect the date_format modifier and should also be set using an API call unless it is the same as the server’s. This allows times and dates to be displayed appropriately for a recipient’s time zone.
Java provides support for both locales and time zones. The Java Locale class can be constructed using ISO 2-letter language and 2-letter country codes (e.g., “fr” for the French language and “CH” or Switzerland). The Java TimeZone class uses an ID, such as “America/Los_Angeles”, “Pacific/Galapagos” and even “America/Indiana/Indianapolis” to account for both the offset from UTC and daylight savings time. (There are about 560 of these IDs.) The Java TimeZone class can be used when formatting, parsing and otherwise constructing Date objects.
The following are provisions for templates that will support Process Engine email template syntax:
Refer to Formal BNF for email templates for more information.