• iOS
  • Android
  • Windows
  • Cordova
  • Web
  • Unity
  • Adobe Air
  • Dashboard
  • API
  • Guides
  • FAQ
  • Guides > Message personalization

    Advanced

    The following documentation goes into more details on how to use the personalization and templating engine.

    You will learn about builtin filters, how to control whitespace if you include if/else statements, what kind of comparison you can use and more.

    Filters

    Sidenote - filters with arguments

    You may have noticed some filters take arguments. When this is the case, there is two way to give the arguments:

    • Using a named argument as such: join(separator=',')
    • Directly giving the value as such: join(',')

    In the following reference we will denote arguments that can be given unnamed as such: argName?: type where the ? indicates the argument is optional.

    General filters

    • formatDate

      Input type

      date

      Arguments

      pattern: string or (dateStyle: string, timeStyle: string)

      Optional arguments

      timezone: string, locale: string

      Return type

      string

      Description

      Formats a date using either the pattern provided or the combined dateStyle/timeStyle

      Ex: {{ installation_date|formatDate(pattern: 'yyyy-MM-dd') }} will result in 2017-01-01

      Ex: {{ installation_date|formatDate(dateStyle: 'LONG', timeStyle: 'SHORT') }} will result in Sunday, January 1, 2017 12:00 AM

      The timezone argument allows you to format the date into a specific timezone.

      Ex: {{ installation_date|formatDate(dateStyle: 'SHORT', timeStyle: 'LONG', timezone: 'Europe/Paris') }} will result in 1/1/17 9:00:00 AM CET

      The locale argument allows you to format the date using a specific locale. A locale controls region-specific behaviour when formatting a date, for example with the US locale the time will be suffixed with AM or PM but not with the UK locale.

      Ex: {{ installation_date|formatDate(dateStyle: 'SHORT', timeStyle: 'LONG', locale: 'UK') }} will result in 01/01/17 09:00:00 CET

    • formatNumber

      Input type

      number

      Optional arguments

      decimals: int, locale: string

      Return type

      string

      Description

      Formats a number using the provided locale or the user's locale if none is provided.

      A locale controls region-specific behaviour when formatting number, for example how are thousands separated, what character to use to separate decimals, etc.

      Ex: {{ 5939310.3939|formatNumber(locale: 'en_US') }} will result in 5,939,310.394. By default there are 3 decimals.

      You can customize how many decimals you want by using the decimals argument.

      Ex: {{ 46.8384|formatNumber(decimals=1) }} will result in 46.8

    Filters for numbers only

    • abs

      Input type

      number or duration

      Return type

      int

      Description

      Returns the absolute value of a number, duration or distance

      Ex: {{ -13|abs }} will result in 13

    • round

      Input type

      number or duration or distance

      Return type

      int

      Description

      Returns the closest int of a number, duration or distance, rounding up

      Ex: {{ 46.8|round }} will result in 47

      Ex: {{ 46.3|round }} will result in 46

    • ceil

      Input type

      number or duration or distance

      Return type

      int

      Description

      Returns the closest int that is greater than the number, duration or distance

      Ex: {{ 46.2|round }} will result in 47

    • floor

      Input type

      number or duration or distance

      Return type

      int

      Description

      Returns the closest int that is lower than the number, duration or distance

      Ex: {{ 46.8|round }} will result in 46

    Filters for strings only

    • lower

      Input type

      string

      Return type

      string

      Description

      Converts a string to lowercase

      Ex: {{ VINCENT|lower }} will result in vincent

    • upper

      Input type

      string

      Return type

      string

      Description

      Converts a string to uppercase

      Ex: {{ vincent|upper }} will result in VINCENT

    • capitalize

      Input type

      string

      Return type

      string

      Description

      Converts the first letter to uppercase and all others letters to lowercase.

      Ex: {{ "john Smith"|capitalize }} will result in John smith

    • title

      Input type

      string

      Return type

      string

      Description

      Converts the first letter of each word to uppercase and all others letters to lowercase.

      Ex: {{ "johN smith"|title }} will result in John Smith

    • append

      Input type

      string

      Arguments

      text?: string

      Return type

      string

      Description

      Appends the text to the value

      Ex: {{ john|append(' smith') }} will result in john smith

    • prepend

      Input type

      string

      Arguments

      text?: string

      Return type

      string

      Description

      Preprends the text to the value

      Ex: {{ john|prepend('smith ') }} will result in smith john

    Filters for tag collections only

    • join

      Input type

      tag collection

      Arguments

      separator?: string

      Return type

      string

      Description

      Returns a string which is the concatenation of all tag values separated by the provided separator

      Ex: {{ c.interests|join(' ') }} will result in sports politics music for someone that has the values ["sports", "politics", "music"] in their c.interests tag collection

    • first

      Input type

      tag collection

      Return type

      string

      Description

      Returns the first tag value

      Ex: {{ c.interests|first }} will result in sports for someone that has the values ["sports", "politics", "music"] in their c.interests tag collection

    • last

      Input type

      tag collection

      Return type

      string

      Description

      Returns the last tag value

      Ex: {{ c.interests|last }} will result in music for someone that has the values ["sports", "politics", "music"] in their c.interests tag collection

    Chaining filters

    It is possible to chain filters to produce more complex results, however you need to make sure the input and output types are compatible between filters.

    For example, you can't call formatDate on a number or even a string, the type has to be a date. Look at the table above to know what filters are compatible.

    Here is a valid example of chaining multiple filters:

    Your next exam is on {{ t.exams|last|date|formatDate('yyyy-MM-dd') }}
    

    Given a user with this tag collection t.exams: ["2017-10-09T14:53:54Z", "2017-10-11T16:53:54Z"] the example evalutes to:

    Your next exam is on 2017-10-11
    

    As you can see we take the last value of the tag collection which returns a string, then pass that to date which parses it and returns a date type. Finally we pass that to formatDate.

    Expression

    An expression is something that returns any kind of value. It can a math operation, a comparison, a function call, a reference to an attribute or tag or even a literal value.

    Examples:

    {% set $firstName = c.first_name|upper %}
    {% set $var = 3 + 10 * 20 %}
    {% set $minor = c.age < 18 %}
    {% set $lastTag = c.interests|last|upper %}
    {% set $tomorrow = now + 24h %}
    {% set $foo = 'foobar' %}
    

    Expression are used in:

    • if/else if conditions
    • variable assignment
    • expression output {{ ... }}

    Comparison

    Type comparison rules

    When comparing two values, they have to be of the same type otherwise it won't work.

    The rules are as follows:

    • A string can only be compared with another string
    • A date can only be compared with another date
    • A duration can be compared with another duration or a number. When comparing with a number it is treated as days; in other words {{ $myDuration == 3 }} is equivalent to {{ $myDuration == 3d }}.
    • A distance can be compared with another distance or a number. When comparing with a number it is treated as meters; in other words {{ $myDistance == 200 }} is equivalent to {{ $myDistance == 200m }}
    • A number can be compared with another number or a boolean.

    Operators

    • == compares two values for equality
    • != compares two values for inequality
    • > returns true if the left hand side is greater than the right hand side
    • >= returns true if the left hand side is greater than or equal to the right hand side
    • < returns true if the left hand side is lower than the right hand side
    • <= returns true if the left hand side is lower than or equal to the right hand side

    Combining comparisons

    As in any programming languages, you can combine comparisons easily:

    • and returns true if both the left hand side and the right and side are true
    • or returns true if either the left hand side is true or the right hand side is true
    • not negates a statement
    • ( and ) to group expressions.

    Example:

    {% set $isYoungAdult = c.age > 18 and c.age < 26 %}
    {% set $hasEnoughBandwidth = c.has_fiber or (c.has_mobile and c.mobile_connection_type == '4g' %}
    {% if $isYoungAdult and $hasEnoughBandwidth %}
    Don't forget you can stream the match in 4k by subscribing !
    {% else %}
    Don't forget you can stream the match by subscribing !
    {% endif %}
    

    Data types

    Standard

    Standard types include:

    • string. You can write a literal string by using a ' character like this: 'This is a string'. To use a ' inside your string you need to double it like this: 'It''s great'
    • integer. You can write a literal integer like this: 230.
    • float. You can write a literal float like this: 20.30
    • boolean. A boolean is either true or false

    Date

    Date is a special type that can't be created by a literal. However they are produced in a couple of cases:

    • if an attribute is a date (that is either a NSDate or a java.util.Date for iOS and Android respectively).
    • by converting a UNIX timestamp (number of seconds since January 1, 1970): {{ 1491814800|date|formatDate('yyyy-MM') }}
    • by using the keyword now which returns the date at the time of execution

    Duration

    Duration is a special integer with a time unit. Units can be:

    • days: 40d
    • hours: 24h
    • minutes: 30m
    • seconds: 46s

    Distance

    Distance is a special integer with a distance unit. It is also always positive. Units can be:

    • meters: 5600m
    • kilometers: 83km

    Casting rules

    You can cast values into different types by using a casting operation, provided the types are compatible. The casting operation looks like this:

    {{ c.my_string_attribute|float|int }}
    

    Casting looks exactly like a filter but it simply converts the original value to the type if the rules allow it.

    The rules of casting are as follows:

    from / to string int float bool date distance duration
    string 1
    int 2
    float X
    bool X X X
    date 2 X X X X
    distance 3 X X
    duration 4 X X

    1 The string has to follow the pattern yyyy-MM-dd'T'HH:mm:ss or the resulting date will be empty.

    2 Casting from date to int will return the UNIX timestamp in seconds. Casting from int to date will treat the integer as a UNIX timestamp in seconds.

    3

    Rules:

    • casting from string to distance will treat the string as an integer representing the distance in meters.
    • casting from int to distance will treat the integer as the distance in meters.
    • casting from float to distance will remove the decimal part and treat it as an integer representing the distance in meters.
    • casting from boolean to distance will treat false as 0 and true as 1.

    You can pass a conversion distance unit as a parameter to the distance filter.

    Valid distance units are detailed above.

    Examples:

    • {{ '100'|distance }} will result into the distance 100m
    • {{ '12km'|distance('m') }} will result into the distance 12000m
    • {{ 2000|distance('km') }} will result into the distance 2000km
    • {{ 43.20440|distance }} will result into the distance 43m
    • {{ true|distance('km') }} will result into the distance 1km (not that you'd ever do that)

    4

    Rules:

    • casting from string to duration will treat the string as an integer representing the duration in days.
    • casting from int to duration will treat the integer as the duration in days.
    • casting from float to duration will remove the decimal part and treat it as an integer representing the duration in days.
    • casting from boolean to duration will treat false as 0 and true as 1.

    You can pass a conversion duration unit as a parameter to the duration filter.

    Valid duration units are detailed above.

    Examples:

    • {{ '100'|duration }} will result into the duration 100d
    • {{ '100h'|duration }} will result into the duration 100h
    • {{ '48h'|duration('d') }} will result into the duration 2d
    • {{ 405|duration() }} will result into the duration 405d
    • {{ 43.409|duration('m') }} will result into the duration 43m
    • {{ true|duration('s') }} will result into the duration 1s

    Math rules

    Math operations on integers and floats work as you would expect:

    {{ (10 + 2) / 2 - (5 * 20) }}
    

    Will evaluate to:

    -94
    

    There are a couple of rules for operations on dates, durations and distances:

    • adding or subtracting a duration from a date will return a new date.
    • subtracting two dates will return a duration.
    • all operations between a duration and a number are allowed and will return a duration in the original unit.
    • all operations between a distance and a number are allowed and will return a distance in the original unit.

    Some unusual operators are available for your convenience:

    • // divides two numbers and returns the truncated integer result. Example: {{ 20 // 7 }} evaluates to 2.
    • % returns the remainder of the integer division of two numbers. Example: {{ 11 % 7 }} evaluates to 4.
    • ** raises the left hand side to the power of the right hand size. Example: {{ 2 ** 3 }} evaluates to 8.

    Whitespace control

    Up until now we haven't really talked about controlling how whitespaces are included - or not - in the message after the template has been rendered.

    By whitespace we mean new line characters and leading spaces before either an expression or a statement.

    Having control on this behaviour is important so that you can better structure your template and not have to write them all on the same line to avoid having newlines in your output.

    Default rules

    The default rules are as follows:

    • Expressions ({{ ... }}) strips the leading whitespaces if the output of the expression is empty

    Example:

    Hello {{ c.first_name }}!
    

    With a c.first_name attribute defined, this evaluates to:

    Hello Vincent!
    

    Note the space after Hello is kept.

    With no c.first_name attribute defined, it evaluates to:

    Hello!
    

    Note that there is only one space: the space after Hello has been removed

    • Statements ({% ... %}) always strips the trailing newlines

    Example:

    {% set $hour now|formatDate('hh')|int %}
    {% set $morning = $hour < 12 %}
    {% set $evening = $hour > 19 %}
    Good {% if $morning %}
    morning
    {% else if not $morning and not $evening %}
    afternoon
    {% else %}
    evening
    {% endif %}!
    

    This evaluates to:

    Good morning!
    

    Depending on the current time it will change to afternoon or evening.

    Forced behaviour

    If the default behaviour doesn't suit you, you can force the behaviour with the following syntax:

    • {{+ +}} or {%+ +%} will force every whitespace to be kept
    • {{- -}} or {%- -%} will force every whitespace to be stripped

    You can mix and match of course: {{+ ... -}} is completely valid.

    Example:

    Hello {{- c.first_name }}!
    

    Now that we forcefully remove the leading whitespace, with a c.first_name defined it evaluates to:

    HelloVincent!
    

    Another example:

    Hello {{+ c.first_name }}!
    

    Here we forcefully keep the leading whitespace, with no c.first_name defined it evaluates to:

    Hello !
    

    Note the space is kept.