Skip to content

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 all defined 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. Attributes of this field contains all base attributes plus attributes from the first variant.

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}}

Variants

Variants can be accessed from the variants top-level field of the template model. It allows for iterations over product variants. The first item in variants is the same as the variant that can be accessed from the product field. Because of this it is sometimes useful to start an iteration from the second item in variants.

{{#variants.minIdx}}2{{/variants.minIdx}}
{{#variants}}{{this.image}}{{/variants}}

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
" "
' '
& &
< &lt;
> &gt;

Syntax

{{#encodeUriComponent}}{URI}{{/encodeUriComponent}}

Example

{{#escapeHtml}}<tagInText>{"json":true}</tagInText>{{/encodeUriComponent}}
&lt;tagInText&gt;{&quot;json&quot;:true}&lt;/tagInText&gt;

escapeColon

The escapeColon lambda section escapes a colon, :, character. Colons will be replaced by &#58;.

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.price}} will be the sole argument of formatDecimal function.

{{#formatDecimal}}
%q
{{#escapeColon}}
<div class="fraction" style="background: url('{{product.fraction_image}}')"/>
{{/escapeColon}}
%r
</div>
:{{product.price}}
{{/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.price}}{{/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}}abbab🆎a{{/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}}abbab🆎a{{/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}}abbab🆎a{{/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 &#58; 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 &#58; 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.

baseImageUrl

The baseImageUrl attribute allows for accessing the image path prefix. There is no need to add {{settings.baseImageUrl}} before each relative image path, because the tag <base href="{{settings.baseImageUrl}}"/> is used by default.

enableHtmlEscape

The enableHtmlEscape lambda section enables or disables escaping of product attributes. 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 the same way as the variants field 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 &#58; can be used instead of the colon character, :, in the regular expression.

Example

Splits the product price grouped by thousands and styles each group individually.

{{#iterator.split}}{{#formatDecimal}}% q:{{product.price}}{{/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}}}

Examples

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}}

Access to a specified variant.

{{#variants.idx.3}}<div style="color:{{this.color}}">{{this.color_name}}</div>{{/variants.idx.3}}
×
Copyright

This online publication is intellectual property of Voyado Lund AB. Its contents can be duplicated in part or whole, provided that a copyright label is visibly located on each copy and the copy is used in conjunction with the product described within this document.

All information found in these documents has been compiled with utmost attention to detail. However, this does not guarantee complete accuracy. Neither Voyado Lund AB nor the authors shall be held liable for possible errors or the consequences thereof.

Software and hardware descriptions cited in these documents might be registered trademarks. All trade names are subject to copyright restrictions and may be registered trademarks. Voyado Lund AB essentially adheres to the manufacturer’s spelling. Names of products and trademarks appearing in this document, with or without specific notation, are likewise subject to trademark and trade protection laws and may thus fall under copyright restrictions.

CLOSE