Tags are used to control the flow of the template. They are enclosed in {% %}.

Each section below represents a built-in tag.


The block tag is used to render the contents of a block more than once.

In the following example we create a block with the name 'header':

{% block header %}
    <h1> Introduction </h1>
{% endblock header %}

Then the block tag can be used with the block function

{{ block("post") }}


The filter tag allows you to apply a filter to a large chunk of template.

{% filter upper %}
{% endfilter %}

{# output: 'HELLO' #}

Multiple filters can be chained together.

{% filter upper | lower | title %}
{% endfilter %}

{# output: 'HELLO&lt;br&gt;' #}


The for tag is used to iterate through primitive arrays or anything that implements the java.lang.Iterable interface, as well as maps.

{% for user in users %}~
    {{ user.name }} lives in {{ user.city }}.
{% endfor %}

While inside the loop, Pebble provides a couple of special variables to help you out:

  • loop.index - a zero-based index that increments with every iteration.
  • loop.length - the size of the object we are iterating over.
  • loop.first - True if first iteration
  • loop.last - True if last iteration
  • loop.revindex - The number of iterations from the end of the loop
{% for user in users %}
    {{ loop.index }} - {{ user.id }}
{% endfor %}

The for tag also provides a convenient way to check if the iterable object is empty with the included else tag.

{% for user in users %}
    {{ loop.index }} - {{ user.id }}
{% else %}
    There are no users to display.
{% endfor %}

Iterating over maps can be done like so:

{% for entry in map %}
    {{ entry.key }} - {{ entry.value }}
{% endfor %}


The if tag allows you to designate a chunk of content as conditional depending on the result of an expression

{% if users is empty %}
    There are no users.
{% elseif users.length == 1 %}
    There is only one user.
{% else %}
    There are many users.
{% endif %}

The expression used in the if statement often makes use of the is operator.

# Supported conditions

If tag currently supports the following expression

ValueBoolean expression
booleanboolean value
Empty stringfalse
Non empty stringtrue
numeric zerofalse
numeric different than zerotrue


The macro tag allows you to create a chunk of reusable and dynamic content. The macro can be called multiple times in the current template.

It doesn't matter where in the current template you define a macro, i.e. whether it's before or after you call it. Here is an example of how to define a macro:

{% macro input(type="text", name, value) %}
    <input type="{{ type }}" name="{{ name }}" value="{{ value }}" />
{% endmacro %}

And now the macro can be called numerous times throughout the template, like so:

{{ input(name="country") }}
{# will output: <input type="text" name="country" value="" /> #}

A macro does not have access to the same variables that the rest of the template has access to. A macro can only work with the variables provided as arguments.

# Access to the global context You can pass the whole context as an argument by using the special _context variable if you need to access variables outside of the macro scope:

{% set foo = 'bar' %}

{{ test(_context) }}
{% macro test(_context) %}
    {{ _context.foo }}
{% endmacro %}

{# will output: bar #}


The raw tag allows you to write a block of Pebble syntax that won't be parsed.

{% raw %}{{ user.name }}{% endraw %}
{% raw %}
    {% for user in users %}
        {{ user.name }}
    {% endfor %}
{% endraw %}


The set tag allows you to define a variable in the current context, whether it currently exists or not.

{% set header = "Test Page" %}

{{ header }}