Skip to content

Syntax

Syntax of the JuniperBot template engine.


Code Islands#

In its simplest form, a template is a text that will be sent as message as is.

However, the whole point of the template engine is the ability to format this text in a given way, use control structures (conditions or loops) inside it, and even perform some actions. The "code islands" are used to do that.

Code#

Code islands begin with {% and ends with %}, just as simple as that. Tags are used inside code constructs to implement a control structures (conditions or loops), declare variables and much more.

{% tag %}

Each code construct can perform only single operation or declare part of a control structure.

The logical sequence is formed by using many separate islands of code for each individual operation or part of the control structure.

Whitespace Control#

Tied up with the code island syntax is another syntactical enabled feature, the white space control functionality. This allows one to remove white spaces before or after a code island. In order to accomplish that, append/prepend the symbol - to the beginning/ending of the code island. Let's take for example:

{% if (1 == 1) -%}     text     {%- endif %}

Such code will produce text without white spaces.

Output#

In JuniperBot Template Engine there is only one way to write the value of variable or an expression to the output. That is accomplished with the print operation as shown below:

{{ expression }}

Note that output also support the white space control feature, using the same approach as per code islands:

{{- expression -}}

Comments#

In template engine you can add comments that will not be printed anywhere:

{# This is the content of the comment.
And it can be a multi-line content. #}

Again, comment constructs also support white space control feature in the same way as code islands:

{#- Your awesome comment -#}

Expressions#

Expressions are the logic building blocks, they allow you to express a value. From the basic constants to binary and ternary operations, expressions give the power to specify a value.

Identifiers#

Identifier is the name in Template Engine. It can contain alphanumeric (latin) characters and also underscores, but cannot start with digits.

List or Map Value Access#

Whenever you need to access either a list element or map value, Template Engine comes with the value access expression. With such expression you can access the value given the key. Note that, for lists, the key is the position of the element in the list starting at zero.

list[0]
map["key1"]

Keywords#

Template Engine has some reserved identifiers, such identifiers are the building blocks of more complex constructs. Below there is the list of the native reserved identifiers:

  • set
  • in
  • global
  • as
  • if
  • do
  • elseif
  • verbatim
  • else
  • filter
  • endif
  • endfilter
  • for
  • null
  • endfor
  • is
  • true
  • not
  • false
  • with
  • empty
  • require
  • return
  • returning
  • Unary Operators#

    Unary operators by definition only need one argument, Template Engine comes with only two built in unary operators, they are not and -.

    Symbol Description Precedence1 Example
    - Switches the signal 5 -(-1) outputs 1
    not Negates the input 10 not false outputs true;
    not true outputs false

    Binary Operators#

    Template Engine comes with several built in binary operators:

    Symbol Precedence1 Description Пример
    . 1 Access inner properties of objects member.id outputs member id
    ^ 3 Takes base number to to the power of exponent 2 ^ 3 outputs 8
    * 5 Multiplies two values 2.2 * 2.2 outputs 4.84
    ** 5 Multiplies the integer part of two values 2.2 ** 2.2 outputs 4
    / 5 Divides two values 5.0 / 2.0 outputs 2.5
    // 5 Divides the integer part of two values 5.0 // 2.0 outputs 3
    % 5 Gets the integer division remainder 5 % 2 outputs 1
    + 10 Sums two values 5 + 2 outputs 7
    - 10 Subtracts two values 5 - 2 outputs 3
    ~ 12 Concatenates two strings "5" ~ "2" outputs "52"
    < 15 Compares two values, checking whether the first is lower than the second 1 < 2 outputs true 1 < 1 outputs false
    <= 15 Compares two values, checking whether the first is lower or equal than the second 2 <= 2 outputs true 2 < 1 outputs false
    > 15 Compares two values, checking whether the first is higher than the second 2 > 1 outputs true 2 > 2 outputs false
    >= 15 Compares two values, checking whether the first is higher or equal than the second 2 >= 2 outputs true 2 >= 3 outputs false
    in 15 Checks whether the second value contains the first one 5 in [2] outputs false
    == 20 Compares two values, checking whether they are equal or not true == false outputs false false == false outputs true
    != 20 Compares two values, checking whether they are different or not true != false outputs true false != false outputs false
    and 25 Conjunction boolean operator true and false outputs false true and true outputs true
    or 25 Disjunction boolean operator true or false outputs true false or false outputs false
    | 30 Uses the first argument as parameter for the second argument. Note that, composition forces the second argument to be a function -5 | abs outputs 5

    Ternary Operator#

    Template Engine only contains one ternary operator. It allows to fork the logic based on a boolean expression, as exemplified below:

    {{ expr ? 1 : 2 }}
    

    Such expression will output 1 if the variable expr is true, or 2 if the variable is false.

    Elvis Operator#

    Template Engine supports elvis operator that returns its first operand if that operand evaluates to a true value according Type Convert, and otherwise evaluates and returns its second operand.

    {{ <expression A> ?: <expression B> }}
    

    This operator is very useful to return a "default" value for expressions.

    Assignment Operator#

    Assignment Operator (affectionately known as "the walrus operator" :=) lets you assign value to variable and return it at the same time.

    {{ <variable> := <expression> }}
    
    The walrus calculates the value of the expression, assigns it to the specified variable and returns the same value.

    {{ result := 1 + 2 }}
    {{ result }}
    

    Previous example will return "3" twice. First one is the result of expression calculation and second one is the value of result variable that has been updated by this assignment expression.

    This operator is very useful to make your code look better and shorter. For example, let's take a simple template using set tag to assign a value to variable:

    {% set amount = 5 %}
    {% if amount > 0 %}
    Daniel has {{ amount }} apples!
    {% endif %}
    

    This template can be simplified:

    {% if (amount := 5) > 0 %}
    Daniel has {{ amount }} apples!
    {% endif %}
    

    Precedence

    Assignment Operator has the lowest precedence and this must be taken into account.

    If previous example would have an expression written like amount := 5 > 0, the amount value would be true, not 5, because comparing operator has the higher precedence so it calculates first. This is why we must use brackets to isolate assignment operator.

    Assignment Operator itself can't make a global variables, but if specified variable does already exist and is global, the assignment operator will update its value and keep it global.

    Text Expressions#

    Test expressions are a complex predicate construct, they return a boolean value as result.

    Name Description Example
    Null Checks whether a value is null or not 1 is null outputs false
    Divisible Checks if a value is divisible by another 2 is divisible by 1 outputs true
    Same As Checks whether two objects are, actually, the same 1 is same as 2 outputs false
    Function based This construct is based on the available list of. 4 is defined outputs true;
    'test' is number outputs false.
    Is Not All test constructs listed before can be negated with the is not constructor. 4 is not defined outputs false

    Selection Operator#

    The selection operator is used to access a properties or object or invoke its functions. You can find available properties and functions in the Data Types and Variables articles.

    guild.name
    channel.sendMessage('hello!')
    

    Selection operator is also used in maps as well to get the value represented by given key.



    1. Precedence is the order or operator calculation , the lower the precedence, the higher the priority.