Text Templates
Text Templates are texts or documents that are to be made available in a specific format for processing by this module. One of the applications that contains Text Templates is MODUS M365 Advanced Mailing.
Placeholders
Placeholders are markers in the text that are automatically replaced by data from a Data Entity during editing by the Text Engine. Placeholders are characterized by the fact that they are defined with an introductory and an outgoing character string. The name of the field (see here) with the replacement data is specified within this string.
Example {#DocumentType#}: Here {# defines the introductory character string, the placeholder prefix. #} is the counterpart, the outgoing character string, the placeholder suffix. The text DocumentType denotes the name of a field of a Document Entity Line, here for example the Sales Header.
The mention of {#DocumentType#} is replaced by the content of the Document Type field, e.g. Order. {#DocumentType#} {#No#} would then possibly result in Order 1003.
Placeholders are the simplest way to replace data in texts.
Conditions and Loops
In addition to placeholders, comprehensive text formatting also includes options for processing elements depending on content, skipping processing or reformatting the content.
Keywords are always introduced by a < and ended by >. The structure is based on the structure of HTML elements. The following keywords are supported in the text:
tmiftmelseiftmelsetmforeach
Here, tmif and tmelseif each allow the attribute test. This contains the condition for the following text block and should be either true or false.
tmforeach allows a collection (e.g. lines of a document, which occur multiple times and represent an array) to be traversed and the text interpreted for each collection element. tmforeach has three attributes:
index: The current position within the collection, starting with 1var: The name of a variable to which the current collection element is assigned. This is then used within the loop to reference sub-elements.collection: The collection itself as an expression.
The following example is based on this data model, prefix and suffix are each a double cross #.
<h1>Your #DocumentType# #No# from #DocumentDate#</h1>
<p>Your #DocumentType# contains the following products</p>
<table style="border-collapse: collapse; width: 80%;" border="1">
<thead>
<tr>
<th style="width: 10%; text-align: right;">Pos.</th>
<th style="width: 10%; text-align: left;">Type</th>
<th style="width: 20%; text-align: left;">No.</th>
<th style="width: 60%; text-align: left;">Description</th>
</tr>
</thead>
<tbody>
<tmforeach collection="#Lines#" var="line" index="i">
<tr>
<td style="width: 10%; text-align: left;">#i#</td>
<td style="width: 10%; text-align: left;">#line.Type#</td>
<td style="width: 20%; text-align: left;">#line.No#</td>
<td style="width: 60%; text-align: left;">#line.Description#</td>
</tr>
</tmforeach>
</tbody>
</table>
<tmforeach> initiates the loop via the collection. The collection to be used are the lines of the data model Lines. The variable (var) to which an element is assigned per loop is line and the count variable (index) is i.
One HTML table line (tr) is output per line, i.e. per collection element, containing four columns (td) with Pos., Type, No. and Description of the line.
Functions
There are also a number of functions. These can be used as a condition for tmif and the attribute test contained in it or can also manipulate data.
Let's assume that a column for the quantity is added to the above template, without decorations for the sake of clarity:
<th>Quantity</th>
[...]
<td><tmif test="#equals(line.Quantity, 0)#"> <tmelse />#line.Quantity#</tmif></td>
tmif introduces a condition, the test attribute evaluates the return of the equals() function used and outputs a blank character in the case of a zero quantity and the quantity contained in the line in the case of a non-zero quantity. Due to the function, equals() naturally requires two values (no prefix or suffix is used for placeholders within functions), individual values are separated from each other by commas.
The following functions are provided; these can of course also be used outside of conditions, provided the return value makes sense.
and(bool1, bool2)- Is true if both bool1 and bool2 are true.compare(obj1, obj2)- Returns the difference between the two values. Negative if obj1 < obj2, 0 if obj1 = obj2, and positive if obj1 > obj2.comparecaseinsensitive(string1, string2)- Performs a case-insensitive text comparison. Returns true if string1 and string2 are equal.equals(obj1, obj2)- Returns true if the two values obj1 and obj2 are equal.format(value, fmtStr/fmtNum)orformat(value, length, fmtStr/fmtNum)- Is identical to the Format() function in AL, but the variant with two parameters has no length.notequals(obj1, obj2)- Identical to not(equals(obj1, obj2)). Returns true if the two values are not equal.or(bool1, bool2)- Returns true if either bool1 or bool2 is true.