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 developers the power to specify a value.

Literals

The most basic expressions, check the table below.

Name Regular Expression
Float -?[0-9]+'.'[0-9]+
Integer -?[0-9]+
Null Reference null
Boolean true or false
String "[^"]*" or '[^']*'
Character '[a-zA-Z]'

Identifier

An identifier is a name in Jtwig. It can contain alphanumeric characters and also underscores, but cannot start with digits. This is exactly the same regular expression as Java identifiers.

[a-zA-Z_$][a-zA-Z0-9_$]*

Of course such similarity happens on purpose, making it possible to specify any Java identifier in Jtwig templates. Such capability enables Jtwig to be fully compatible with Java identifiers, an important feature, specially, when it comes to the selection operator (as explained later on). This is one of the fundamental differences between Twig and Jtwig. Their regular expressions for identifiers are different and they match exactly the expression defined by their mother language. However different, they are quite similar. As per PHP official documentation PHP Manual, identifiers are defined according to the following regular expression:

[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*

PHP definition is very similar to Java’s one, apart from the $ character, however it also includes bytes from 127 to 225 (\x7f-\xff). Depending on the encoding, these extra bytes might be latin characters or even punctuation.

This allows one to create Jtwig and Twig compatible templates, nevertheless, it is important to be aware of such differences in order to accurately measure compatibility.

Lists

There are two ways to specify a list in Jtwig. It can be either by enumeration or by comprehension. To specify a list by enumeration, one basically need to provide every single element of the list, as shown below.

[1, 2, 3]

To specify a list by comprehension, however, one just need to specify both the beginning and the ending elements of the list, Jtwig engine, will then expand the definition. Currently, it only supports Integers or Characters.

1..3

Both lists, exemplified above, produce the same output.

Maps

It is also possible to represent collections of key and value pairs in Jtwig, so called maps, where keys can either be Identifiers or Strings and values can take form of any kind of expression.

{ key1: 'value1', 'key 2': 'value2' }

Keep in mind that identifiers used to represent the key elements are not used as variable placeholders, instead, they are converted to their String representation. For example, the identifier key1 shown above will be converted to the String value "key1".

List or Map Value Access

Whenever one need to access either a list element or map value, Jtwig, like Twig, comes with the value access expression. With such expression one 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[1]
map[“hello”]

Keywords

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

  • include
  • set
  • block
  • endblock
  • if
  • elseif
  • else
  • endif
  • for
  • endfor
  • import
  • macro
  • endmacro
  • extends
  • embed
  • endembed
  • true
  • false
  • in
  • as
  • autoescape
  • endautoescape
  • do
  • flush
  • verbatim
  • endverbatim
  • spaceless
  • endspaceless
  • filter
  • endfilter
  • null
  • is
  • not
  • with

Note that Jtwig is extensible and the list of keywords might be affected by such extensions.

Unary Operators

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

Operator Symbol P* Description Example
Negative - 5 Switches the signal -(-1) outputs 1
Not not 10 Negates the input not false outputs true
not true outputs false

* Precedence order, the lower the precedence, the higher the priority.

Binary Operators

Jtwig comes with several built in binary operators. Below, one will describe the entire list of built in binary operators.

Operator Symbol P* Description Example
Selection . 1 Access inner properties of objects. [1, 2].size outputs 2
Multiply * 5 Multiplies two values. 2.2 * 2.2 outputs 4.4
Integer Multiply ** 5 Multiplies the integer part of two values. 2.2 * 2.2 outputs 4
Divide / 5 Divides two values. 2.2 * 2.2 outputs 1.1
Integer Divide // 5 Divides the integer part of two values. 2.2 * 2.2 outputs 1
Remainder % 5 Gets the integer division remainder. 5 % 2 outputs 1
Sum + 10 Sums two values. 5 + 2 outputs 7
Subtract - 10 Subtracts two values. 5 - 2 outputs 3
Concat ~ 12 Concatenates two strings. "5" ~ "2" outputs "52"
Less < 15 Compares two values, checking whether the first is lower than the second. 1 < 2 outputs true
1 < 1 outputs false
Less or equal <= 15 Compares two values, checking whether the first is lower or equal than the second. 2 <= 2 outputs true
2 < 1 outputs false
Greater > 15 Compares two values, checking whether the first is higher than the second. 2 > 1 outputs true
2 > 2 outputs false
Greater or equal >= 15 Compares two values, checking whether the first is higher or equal than the second. 2 >= 2 outputs true
2 >= 3 outputs false
Contains in 15 Checks whether the second value contains the first one. 5 in [2] outputs false
Equivalent == 20 Compares two values, checking whether they are equal or not. true == false outputs false
false == false outputs true
Different != 20 Compares two values, checking whether they are different or not. true != false outputs true
false != false outputs false
And and 25 Conjunction boolean operator. true and false outputs false
true and true outputs true
Or or 25 Disjunction boolean operator. true or false outputs true
false or false outputs false
Compose | 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

* Precedence order, the lower the precedence, the higher the priority.

Ternary Operator

Jtwig 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.

Test Expressions

Test expressions are a complex predicate construct, they return a boolean value as result. Jtwig comes with some built in tests.

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. Note that this uses the Java == operator between the two given operands. 1 is same as 2 outputs false
Function based This construct is based on the available list of functions defined in Jtwig. It even allows one to use user defined functions in a test expression. 4 is defined outputs true. Note that defined is a function from the built in list of functions
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 uses multiple strategies to extract properties or execute a method from a given identifier. An identifier in Jtwig can either specify a native Java object or a macro import. In this section one will only detail how the extracting of Java native object properties works. Lets start with two simple examples:

var.p1
var.method1(2)

The first expression above specifies a selection operation to extract property p1 from var object. The second expression however is providing an argument, such feature allows Jtwig to execute Java methods. By default, there are several different strategies used to extract values from a Java object. All strategies are applied until one of them gets a value. It tries each strategy in the following order:

Method with the same name

In this strategy the given object meta information is searched, using reflection, for methods with the exact same name (case sensitive comparison) as the property name provided. Using the previous examples, it would search for a method with name p1 without arguments given the first expression, where for the second expression it will search for a method, again, with the same exact name and the same number of arguments.

Method prefixed with get, is or has

Similar to the previous strategy but instead of searching for an exact match, it looks for methods with the get, is or has prefixes. As per previous first example, it would try to find in the following order getP1, isP1 or hasP1. As exemplified, the first letter of the given property name is capitalized. Once again such comparisons are case sensitive. This strategy also works with arguments, exactly the same the previous strategy works.

Field with the same name

This strategy searches for fields with the exact same name as provided, the name comparison is case sensitive.

Map key with the same name

Is a strategy that only works against map objects and basically represents another way of accessing values in a map using the key as the property name.