All templates are located in the templates directory of modules. Templates are referred to by their full filename. When a template is inside a directory then the full path of the template must be given.
For example, say we have two templates:
The above are referred to as foobar.tpl and email/email_base.tpl. Just email_base.tpl will not find the email template.
All templates of all modules are grouped together, regardless of which module they are defined in. The module name is never given as part of the template name.
Templates with the same filename can be defined in multiple modules. The actual template which is selected depends on the priority of the module.
The module priority is a number defined in the module’s code and is usually a number between 1 and 1000. A lower number gives a higher priority. Templates in a module with higher priority hide templates in a module with lower priority.
When two modules have the same priority then the modules are sorted by their name. That means that, given the same priority number, mod_aloha has higher priority than mod_hello.
This mechanism allows any module (or site) to replace every single template in the system with its own version.
Exactly the same module priority is also valid for all files in the lib directory of modules.
The module priority is a very powerful mechanism for extending and adapting Zotonic.
But what if a page requested with a mobile phone should be served with a different template than the same page requested with a desktop computer?
For this there is another template selection mechanism, based on the categorization of the device requesting the page.
Every request Zotonic classifies the device using the User-Agent request header. The possible classifications are:
- Screen readers, feature phones, text only browsers.
The selected class is available in m.req.ua_class or from Erlang z_user_agent:get_class/1.
More properties can be found using m.req.ua_props or z_user_agent:get_props/1.
The four user agent classes map to subdirectories of the templates directory:
All templates that are not in those sub-directories are categorized as generic.
The template system follows a strict hierarchy between the different user agent classes:
desktop → tablet → phone → text → generic
Where the system starts looking from the current user agent class to the right. So for a phone, the templates in the tablet and desktop directories will never be considered.
The user agent class and the module priority are two dimensions of the template selection process.
The module priority is more important than the user agent class.
A mismatch in user agent class (e.g. a desktop template when looking for a phone version) will never be selected. A sub-optimal version (e.g. a generic or text version instead of a phone version) will be selected if that sub-optimal version resides in a module with higher priority than the module with the better matching version.
The all include tag will select the best version from all modules. Again skipping any user agent mismatches.
Building templates and mobile first.
The lookup strategy for templates conforms to a mobile first strategy. When adding a page or building a site, the idea is to start with the simplest, text only, version of the site. The text only version is then placed in the templates/text directory. Next will be adding more features, markup and interaction for the phone version. Only then moving up to the big screen for tablet (touch) or desktop (mouse).
Seeing which template is selected.
mod_development implements a screen where it is possible to see in real time which templates are included and compiled. The full path of all templates can be seen, giving insight in the template selection process.
See also mod_development