Template model¶
The template model defines attribute names and functions which can be used inside the template. The base model is a product. It allows for access to product attributes including price and title. The template model also allows for advanced features such as making data manipulations and accessing settings or URL parameters.
Advanced features
The template model introduces advanced features. The most important part of the template model is how it treats values and how they can be used. For more information, see Conditional content.
Product¶
Product attributes can be accessed from product
, a top-level field of the template model. The following product attributes are available:
brand
custom_{attribute_name}
, i.e. a custom attribute is prefixed withcustom_
department
discount
image
listPrice
pattern
rating
releaseDate
sellingPrice
swatches
thumbnails
title
url
It isn't required to write the product
prefix each time, such as in {{product.sellingPrice}}
. The prefix can be omitted if the attribute is inside the product context. In the example below, both sellingPrice
and discount
will be treated as product attributes.
{{#product}}
{{#discount}}{{sellingPrice}}{{/discount}}
{{/product}}
However, when nesting contexts it is important to be careful as there is a risk of missing product attributes. In the example below, product
does not contain cmp
or string
as product attributes. This is because cmp
is a top-level field which itself contain string
.
{{#product}}
{{#cmp}}{{string}}{{/cmp}}
{{/product}}
Lambda expressions¶
Lambda expressions are directly from Mustache. The values for keys of a section can be either a function or a lambda expression. The complete lambda expression is invoked by passing in the content within the section itself as a parameter to the lambda expression.
Common to all functions
All functions use a common syntax with the colon character, :
, as an argument separator. If it is possible that a source argument can contain a colon, then all arguments should have colons present. If the last argument is an empty string or if it contains only space characters, an additional colon should be added.
ellipsis¶
An ellipsis, ...
, is used to shorten a string. Always set the maximum length of a string before shortening it. Compared to the CSS3 text-overflow: ellipsis
, the ellipsis function does work on a template level but it cannot measure the text size.
Syntax¶
{{#ellipsis}}{source}:{max-len}{{/ellipsis}}
Description¶
{source}
- Any string, for example {{product.description}}
.
{max-len}
- The maximum number of characters before the ellipsis will be inserted.
Example¶
Template | Result |
---|---|
{{#ellipsis}} 12345 :5{{/ellipsis}} | 12345 |
{{#ellipsis}} 1 2345678910:5{{/ellipsis}} | 1 234... |
{{#ellipsis}} 1 2345678910:5{{/ellipsis}} | 1 23... |
encodeUri¶
The encodeUri lambda section encodes a URI by replacing each instance of certain characters by one, two, three, or four escape sequences representing the UTF-8 encoding of the character. There will only be four escape sequences for characters composed of two "surrogate" characters.
Syntax¶
{{#encodeUri}}{URI}{{/encodeUri}}
Example¶
{{#encodeUri}}https://example.com/path with spaces?q=^|^{{/encodeUri}}
https://example.com/path%20with%20spaces?q=%5E%7C%5E
encodeUriComponent¶
The encodeUriComponent lambda section encodes a URI component. It encodes spaces and the following special characters: ,/?:@&=+$#
Syntax¶
{{#encodeUriComponent}}{URI}{{/encodeUriComponent}}
Example¶
{{#encodeUriComponent}}?x=te + st&{{/encodeUriComponent}}
%3Fx%3Dte%20%2B%20st%26
escapeHtml¶
The escapeHtml lambda section escapes special HTML characters. By default, all product attributes are escaped, but it can be disabled.
Raw | Escaped |
---|---|
" | " |
' | ' |
& | & |
< | < |
> | > |
Syntax¶
{{#encodeUriComponent}}{URI}{{/encodeUriComponent}}
Example¶
{{#escapeHtml}}<tagInText>{"json":true}</tagInText>{{/encodeUriComponent}}
<tagInText>{"json":true}</tagInText>
escapeColon¶
The escapeColon lambda section escapes a colon, :
, character. Colons will be replaced by :
.
Syntax¶
{{#escapeColon}}{text, possibly containing colon character}{{/escapeColon}}
Example¶
Inline styles require a colon character. To use it inside a lambda expression with arguments, colons should be escaped. In the following example {{product.sellingPrice}}
will be the sole argument of formatDecimal function.
{{#formatDecimal}}
%q
{{#escapeColon}}
<div class="fraction" style="background: url('{{product.fraction_image}}')"/>
{{/escapeColon}}
%r
</div>
:{{product.sellingPrice}}
{{/formatDecimal}}
formatDecimal¶
The formatDecimal lambda section provides the ability to add styles for integer and fractional parts separately. This function can be used for currency and mostly overrides the functionality of the formatPrice.
Syntax¶
{{#formatDecimal}}{format}:{decimal value}[:{source decimal separator}[:{result decimal separator}]]{{/formatDecimal}}
Description¶
{format}
- Formats a string. The format specifiers work with one value and part of them are used as predicates in the resulting pattern. For more information, see Format details.
{decimal value}
- The decimal value to format.
{source decimal separator}
- The decimal separator to split the integer and fractional parts in the input decimal value. The dot, .
, is used by default.
{result decimal separator}
- The decimal separator to be printed instead of a %s
format specifier. The {source decimal separator}
will be used by default.
Format details¶
%[ [grouping symbol]]q
- Print the quotient of the decimal value. Can be grouped by thousands if it has a space, , flag and possibly some grouping symbol after it.
%[c|d|u|n][0][-][{width}]r
- Print the reminder, i.e. fractional part, of the decimal value if the -
flag is not present. Because of the rounding, %r
can be used only once unlike the %q
or any other format specifiers.
c|d|u|n
- The rounding mode. If {width}
is present and the fractional part is longer than it, then the value will be rounded and can even change the quotient value if after rounding the fractional part will be equal to 1
.
Rounding mode | Description |
---|---|
c | Stands for CEIL and always rounds the value up to the nearest integer. |
d | Stands for HALF_DOWN and rounds the value down to the nearest integer, even when the value is x.5 , e.g. 4.5 => 4.0 . |
u | Stands for HALF_UP and rounds the value up to the nearest integer when the value is x.5 and over, e.g. 4.5 => 5.0 . The default rounding mode. |
n | Stands for NOTHING and no rounding will be used to the value. |
0
- Flags that there is no need to display the fractional part if it is zero.
-
- Flags the fractional part present only to set rounding, nothing will be rendered.
{width}
- The number of digits to display. If there are not enough digits, the value will be padded by zeroes.
%s
- A place holder for the result decimal separator. Displays nothing if the 0
flag for the reminder is present and the reminder is zero.
%i
- A paired conditional specifier. If the value is an integer then display text after the first %i
up to the next %i
, or to the end of the {format}
argument.
%f
- A paired conditional specifier. If the value has a non-zero fractional part then display text after the first %f
up to the next %f
, or to the end of the {format}
argument.
%%
- Prints the percentage symbol, %
.
Example¶
Show the fractional part of the price only if it isn't zero. Set a two-digit position for the fractional part.
{{#formatDecimal}}<div class="price-integer">% q</div>%f<div class="price-fractional">%2r</div>:{{product.sellingPrice}}{{/formatDecimal}}
formatPrice¶
Formats a decimal value. Allows decimals to change to zero fraction display, decimal separator and/or add grouping separator.
Syntax¶
{{#formatPrice}}{source}[:{zero fraction}[:{grouping separator}[:{result decimal separator}[:{source decimal separator}]]{{/formatPrice}}
Description¶
{source}
- A decimal number.
{zero fraction}
- Define behavior if the fractional part is zero. 0
- two zeroes will be added after decimal separator, 1
- cut the zero fraction with a decimal separator, any other string will be printed instead of the decimal separator and fractional part.
{grouping separator}
- The character used for thousands separator. Can only be one character or no character at all.
{result decimal separator}
- The string printed between the integer and the fractional parts in the result, .
is used by default.
{source decimal separator}
- The decimal separator used to parse the original value.
Example¶
Template | Result | Description |
---|---|---|
{{#formatPrice}} 100.00{{/formatPrice}} | 100 | Zero fraction cut by default. |
{{#formatPrice}} 99,1:00:::,{{/formatPrice}} | 99.10 | Non-standard decimal separator in the source value. |
{{#formatPrice}} 253500:: :,{{/formatPrice}} | 253 500,00 | Adding zero fraction, separate thousands by space and use non-standard decimal separator. |
{{#formatPrice}} 15.0::~: :,{{/formatPrice}} | 15:~ | Special ending zero fraction. |
replace¶
Replaces each sub-string of a string that matches the literal target sequence with the specified literal replacement sequence. The replacement proceeds from the beginning of the string to the end. For example, replacing aa
with b
in the string aaa
will result in ba
rather than ab
.
Syntax¶
{{#replace}}{source}:{target}:{replacement}{{/replace}}
Description¶
{source}
- The source string.
{target}
- The source sub-string to be replaced.
{replacement}
- The replacement value.
Example¶
Template | Result |
---|---|
{{#replace}} abbaba{{/replace}} | aba |
replaceFirst¶
Replaces the first sub-string of this string that matches the literal target sequence with the specified literal replacement sequence. The replacement proceeds from the beginning of the string to the end. For example, replacing aa
with b
in the string aaa
will result in ba
rather than ab
.
Syntax¶
{{#replaceFirst}}{source}:{target}:{replacement}{{/replaceFirst}}
Description¶
{source}
- The source string.
{target}
- The source sub-string to be replaced.
{replacement}
- The replacement value.
Example¶
Template | Result |
---|---|
{{#replaceFirst}} abbaba{{/replaceFirst}} | abab |
replaceLast¶
Replaces the last sub-string of this string that matches the literal target sequence with the specified literal replacement sequence. The replacement proceeds from the beginning of the string to the end. For example, replacing aa
with b
in the string aaa
will result in ba
rather than ab
.
Syntax¶
{{#replaceLast}}{source}:{target}:{replacement}{{/replaceLast}}
Description¶
{source}
- The source string.
{target}
- The source sub-string to be replaced.
{replacement}
- The replacement value.
Example¶
Template | Result |
---|---|
{{#replaceLast}} abbaba{{/replaceLast}} | abba |
regexReplace¶
Replaces each sub-string of this string that matches the given regular expression with the given replacement.
Syntax¶
{{#regexReplace}}{source}:{regex}:{replacement}{{/regexReplace}}`
Description¶
{source}
- The source string.
{regex}
- The regular expression to which this string is to be matched. The decimal HTML entry :
can be used instead of the colon character, :
, in the regular expression.
{replacement}
- The string to be substituted for each match.
Example¶
Template | Result |
---|---|
{{#regexReplace}} 2020-04-01:(d{4})-(d{2})-(d{2}):$3.$2.$1{{/regexReplace}} | 01.04.2020 |
regexReplaceFirst¶
Replaces the first sub-string of this string that matches the given regular expression with the given replacement.
Syntax¶
{{#regexReplaceFirst}}{source}:{regex}:{replacement}{{/regexReplaceFirst}}
Description¶
{source}
- The source string.
{regex}
- The regular expression to which this string is to be matched. The decimal HTML entry :
can be used instead of the colon character, :
, in the regular expression.
{replacement}
- The string to be substituted for the first match.
Example¶
In this example it is known that the first number of the source string will be a brand ID, but the string contains other numbers as well, and it is required to replace the brand ID with the brand name. The source string can contain colon characters,:
.
{{#regexReplaceFirst}}Brand: 13179, Article: 107882:\d+:{{product.brand_name}}{{/regexReplaceFirst}}
product.brand_name = "Seafall"
Brand: Seafall, Article: 107882
slice¶
Extract a part of a string starting from the beginning (index inclusive) up to the end (index exclusive). Safe to use with arguments outside of the source string bounds.
Syntax¶
{{#slice}}{source}:{begin}[:{end}]{{/slice}}
Description¶
{source}
- The source string to be sliced.
{begin}
- The zero-based index at which to begin extraction. A negative index can be used, indicating an offset from the end of the source string. Default value is 0
.
{end}
- The zero-based index before which to end extraction. A negative index can be used, indicating an offset from the end of the source string. Default value is the string source length.
Example¶
Template | Result |
---|---|
{{#slice}} 01234:3{{/slice}} | 34 |
{{#slice}} 01234:-2{{/slice}} | 34 |
{{#slice}} 01234::-1{{/slice}} | 34 |
{{#slice}} 01234:-3:-1{{/slice}} | 23 |
{{#slice}} 01234:1:2{{/slice}} | 1 |
Arguments can be out of the source bounds | |
{{#slice}} 01234:3:10{{/slice}} | 34 |
{{#slice}} 01234:5:-1{{/slice}} |
trim¶
Removes whitespace from both ends of a string. Can be used when combining values after a replacement.
Syntax¶
{{#trim}}{source}}{{/trim}}
Example¶
{{#formatPrice}}{{#trim}}{{store.operation1}}{{/trim}}.{{#trim}}{{store.operation2}}{{/trim}}:: :{{/formatPrice}}
store.operation1 = "1000 "
store.operation2 = " 39 "
1 000.39
URL¶
Each user request URL query parameter can be accessed through the url
top-level template model field. It contains an all
field which will print a query string with exclusion of special parameters. Such as campaign
, position
, block
, customer_key
, timestamp
, ts
, mobile
, and products
.
This field plays an important role for using product image templates. Different images will be used for different values of the used query parameters.
Settings¶
The settings field allows for accessing template configuration.
enableHtmlEscape¶
The enableHtmlEscape lambda section enabling or disabling product attributes escaping. It is enabled by default and all product attributes are escaped automatically. It can be disabled at any time by providing false
as argument {{#settings.enableHtmlEscape}}false{{/settings.enableHtmlEscape}}
.
After manipulating the raw value is finished it is possible to escape the result manually.
Html escaping can be enabled again by providing true
or an empty string as argument.
Conditions¶
Conditions can be used to compare and test values to change things in the template. The cmp
field contains several lambdas to provide comparisons and one field to store the result.
test¶
This field contains the result of the comparison operation and is an integer value. Zero, 0
, means that the compared values are equals. A value greater than zero means that first value is bigger, and a value less than zero means that first value is less than the second one.
string¶
Compares two strings lexicographically. The comparison is based on the Unicode value of each character in the strings. The character sequence represented by this String object is compared lexicographically to the character sequence represented by the argument string. The result is a negative integer if this String object lexicographically precedes the argument string. The result is a positive integer if this String object lexicographically follows the argument string. The result is zero, 0
, if the strings are equal.
Syntax¶
{{#cmp.string}}{value1}:{value2}{{/cmp.string}}
Example¶
All examples are made inside the {{#cmp}}
section.
Template | {{cmp.test}} |
---|---|
{{#string}}#000000:#000000{{/string}} | 0 |
{{#string}}aqua:sand{{/string}} | -18 |
str¶
Shortcut for string.
integer¶
Compares two int values numerically. The test result is 0
if value1 == value2; less than 0
if value1 < value2; and a value greater than 0
if value1 > value2.
Syntax¶
{{#cmp.integer}}{value1}:{value2}{{/cmp.integer}}
decimal¶
Compares two decimal values numerically. Test result is 0
if value1 == value2; -1
if value1 < value2; and 1
if value1 > value2
Syntax¶
{{#cmp.decimal}}{value1}:{value2}{{/cmp.decimal}}
testEq¶
A boolean value that indicates that the last compare was between two identical values. It is true when test
field is 0
and {{#testEq}}
is equivalent to {{^test}}
.
testAbove¶
A boolean value that indicates that test
> 0
.
testBelow¶
A boolean value that indicates that test
< 0
.
testAE¶
A boolean value that indicates that test
is equal to or above 0
.
testBE¶
A boolean value that indicates that test
is equal to or below 0
.
intSub¶
Subtract one integer value from another. The test field is an int value and can store the result of any integer arithmetic operations. More complicated operations can be done with combinations of the calc
field, the store
field, and the iterator
field.
Syntax¶
{{#cmp.intSub}}{value1}:{value2}{{/cmp.intSub}}
intAdd¶
Add one integer value to another. The test field is an int value and can store the result of any integer arithmetic operations. More complicated operations can be done with combinations of the calc
field, the store
field, and the iterator
field.
Syntax¶
{{#cmp.intAdd}}{value1}:{value2}{{/cmp.intAdd}}
intDiv¶
Divide one integer value to another and store integer part of operation into the test field. The test field is an int value and can store the result of any integer arithmetic operations. More complicated operations can be done with combinations of the calc
field, the store
field, and the iterator
field.
Syntax¶
{{#cmp.intDiv}}{value1}:{value2}{{/cmp.intDiv}}
intMod¶
Calculate the modulus of one integer value for another and store integer part of operation into the test field. The test field is an int value and can store the result of any integer arithmetic operations. More complicated operations can be done with combinations of the calc
field, the store
field, and the iterator
field.
Syntax¶
{{#cmp.intMod}}{value1}:{value2}{{/cmp.intMod}}
Calculations¶
Allows for performing arithmetic operations.
intMax¶
Print the maximum value of two integers.
Syntax¶
{{#calc.intMax}}{value1}:{value2}{{/calc.intMax}}
intMin¶
Print the minimum value of two integers.
Syntax¶
{{#calc.intMin}}{value1}:{value2}{{/calc.intMin}}
intAdd¶
Print the sum of two integers.
Syntax¶
{{#calc.intAdd}}{value1}:{value2}{{/calc.intAdd}}
intSub¶
Print the difference between two integers.
Syntax¶
{{#calc.intSub}}{value1}:{value2}{{/calc.intSub}}
intDiv¶
Print the integer part of division between two integers.
Syntax¶
{{#calc.intDiv}}{value1}:{value2}{{/calc.intDiv}}
intMod¶
Print the modulus of one integer for another.
Syntax¶
{{#calc.intMod}}{value1}:{value2}{{/calc.intMod}}
decimalMax¶
Print the maximum of two decimals.
Syntax¶
{{#calc.decimalMax}}{value1}:{value2}{{/calc.decimalMax}}
decimalMin¶
Print the minimum of two decimals.
Syntax¶
{{#calc.decimalMin}}{value1}:{value2}{{/calc.decimalMin}}
decimalAdd¶
Print the sum of two decimals.
Syntax¶
{{#calc.decimalAdd}}{value1}:{value2}{{/calc.decimalAdd}}
decimalSub¶
Print the difference between two decimals.
Syntax¶
{{#calc.decimalSub}}{value1}:{value2}{{/calc.decimalSub}}
decimalFromPercent¶
Calculates a percentage of the specified number. The rounding mode is defined by constants similar to those of Java RoundingMode.
Syntax¶
{{#calc.decimalFromPercent}}{value}:{percent}[:{RoundingMode}[:{precision}]]{{/calc.decimalFromPercent}}
Description¶
{value}
- A decimal value.
{percent}
- A percent to calculate.
{precision}
- A whole number of digits. Default value is 10
.
{RoundingMode}
- Specifies the rounding behavior. Default value is FLOOR
.
Example¶
Template | Result |
---|---|
{{#decimalFromPercent}} 999.99:10{{/decimalFromPercent}} | 99.999 |
decimalPercent¶
Alias for decimalFromPercent.
decimalToPercent¶
Calculates the percentage of the first number to the second, i.e. the part to the whole. The rounding mode is defined by constants similar to those of Java RoundingMode.
Syntax¶
{{#calc.decimalToPercent}}{part}:{whole}[:{RoundingMode}[:{precision}]]{{/calc.decimalToPercent}}
Description¶
{part}
- A decimal value used to calculate what percentage of the whole it is.
{whole}
- A decimal value used to calculate what percentage of it that is the part value.
{precision}
- A whole number of digits. Default value is 10
.
{RoundingMode}
- Specifies the rounding behavior. Default value is FLOOR
.
Example¶
Template | Result |
---|---|
{{#decimalToPercent}} 5:10{{/decimalToPercent}} | 50 |
Iterator¶
Allows to split any value and access any part separately. First step is to split the value. Then iterator
field can be accessed through the collection extension.
split¶
Splits a string around matches of the given regular expression.
Syntax¶
{{#iterator.split}}{value}[:{regex}]{{/iterator.split}}`
Description¶
{value}
- Any value.
{regex}
- The delimiting regular expression. The decimal HTML entry :
can be used instead of the colon character, :
, in the regular expression.
Example¶
Splits the product selling price grouped by thousands and styles each group individually.
{{#iterator.split}}{{#formatDecimal}}% q:{{product.sellingPrice}}{{/formatDecimal}}: :{{/iterator.split}}
{{#iterator}}
<div class='price-proup-{{-index}}>{{.}}</div>
{{/iterator}}
Store¶
When the result of complex transformations needs to be used several times it can be saved once into the store
instead of having repeating transformations.
The following example subtracts the percentage discount from the original price and stores it as sellingPrice
.
{{#product}}
{{#calc}}
{{#store.put.sellingPrice}}
{{#decimalSub}}
{{listPrice}}:
{{#decimalPercent}}{{listPrice}}:{{discount}}:FLOOR{{/decimalPercent}}
{{/decimalSub}}
{{/store.put.sellingPrice}}
{{/calc}}
{{/product}}
...
{{store.sellingPrice}}
The store model consists of the map for results and several methods to store results.
put¶
Allows adding named variables to the store
map.
Syntax¶
{{#store.put.{name}}}{value}{{/store.put.{name}}}
Description¶
{name}
- The name of the stored variable. The value will be accessed using this name. A name cannot contain dots or only be space characters.
{value}
- Any value. A stored value will be trimmed.
get¶
Allows retrieving a value from the store.
Syntax¶
{{store.get.{name}}}
- Name can be a reserved word (put, get, set).
{{store.{name}}}
- Name cannot be a reserved word.
A name cannot contain dots or only be space characters.
set¶
If there is no need to set a name for the variable, set
can be used instead of put
. This stores the default value which can then be retrieved/printed by mentioning {{store}}
.
Syntax¶
{{#store.set}}{value}{{/store}}
Collection extension¶
The collection extension is a wrap around the collection that allows for selecting a part of the collection. This is done using special lambda expressions.
minIdx¶
Set the starting index of the wrapped collection. Numeration starts from 1
.
Syntax¶
{{#{name}.minIdx}}{integer}{{/{name}.minIdx}}
maxIdx¶
Set the maximum index of the wrapped collection. Numeration starts from 1
.
Syntax¶
{{#{name}.maxIdx}}{integer}{{/{name}.maxIdx}}
selected¶
Direct access to selected sub-collection. The collection extension wrap will iterate this object by default. Mostly, there is no need for direct calls. {{#{name}.selected}}...{{/{name}.selected}}
will be equivalent to {{#{name}}}...{{/{name}}}
and {{{name}.selected.size}}
equals to {{#{name}.size}}
.
all¶
Direct access to the wrapped collection. The minIdx
and/or maxIdx
can be set to iterate over the whole collection without changing back indexes.
idx¶
Direct access to elements.
Syntax¶
{{#{name}.idx.{number}}}{text}{{/{name}.idx.{number}}}
Example¶
Getting access to the second element inside the iterator. This line will not be shown if the iterator only has one item.
{{#iterator.idx.2}}The second element value is "{{.}}"{{/iterator.idx.2}}