-
Notifications
You must be signed in to change notification settings - Fork 130
Templating Language
Stacey pre-parses each template using the Twig templating language, which is based on the excellent Jinja templating library for Python. You can refer to the Twig documentation for a more detailed account of its capabilites.
In general, there are three type of tags:
{% template logic %} | Containment for template logic. Primarily used for loops, if statements, setting variables and including partials. Equivalent to PHP's <?php ?> tags. |
{{ render output }} | Used to output variables. If the variable is not set, then nothing will be output. Equivalent to PHP's <?= ?> tags. |
{# comment block #} | Marks comments within templates. Comment blocks themselves are never rendered in the final generated output. |
Within these tags, there are a number of template constructs that Twig allows.
Gives the ability to loop over collections.
{% for page in page.children %}
{# output something #}
{{ page.variable }}
{% endfor %}
In the above example, page can be set to any name that makes sense to you. For example, you could substitute it with child like the following:
{% for child in page.children %}
{# output something #}
{{ child.variable }}
{% endfor %}
In Twig, for loops can be combined with else blocks. In the below example, if the page.children collection doesn't exist, then the contents of the else block will be executed.
{% for page in page.children %}
{# output something #}
{{ page.variable }}
{% else %}
{# if page.children doesn't exist, run this block #}
No children.
{% endfor %}
Twig allows standard 'does this exist?' if statements as well as proper mathematical comparisons. This means you can create statements like:
{% if page.children|length > 0 %}
{# Standard usage #}
{% if page.variable %}
{# output something #}
{{ page.variable }}
{% endif %}
Standard else blocks are also supported.
{% if page.variable %}
{# output something #}
{{ page.variable }}
{% else %}
{# output something else #}
{{ page.other_variable }}
{% endif %}
Partial templates separate out re-usable and repeatable blocks of html into their own files. They sit within the /templates/partials folder. As with templates, partials do not need to be .html files. Stacey will recognise any file extension.
To include a partial in your template, you use the following syntax:
{# include a partial template #}
{% include 'partials/navigation/children.html' %}
You can also pass specific named variables and collections through to the partial template:
{# pass the 'child' variable through to the template #}
{% for child in page.children %}
{% include 'partials/navigation/child.html' with { 'page': child } %}
{% endfor %}
{# pass the 'children' collection through to the template #}
{% set children = page.children %}
{% include 'partials/navigation/children.html' with children %}
Variables and collections can be modified by filters. Filters follow the variable or collection and are separated by a pipe (|) symbol. Filters can also be stacked.
The following filter is an example of taking the page_name variable and outputting it in lowercase.
{{ page.page_name|lowercase }}
{% for page in page.children|reverse %}
{# Reversed list of child pages! #}
{% endfor %}
In addition to the Twig's default language set, there are a number of utility functions which which are available.
Within a template, you can use the get() method to change to the context to a different page. The method must be passed a valid absolute page url.
{# set the page variable to a different page context #}
{% set page = get('/projects') %}
{# page.page_name will now equal 'Projects' #}
{# 'page' is '/' #}
{% block context %}
{% set page = get('/projects') %}
{# do stuff within the context of the '/projects' page #}
{% endblock %}
{# the page variable is set back to '/' #}
The get() function can also be used to change the context relatively by passing the current page url as a second parameter.
In the below example, the page variable is will be set to the context of the /child-page folder which which sits below the current page. This means you are not limited to passing absolute urls (ie. /projects/project-1/child-page)
{# set the page variable to a relative page context #}
{# this will change the context to the 'child-page' below the current page #}
{% set page = get('/child-page', page.url) %}