Templates developer guide

Edit on GitHub  

Templates are text files marked up using the Zotonic template language. Zotonic interprets that mark-up to dynamically generate HTML pages. Zotonic’s template syntax is very similar to the Django Template Language (DTL).

Variables

Variables are surrounded by {{ and }} (double braces):

Hello, I’m {{ first_name }} {{ last_name }}.

When rendering this template, you need to pass the variables to it. If you pass James for first_name and Bond for last_name, the template renders to:

Hello, I’m James Bond.

Instead of strings, variables can also be objects that contain attributes. To access the attributes, use dot notation:

{{ article.title }} was created by {{ article.author.last_name }}

The variables that you add to your templates get their values from three places:

To print the variables in your template for debugging, you can use the debug tag:

{% debug %}

Filters

Optionally, you can pipe template variables through filters. Filters transform the value before rendering it. To apply a filter, you append | plus the filter’s name to the variable:

{{ first_name|lower }} {{ last_name|upper }}

Renders:

james BOND

There’s a reference of built-in filters. If you need to, you can also create your own filters.

Tags

With tags, you can add logic and flexibility to your templates. Tags are surrounded by {% and %}, like this:

{% tag %}

Some tags have arguments:

{% tagname id width=200 height=200 crop %}

And some tags are block tags, which require both an opening and a closing tag. The name of the closing tag is always end plus the name of the opening tag:

{% if article.is_published %}
    There you go:: {{ article.title }}
{% else %}
    Sorry, the article hasn’t been published yet!
{% endif %}

See also the reference all tags. You can also create your own tags.

Models

A template model provides data to templates through the syntax: m.modelname.property. For example:

{# Get the site's title #}
{{ m.site.title }}

{# Fetch the title of the page with name page_home #}
{{ m.rsc.page_home.title }}

{# Fetch the title of the page whose id is the integer 1 #}
{{ m.rsc[1].title }}

{# Perform a search on all persons #}
{% for p in m.search[{query cat='person'}] %}{{ p.title }}{% endfor %}

{# Fetch the title of the page whose id is the template variable id #}
{{ m.rsc[id].title }}

You’ll find that you need m.rsc[id] the most, so there’s a recommended shortcut for that:

{{ id.title }}

See the reference for a list of all models. You can also add your own models.

Template names

All templates are stored in the priv/templates/ directory of sites and modules. They have the extension .tpl. Templates are referred to by their filename, including their subdirectory name within priv/templates/ (if any). So if you have these two templates:

  • modules/mod_example/priv/templates/foobar.tpl
  • modules/mod_example/priv/templates/email/email_base.tpl

you refer to them as:

  • foobar.tpl
  • email/email_base.tpl

The module name itself (mod_example) is never part of the template name, because all templates are grouped together. This allows you to override Zotonic’s templates.

Overriding templates

If you want to override a template, you create a template with the same name in your site (or module). So what if the email/email_base.tpl template from mod_example mentioned above is not to your liking? Just create a email/email_base.tpl file in your own site: sites/yoursite/priv/templates/email/email_base.tpl.

So if multiple templates can have the same name, how does Zotonic know which template to render: the one from mod_example or the one from yoursite? This depends on the module priority. Usually sites have a higher priority than modules, so yoursite wins and can serve its template.

If you want to add your template instead of overriding, you can use the all include and all catinclude tags.

Page templates

Most of your templates will be page templates. When showing a page, Zotonic’s page controller looks up the appropriate template in order of specificity and renders the first template it finds (assuming the name of the page page_name):

  1. page.name.page_name.tpl (unique name)
  2. page.category.tpl (category)
  3. page.tpl (fallback)

So if you have a page in the category ‘article’ (which is a sub-category or ‘text’) and that page has a unique name ‘my_text_page’, Zotonic will look for the following templates:

  1. page.name.my_text_page.tpl (unique name)
  2. page.article.tpl (category)
  3. page.text.tpl (category)
  4. page.tpl (fallback)

The same lookup mechanism is used for the catinclude tag.

Template structure

Now you know how Zotonic decides which template to render for a page, let’s go into how you can render templates yourself. Usually, you spread template logic for a page over multiple template files. This allows you to re-use these files in other templates.

Including templates

You can include other templates using the include tag:

This is the main template. To include another template:

{% include "other-template.tpl" %}

Zotonic will replace the include tag with the output of other-template.tpl.

Variants of the include tag are catinclude, all include and all catinclude: following the lookup mechanism described above, Zotonic will find the best template based on the page and module priority.

Inheritance

To improve template re-use, it is common to inherit from a base template. A simple base template might look like this:

templates/base.tpl
<!DOCTYPE html>
<html>
    <head>
        <title>Zotonic{% block title %}{% endblock %}</title>
    </head>

    <body>
        {% block content %}This is default content{% endblock %}
    </body>
</html>

You can then extend multiple templates from this single base template using the extends tag. The base template contains block tags that can be overridden in child templates:

templates/page.tpl
{% extends "base.tpl %}

{% block title %}This is the page title{% endblock %}

{% block content %}
    This will override the content block from base.tpl
{% endblock %}

Using the inherit and overrules tags, you adapt the inheritance to your needs.

See also

  • Media on how to include images and other media in your templates.
  • Wires on using JavaScript to add interaction to your templates.

⇄ See also

Media developer guide

Resources can have media resources attached to them. Resources and their media (images, video and audio) are connected through ‘depiction’ edges . Additionally, resources can be embedded in some HTML…

Wires developer guide

Wires are the older way to code actions and client/server interaction. It is now advised to use MQTT topics with mod_mqtt instead. Actions The action defines what should happen when the wire is…

Modules developer guide

Modules are the building blocks of Zotonic. They add functionality to your Zotonic website such as: the admin web interface embedding videos in your content search engine optimization (SEO) social…

Create a custom filter cook book

Create custom template filters to change the way variables are rendered in your templates. By following some simple rules, Zotonic will automatically find the filter for you: Create a file in the…

Create a custom model cook book

In this chapter we will look at how to implement a model around the The Open Movie Database (OMDB) API . We will touch useful background information at the same time. Model modules Models are Erlang…

Introduction developer guide

This is the Zotonic Developer Guide. It takes you through all aspects of Zotonic so you can start building your own sites as quickly as possible. If you are an end user rather than developer, you may…

Getting Started developer guide

You have two options for running Zotonic: to get started quickly, start our Zotonic container. Or you can install Zotonic on your computer. Docker First download and install Docker . Then build and…

Docker developer guide

We offer the Docker image zotonic/zotonic-dev which contains build tools and Erlang. It can be used for development work on Zotonic itself, where you’ll mount your Zotonic directory as a volume in…

The Status site developer guide

The Zotonic “status” site is the first thing you see once you have installed Zotonic, when you do not have any sites configured yet. This is what it looks like: This site is also the fallback site…

Sites developer guide

Zotonic has the capability of serving more than one site at a time. You can have multiple sites enabled, each with its own set of templates, database and dispatch rules. Each site has its own…

Controllers developer guide

Controllers are the Erlang modules which decide what happens when a browser requests a page. Zotonic looks at the dispatch rules that match the requested URL, and if a dispatch rule matches, the…

Dispatch rules developer guide

Dispatch rules route incoming requests to controllers . A dispatch rule contains a pattern that is matched against the URL of an incoming request. When a URL is requested by the web browser, the…

Resources developer guide

Resources are Zotonic’s main data unit. You may want to familiarise yourself with the Zotonic data model in the User Guide. Resource properties Resources are very flexible data units: they can have…

Templates developer guide

Templates are text files marked up using the Zotonic template language. Zotonic interprets that mark-up to dynamically generate HTML pages. Zotonic’s template syntax is very similar to the Django…

Icons developer guide

Including Zotonic icons CSS Add the CSS file to your template: { % lib "css/z.icons.css" %} This ensures that whenever a Zotonic icon class is used, the image will show up. Writing Zotonic…

Forms and validation developer guide

You should validate all input data entered in forms . In Zotonic you create forms by writing plain HTML. You can attach one or more validators to each input element. Validators define acceptable…

Search developer guide

Using the query search API you can retrieve lists of resources in various ways. In your templates, you do so through the search model : {% for id in m.search [{ query ( options go here ... ) }] %}…

Translation developer guide

Many sites need to support content and templates in multiple languages. Luckily, Zotonic is completely multilingual, out of the box. mod_translation does all the work for you. Zotonic will try to…

Access control developer guide

Access control is about defining who is allowed to access certain resources. It takes two steps: The user is authenticated , that is, the user’s identity is determined based on some form of…

Notifications developer guide

At different moments in the lifecycle of the web request, Zotonic sends notifications. By observing these notifications you can override Zotonic’s behaviour. You can also add your own notifications.

Browser/server interaction developer guide

There are multiple ways to set up interaction between server-side Zotonic code and client-side JavaScript. If you want to initiate the interaction in the client (browser) publish/subscribe. API…

E-mail handling developer guide

Configuration Any Zotonic system is capable of sending and receiving e-mail messages over SMTP. Zotonic implements a mailing system for sending text and HTML messages to one or more recipients. Out…

Command-line shell developer guide

The Zotonic shell gives you access to a running Zotonic instance with its code and data. To connect to the background Zotonic server instance within an EShell (Erlang shell): zotonic shell…

Logging developer guide

Zotonic uses Lager for logging. Lager metadata is automatically set by Zotonic, so to log a message from your code, simply call Lager directly: lager : error ( "Something went very wrong with ~p…

Testing sites developer guide

It is possible to create end-to-end integration tests for Zotonic websites. Tests like these are called sitetests . They run within the Zotonic shell, starting the website under test using a special…

Deployment developer guide

So you have built your Zotonic site, and now you want to show it to the world. This page tells you how to configure your zotonic environment so that it is ready for real-world website visitors. As…

Troubleshooting developer guide

Installation Site doesn’t start Check your database connection configuration in the zotonic_site.config file which is located in the zotonic user directory . This can be found in yoursite/priv…

Contributing to Zotonic developer guide

We encourage contributions to Zotonic from the community! This chapter describes how you can help improve Zotonic. Fork the zotonic repository on Github (at https://github.com/zotonic/zotonic ).

Release Notes release notes

Every time a Zotonic release is made, we create a document which lists the most important changes. This page contains links to the release notes for each release so far, dating back to Zotonic’s…

Upgrade notes developer guide

These notes list the most important changes between Zotonic versions. Please read these notes carefully when upgrading to a new major Zotonic version. Upgrading from 0.x to 1.0 Before upgrading to 1.

Directory structure developer guide

Zotonic is a set of regular OTP applications. These can be found in the repository’s apps/ directory: zotonic / _ build _ checkouts apps / zotonic_core…

→ Referred by

Tags category

With tags you add logic and flexibility to your templates. Built-in tags The tags that are included with Zotonic. all catinclude all include autoescape block cache call catinclude comment cycle…

Modules developer guide

Modules are the building blocks of Zotonic. They add functionality to your Zotonic website such as: the admin web interface embedding videos in your content search engine optimization (SEO) social…

Access control developer guide

Access control is about defining who is allowed to access certain resources. It takes two steps: The user is authenticated , that is, the user’s identity is determined based on some form of…

Filters category

Filters transform template variables before they are rendered. Binaries first last length to_binary Booleans yesno Dates add_hour add_day add_month add_week add_year date date_range datediff…

Create a custom filter cook book

Create custom template filters to change the way variables are rendered in your templates. By following some simple rules, Zotonic will automatically find the filter for you: Create a file in the…

Global template variables reference

These variables are always available for rendering in templates . zotonic_version The version of Zotonic, for example "1.0-dev" . zotonic_dispatch An atom with the name of the dispatch rule that…

Overriding Zotonic cook book

This chapter describes how to override the templates, styling and logic provided by Zotonic. Overriding works by adding a site or module that has a higher priority than Zotonic’s built-in modules. In…

Sites developer guide

Zotonic has the capability of serving more than one site at a time. You can have multiple sites enabled, each with its own set of templates, database and dispatch rules. Each site has its own…

Models category

Template models provide data to templates. m_acl m_acl_rule m_acl_user_group m_admin m_admin_blocks m_admin_config m_admin_identity m_admin_menu m_admin_status m_auth2fa m_authentication m_backup…

E-mail handling developer guide

Configuration Any Zotonic system is capable of sending and receiving e-mail messages over SMTP. Zotonic implements a mailing system for sending text and HTML messages to one or more recipients. Out…

∈ Developer guide Category