Edit on GitHub
Jump to docs navigation

Templating / Twig tags, functions & filters

Note: You are currently reading the documentation for Bolt 3.7. Looking for the documentation for Bolt 5.2 instead?

As mentioned before, a template in Bolt can use all of the standard Twig tags, function, filters, tests & operators, with a few additions that are specific to working with Bolt. If you're not familiar with Twig yet, you should read "Twig for Template Designers", on the official Twig website.

Below you will find Bolt specific, and common Twig tags, functions, and filters.

Twig tags

setcontent

The setcontent tag is used to perform various queries on the database. It converts a human-readable query to actual records.

Much, much more information about the setcontent tag, together with additional query arguments, pagination, sorting and other options you can find in the chapter about Fetching content.

These queries are currently possible:

  • entry/12 - get entry with id 12
  • page/about - get page with slug about
  • event/latest/5 - get latest 5 events
  • news/first/5 - get first 5 newsitems
  • quote/random/5 - get 5 random quotes
  • animal/search/5 - search for animals and return 5 of them (use where parameter 'filter' to specify search string)
  • (animal,plant)/search/20 - search for animals and plants and return 20 of them (use where parameter 'filter' to specify searchstring)
{% setcontent about = 'page/about' %}

<h3>{{ about.title }}</h3>
{{ about.introduction|raw }}

<a href="{{ about.link }}">link</a>

switch

The switch tag implements a switch statement, like the one present in PHP and many other programming languages. It allows you to 'clean up' a list of if / elseif / else statements, in a more concise way. For example:

{% set foo = 1 %}
{% switch foo %}
  {% case 1 %}
    Foo was equal to the number one.
  {% case 2 %}
    Foo was two.
  {% default %}
    This is the default fallback.
{% endswitch %}

for

This tag is used to iterate over arrays or collections of an object, similar to foreach in PHP.

<h3>Recent pages</h3>
{% setcontent pages = 'pages' limit 5 order '-datecreated' %}
<ul>
  {% for page in pages %}
    <li><a href="{{ page.link }}">{{ page.title }}</a></li>
  {% else %}
    <p>No recent pages.</p>
  {% endfor %}
</ul>

See: for in the Twig documentation.

Twig functions

asset

Use the {{ asset() }} Twig function to create public link to the so-called assets in your theme, like JavaScript, CSS or other files.

For more information, see Linking in templates.

htmllang

This Twig function will output the currently set locale in a suitable format for the HTML lang attribute in your templates. For example, if you've set locale: en_GB, this is the result:

<html lang="{{ htmllang() }}">

# <html lang="en-GB">

include

Use this to include another Twig template in the current template. Twig parses the template like any other template, so included templates have access to the variables of the active template, e.g. those that you would use in the 'main' template.

You can also use include inside the included templates.

{{ include('_header.twig') }}

For more information, see include.

An alternative to using 'include', is to set up your templates using Template Inheritance. This is a method of defining a base template, and then expand it in more detail in the templates that extend this base template. See the section on Template inheritance on the twig website.

imageinfo

Sometimes it can be useful to have more information about a specific image in your templates. You might want to know which type it is, what the dimensions are, and what the aspect ratio is. In these cases, the imageinfo function can be used. It returns an array of data about the image. See the screenshot for details:

To see the available values for an image, use:

{{ dump(imageinfo(record.image)) }}
{# assuming 'record.image' is the image of the current record. #}

For images in imagelist field types use:

{% for image in record.imagelist %}
    {{ dump(imageinfo(image.filename)) }}
{% endfor %}

The aspect ratio is the proportional relationship between the width and the height of the image. In general, this is used to determine whether an image is 'landscape' or 'portrait'. Note that an image is considered to be landscape if the aspect ratio is equal to or larger than 5:4 (1.25). An image is considered to be portrait if the aspect ratio is equal to or smaller than 4:5 (0.8). Images between those ratios are considered to be Square, even though the width and height might not be exactly equal. For example, an image that is 650 x 600 pixels is classified as square. If you need more precise values, you can do your own calculations, using the 'aspectratio' value.

For example, if you want to style an image, depending on its aspect ratio, you can use these values:

{% if imageinfo(record.image).landscape %}
    <img src="{{ thumbnail(record.image, 400, 320) }}" class="landscape">
{% elseif imageinfo(record.image).portrait %}
    <img src="{{ thumbnail(record.image, 320, 400) }}" class="portrait">
{% else %}
    <img src="{{ thumbnail(record.image, 320, 320) }}" class="square">
{% endif %}

ismobileclient

This Twig function allows you to do a basic test to check if the current client (browser) is a mobile device, like a mobile phone.

{% if ismobileclient() %}
  You are on mobile, most likely.
{% else %}
  You are most likely not on a mobile device.
{% endif %}

Note that this function is pretty rudimentary, so use it sparingly. Often, it's advisable to use media queries in CSS, for more fine-grained control over how to present information on a varying number of screen sizes.

To insert an image in the HTML, which functions as an image popup use either the popup function or filter.

You can optionally provide the width, height and cropping parameters, like you can do with the thumbnail filter.

{{ record.photo|popup(100, 100, "r") }}
or
{{ popup("2016-08/foo.jpg", 100, 100) }}

By default, Magnific will display the filename under the image in the popup. You can specify another value for this caption by using a fourth parameter (e.g alt or title tag).

{{ popup("2016-08/foo.jpg", 100, 100, 'My title') }}
or
{{ popup("2016-08/foo.jpg", 100, 100, record.values.image.alt) }}

Note that you should include the Magnific Popup .js and .css yourself, as well as set up the 'initialization' code:

<script src="/app/view/js/jquery.magnific-popup.min.js"></script>
<link rel="stylesheet" type="text/css" href="/app/view/css/magnific-popup.css">

{# set up lightbox script here, or do this in your own .js file somewhere #}
<script type="text/javascript">
  $(document).ready(function() {
    $('.magnific, div.imageholder a').magnificPopup({
        type: 'image'
        // other options
    });
  });
</script>

For more information about Magnific Popup, see the Magnific Popup website.

path

Use the path Twig function to create valid URI strings to paths configured on your site.

For more information, see Linking in templates.

canonical

Use the canonical Twig function to create a valid URI to the current page, to use in as an external link.

For more information, see Linking in templates.

url

Use the path Twig function to create valid URL strings to paths configured on your site.

For more information, see Linking in templates.

redirect

Use this function to redirect from a page to another page or domain. Commonly used in an if/else clause, to redirect visitors based on some criteria.

{% if record.image!="" %}
    <a href="{{ image(record.image) }}">
        <img src="{{ thumbnail(record.image, 400, 260) }}">
    </a>
{% else %}
    {# passive-aggressive way to tell people to find their own image #}
    {{ redirect('http://images.google.com/') }}
{% endif %}
{% setcontent records = "pages/latest/5" %}
{% for record in records %}

    <h2><a href="{{ record.link }}">{{ record.title }}</a></h2>
    <p>{{ record.excerpt() }}</p>

{% else %}

    {{ redirect(path('homepage')) }} or {{ redirect('page/some-page') }}

{% endfor %}

getuser & getuserid

Sometimes you need to fetch a specific record based on the correct user. In cases like these, You'll need to be able to get the data for this user, and the user's id. For these occasions, the functions getuserid and getuser come in handy. The function takes one argument: either a known id, or the username, that the user also uses to log on.

Example 1: Getting a user

{{ dump(getuser(1)) }}

Example 2: Using in setcontent

{% setcontent pages = "pages" where { ownerid: getuserid('admin') } %}

dump()

{% set about = content('page', {'slug': 'about'}) %}

{{ dump(about) }}

For more info on debugging your Bolt site, see the chapter on Bolt Internals.

Note: Don't forget to set debug: true in your config.yml file. Otherwise the dump() will output nothing at all.

Twig filters

excerpt

Excerpt creates a short, text-only, excerpt of a record or a string. It's useful to get short blurbs of text for overview pages, listings, et cetera. If you pass it a string, it will simply strip out HTML and, reduce it to a given length:

{% set text = "Bonum patria: miserum exilium. Ut optime, secundum" %}
{{ text|excerpt(10) }}

=> Bonum pat…

If you get an excerpt of a Record, Bolt will attempt to get an excerpt that's representative of the Record. If it has a recognisable title, it will start with that, and it will use the other text-fields to complete it. In fact, it's the same function that's used in the Bolt backend, on the dashboard.

{% setcontent page = "pages/1" %}
{{ page|excerpt(200) }}

=> Lorem ipsum dolor sit amet, consectetur adipiscing elit. Videsne quam sit magna
dissensio? Cum ageremus, inquit, vitae beatum et eundem supremum diem, scribebamus haec.
Duo Reges: constructio int…

It is also possible to highlight a keyword in an excerpt, which can be used in search results.

{% set keyword = 'ageremus' %}{# this is the keyword you want to highlight #}
{% set include_title = false %}{# this will include the title in the results #}
{% setcontent page = "pages/1" %}
{{ page|excerpt(200, include_title, keyword|default('')) ) }}

=> …consectetur adipiscing elit. Videsne quam sit magna dissensio? Cum <mark>ageremus</mark>,
inquit, vitae beatum et eundem supremum diem, scribebamus haec. Duo Reges: constructio int…

Some of your content's fields are often not wanted in an excerpt. To strip them from it, you can pass an array containing the unwelcomed fields names.

{% setcontent page = "pages/1" %}
{{ page|excerpt(200, null, null, ['your', 'unwanted', 'fieldnames']) ) }}
# or
{{ page|excerpt(stripFields=['your', 'unwanted', 'fieldnames']) ) }}

localedatetime

Outputs a localized, readable version of a timestamp, based on the locale setting in the config.yml-file. See the Locales page for more information on locales. If the locale you've set in config.yml does not work, you should verify that the locale is properly installed on your system.

In Bolt dates are stored with each record for the date the record was created, when it was last edited, and optionally when it was published. These dates are stored in a way that makes it easier for the database to work with them when it comes to sorting or selecting a specific period. They look like: 2013-02-18 09:41:10, which isn't suitable to output on the website itself. The localedatetime filter transforms the ugly timestamp to a readable, localized text. Examples:

'{{ record.datepublish }}' is the same as
'{{ record.datepublish|localedatetime("%A %B %e") }}'

Outputs:

  • '2012-12-05 06:51:16' is the same as 'mánudagur desember 5', if your locale is set to is_IS, or
  • '2012-12-05 06:51:16' is the same as 'Monday December 5', if it's set to en_GB. Note that it correctly uses capitals according to the chosen language's conventions.

Some other examples:

<ul>
    <li> Created: {{ record.datecreated|localedatetime("%c") }}</li>
    <li> Published: {{ record.datepublish|localedatetime("The %A in week %V of %Y") }}</li>
    <li> Last changed: {{ record.datechanged|localedatetime("%B %e, %Y %r ") }}</li>
</ul>

Outputs:

  • Created: Fri 9 Nov 10:55:19 2012
  • Published: The Sunday in week 07 of 2013
  • Last changed: February 17, 2013 01:09:30 pm

The localedatetime-filter uses the PHP strftime() function internally. For all possible options, see the official strftime() page on php.net.

date

{{ content.datecreated|date("M d, ’y")}}

See the various options for 'date' on the PHP website.

Note: This filter does not display a localized version of the date. Use the {{ localedatetime }}-filter if you want to display dates in other languages than English.

current

Checks if a given record corresponds to the page being shown in the browser. Useful for adding 'active' states to menus and such.

{% if page|current %}class="current"{% endif %}

or:

{% if page|current %}
    Yes, {{ page.title }} is the current page.
{% else %}
    No, you're viewing another page than {{ page.title}}
{% endif %}

round, ceil and floor

The round, floor and ceil modifiers can be used to round numbers (or strings containing a numerical-like values) to the nearest integer, which basically means "whole number".

{% set pi = 3.141592 %}

Rounded, Pi is {{ pi|round }} {# "3" #}

The constant Pi is somewhere between {{ pi|floor }} and {{ pi|ceil }}
{# "3 and 4" #}

If you need fancier number formatting than this, you can use the built-in Twig number_format-filter. See the docs here.

slug

The slug filter can be used to transform any string into a slug-like value. This can be very useful when you're hand-crafting links to categories, pages or other structures where you need a URL-safe representation of a string.

In this example, we build links to all category listing pages:

<ul>
{% for category in app.config.get('taxonomy/categories/options') %}
    <li><a href="/category/{{ category|slug }}">{{ category }}</a></li>
{% endfor %}
<ul>

shy

The "soft hyphenate" filter can be used for strings without spaces, that would otherwise break the layout of your page. By adding these soft hyphens, the browser knows it can wrap to the next line. For example:

|                         |
| Before: {{ file }}      |
| MyVeryLongFilenameWithoutSpacesOrDashesOrWhatever.jpg |
|                         |
| After: {{ file|shy }}   |
| MyVeryLongFilenameWith- |
| outSpacesOrDashesOrWha- |
| tever.jpg               |
|                         |

safestring

Use this modifier to return a "safe" version of the string. For example:

{% set text = "Bonum patria: miserum exilium. Ut optime, secundum" %}
{{ text|safestring(true) }}

=> bonum-patria-miserum-exilium-ut-optime-secundum

Characters in the string are converted to lowercase, accented ones are converted to their lowercase ASCII equivalent. Punctuation signs, and trailing space if present, are replaced by hyphens.

You can specify two parameters: strict mode and extrachars.

  • Strict mode (boolean, default to false): spaces are converted to hyphens.
  • Extra chars (string, default to empty): A string containing extra non-alphabetical characters to keep in result.
{# Default settings #}
{% set text = "Bonum patria: miserum exilium. Ut optime, secundum" %}
{{ text|safestring() }}

=> bonum patria-miserum exilium-ut optime-secundum

{# Strict mode #}
{% set text = "Bonum patria: miserum exilium. Ut optime, secundum" %}
{{ text|safestring(true) }}

=> bonum-patria-miserum-exilium-ut-optime-secundum

{# Keep dots #}
{% set text = "my beautiful image.jpg" %}
{{ text|safestring(true, ".") }}

=> my-beautiful-image.jpg

showimage

Use this filter to insert an image in the HTML. You can optionally provide the width, height and cropping parameters, like you can do with the thumbnail filter.

{{ record.photo|showimage(800, 600) }}
or
{{ showimage("2013-03/foo.jpg", 800, 600) }}

thumbnail

Use this modifier to create a link to an automatically generated thumbnail of a size of your choosing. For example:

<img src="{{ content.image|thumbnail(320, 240) }}">

If content.image is an image in your files/ folder, like foo.jpg, this modifier will output a link like /thumbs/320x240/foo.jpg. This is useful for creating absolute links to a thumbnail, regardless of whether Bolt is installed in the root of your domain, a subdomain or a folder.

You can specify three parameters: the width, height, and the mode of cropping. The mode of cropping is important if you're requesting a thumbnail that has different proportions than the original image. Valid options for cropping are:

  • 'c' (crop, default) - Makes sure you always get an image that is the specified width and height. The image is not transformed, so it will be cropped to fit the boundaries is necessary.
  • 'f' ('fit') - The image will not be cropped but resized to fit within the given maximum width and height. This means that you will always get an image with the exact same width and height that you specified. The resulting image might be deformed, and will not have the same aspect ratio as the original.
  • 'b' (borders) - Will add a border to the image, in order to make it fit within the given boundaries.
  • 'r' (resize) - Will resize the image to fit the boundaries, without cropping. This means your thumbnail might be smaller than the width/height given, but the the image will always maintain the aspect ratio of the original image.

Use the cropping parameter like this:

<img src="{{ content.image|thumbnail(100, 100, "r") }}">

If you omit the width and height altogether, the thumbnail will use the 'default' size and cropping mode. Remember to add quotes around the cropping mode.

<img src="{{ content.image|thumbnail }}">

You can set the size in your config.yml, like this:

thumbnails: [ 160, 120, c ]

To use a defined thumbnail alias, you just need to pass in your alias name like so:

<img src="{{ content.image|thumbnail('cover') }}">

image

Use this modifier to create a link to an image of your choosing. For example:

<img src="{{ content.photo|image }}">

If content.photo is an image in your files/ folder, like 2012-11/foo.jpg, this modifier will output a link like /files/2012-11/foo.jpg. This is useful for creating absolute links to an image, regardless of whether Bolt is installed in the root of your domain, a subdomain or a folder.

You can specify three parameters: the width, height, and the mode of cropping. By doing so, the image will be resized, and it behave exactly like the thumbnail filter.

<img src="{{ content.photo|image(100, 100, "r") }}">

To scale an image proportionally to a given width or height, set the other dimension to null, and set cropping mode to resize.

<img src="{{ content.image|image(400, null, "r") }}">

raw

If the content contains HTML-fields, they will be rendered with escaped characters by default. If you want to use the HTML as-is, add the raw modifier:

{{ page.tite|raw }}

If we didn't add the raw modifier, all '<' and '>' characters in the body would be output as '&lt;' and '&gt;' respectively. If 'body' is an HTML field in our ContentType, we want it to be output as normal HTML, so we have to add the raw modifier.

order

In most cases the results of {% setcontent %} or {{ record.related() }} are in the desired order. In some cases you might want to reorder them, by using the order-filter. The filter takes one or two parameters: the names of the fields you wish to order the results on:

{% set relatedrecords = record.related() %}
<p class="meta">Related content:
    <ul>
    {% for related in relatedrecords|order('datepublish') %}
        <li><a href="{{ related.link }}">{{ related.title }}</a></li>
    {%  endfor %}
    </ul>
</p>

or:

{# get the 10 latest entries by date, but sort them on the title field #}
{% setcontent entries = "entries/latest/10" %}
<ul>
{% for entry in entries|order('title', 'subtitle') %}
    <li><a href="{{ entry.link }}">{{ entry.title }}</a></li>
{%  endfor %}
</ul>

Note: Ordering with the order-filter is case sensitive. This means that 'banana' will come before 'Apple'. If you're sorting on a title or name field and this case sensitivity is undesirable, you can use |order('slug') instead. The slug is always lowercase, so this will normalize the ordering.

preg_replace

Makes PHPs preg_replace() function available as twig filter. Example usage:

{{ content.text|preg_replace('/[^a-z]+/', '_') }}

Available variables in Twig

app

{{ app.config.get('general/sitename') }}
{{ dump(app.config.get('general')) }}

For more info on app, see the chapter on Bolt Internals.

Tests

json

Use this test to determine if a given variable is JSON.

Examples:

{% if var is json %}
    JSON: {{ var }}
{% else %}
    JSON: {{ var|json_encode }}
{% endif %}
{% if var is json %}
    Decoded: {{ var|json_decode }}
{% endif %}

defined (for extensions)

Use this test to determine if a certain extension is available. You can use this in your themes, when it's not apparent whether or not the user will have a certain extension installed.

Examples:

{% if app.extensions.get('Bolt/FacebookComments') is defined %}
    {{ include(template_from_string("{{ facebookcomments() }}")) }}
{% endif %}

You can also use this to output a friendly warning to users of the template:

{% if app.extensions.get('Bolt/BoltForms') is defined %}
    {{ include(template_from_string("{{ boltforms('contact') }}")) }}
{% else %}
    <p>Warning: This theme suggests you install the 'BoltForms' extension.</p>
{% endif %}

Note: in the {% if %} tag you must use the vendorname and extensionname of the extension as a string, so be sure to use quotation marks. If you're not sure what the correct name is that you need to use, dump the installed extensions to find out:

{{ dump(app.extensions.all()) }}


Edit this page on GitHub
Couldn't find what you were looking for? We are happy to help you in the forum, on Slack or on Github.