Definitions

Before we go any further, let’s baseline some definitions –

Output braces are two consecutive braces: {{ and }}. The result of this will be text output in place of whatever what is between the braces (and the braces themselves).

Logic braces are a brace appended/prepended by a percent sign: {% and %}. This will not result in output, but will be evaluated by the engine and may affect future statements/flow.

An identifier is a text token inside output braces that maps to a value in a TemplateContext.

{{ name }}

The engine will attempt to find a corresponding value for name by searching the context and its contained model or scopes.

An identifier might be modified by a member, which is one or more tokens appended to an identifier using a dot (.).

{{ name.first }}

In the above code, first is a member appended to the identifier name.

Theoretically, an identifier can have an unlimited number of members:

{{ person.parent.name.full.first.size }}

A member invokes some behavior on the output from whatever is to the left of it – it might invoke several different behaviors depending on what the identifier represents.

The member might be interpreted as:

  • The name of a property on an underlying object
  • The name of a key in an underlying dictionary
  • A key which executes code to return a calculated value

See Virtual Members for a deep dive into how this works.

A tag is a template statement in logic braces which has no closing tag:

{% continue %}

There is no endcontinue tag. Therefore, it encloses nothing.

A block also uses logic braces, but it encloses something – text, or other Liquid tags, blocks, or identifiers. The opening tag is followed by a tag of the same name prefaced by end.

{% comment %}
  This is a comment.
{% endcomment %}

Blocks are enforced by the parser. If a block doesn’t have a corresponding end tag, the parser will throw an exception.

You can define your own tags and blocks, either from a set of three pre-defined patterns, or you can extend the parser to define your own patterns.

A filter is a text value appended to an identifier/member token by a “pipe” (|).

{{ name | reverse }}

A filter might have one or more arguments. These arguments are usually positional.

{{ amount | format_number:"N0" }}
{{ name | replace:"a","b" }}

Some filters might take named arguments. This is rare, but is sometimes done when the number of arguments is variable.

{{ 'Vehicle: {0}, Wheels: {1}' | format_string:'Bicycle', 2, culture:'en' }}

In that example, there are two positional arguments – Bicycle and 2 – and a named argument of culture with a value of en.

There are dozens of built-in filters, and you can write your own.