Templates

A template is a text file with a special markup that Moya uses to generate output (typically HTML). Templates are combined with data generated from Moya code to produce the page requested by the user.

Template Filesystem

Templates are stored in a directory within each Library (see Creating a Library). When Moya starts up, the template folders for each installed library are combined to creates a single virtual filesystem (called "templates"). This filesystem is used internally by Moya, but may be used as any other filesystem.

You can see which directories are used in the templates filesystem with the following command line:

$ moya fs templates

You can also see a tree view of the templates filesystem with the following:

$ moya fs templates --tree

When adding templates to a library it is important to follow the convention of putting them in a directory named after the Library long name. For example, if your library is called moya.blether then your templates should be stored templates/moya.blether/.

This convention makes it possible for a library to override a template in another library, which can be useful for customizing the look and feel of your web application. For example, in moya.pages (a builtin library) there is a template called page.html with the path moya.pages/page.html. If another library also contains a template with a path of moya.pages/page.html it will be used in place of the original, if the library it belongs to has a higher priority (see below).

When there are two or more conflicting paths in template directories, Moya selects the one with the highest priority value (defined in the [template] section of lib.ini). If two templates have the same priority, then the library imported last wins.

A project may also define a templates directory in project settings which is added to the templates filesystem. This allows you to customize template at a project level.

Rendering Templates

There are a few tags which you may use in Moya code to render a template. One such tag is <render-template> which renders a template to a string. Let's look at an example of how you might use this tag:

<render-template template="product.html" dst="html"/>

The above code will read a template from your templates filesystem called "product.html", it will then render that template and store the response in a variable called html.

In the preceding example, the value for template is a relative path (it doesn't start with a forward slash). When Moya is asked to load a template from a relative path, it will look for it in the templates directory for the current application (where <render-template> was called). So if the above code was called from an application installed from the library moya.sushifinder, Moya will read the template /moya.sushifinder/product.html.

If a template path is absolute (i.e. starts with a slash), then Moya looks for the template in the root of your templates filesystem. Absolute template paths aren't used as often, because most applications will use only the templates bundled in the library. Templates in the root of the template filesystem are reserved for common site-wide templates.

You can also tell Moya to read a template from another application with the from attribute, which expects an application name, or a library name if you only have one instance of that library installed. For example, here's how you could render a template from the Moya Pages library:

<render-template template="page.html" from="moya.pages" dst="html" />

This will read the template from /moya.pages/page.html. You could replaced the template attribute with this path, but using from attribute is preferred because it is possible for an application to change the directory where its templates are stored, with the templates_directory setting.

You can supply data to templates with the <render-template> tag in a similar way to compound data types, such as dictionaries. The following renders a template called product.html and supplies a template data value called product, which may be inserted in to the output:

<render-template template="product.html" dst="html">
    <str dst="product">Nigiri</str>
</render-template>

You can also use the LET extension, which can be more compact. The following is equivalent to the previous example:

<render-template template="product.html" let:product="Nigiri" dst="html"/>

There are other ways of rendering templates, which we will cover in URLs, Views and Middleware.

Template Basics

In a template, everything inside {% and %} is considered a template tag and will contain processing instructions that change the output in some way. Some tags are stand-alone, but others may contain blocks of more template code. For example, the {% for %} tag repeats a block of code for every value in a collection. It will repeat everything up until and {% endfor %} tag.

Data may be inserted directly within a template with the same substitution syntax used in Moya code. Anything inside ${ and } is considered an expression, and will be replaced with the result of that expression.

Here's an example of a simple block of template code. The following template takes a list of strings called crew and will generate an HTML unordered list:

<ul>
{% for character in crew %}
    <li>${title:crew} is on board</li>
{% endfor %}
</ul>

The value of crew may be any collection, such as a simple list, but in a real site it would likely be the results of a query run on the database. Lets use the value of crew generated from the following Moya code:

<list dst="crew">
    <str>john</str>
    <str>rygel</str>
    <str>scorpius</str>
</list>

When the template is rendered with the list above, Moya will generate the following HTML markup:

<ul>

    <li>John is on board</li>
    <li>Rygel is on board</li>
    <li>Scorpius is on board</li>

</ul>

Controlling Whitespace

You may have noticed that the example in the example template code produced two extra lines inside the <ul> html tag. This is because a new line was created for the {% for %} and {% endfor %} template tags. The new line characters are still present in the rendered output. We could format our code in the following way to avoid littering the output HTML with superfluous new lines:

<ul>{% for character in crew %}
    <li>${title:crew} is on board</li>{% endfor %}
</ul>

The downside is that now our template code is somewhat harder to read. Moya offers an alternative way of removing un-needed whitespace. If you add a hyphen (-) at the beginning of a tag (i.e. {%-) then the whitespace up to the start of the tag will be removed. If you add a hyphen at the end of the tag (i.e. -%}) then the whitespace after the tag will be removed. Here's how you would use this extra syntax with the example template code:

<ul>
{%- for character in crew %}
    <li>${title:crew} is on board</li>
{% endfor -%}
</ul>

This will produce the following output:

<ul>
    <li>John is on board</li>
    <li>Rygel is on board</li>
    <li>Scorpius is on board</li>
</ul>

Escaping

Moya escapes variables used in templates by default. In other words, it replaces special characters such has < > and & which might otherwise be interpreted by the browser as HTML.

For example, let's say we have a variable called name, presumably entered by a user at some point. This user has given his name as <h1>Rygel</h1> in an attempt to have his name styled as a header everywhere it is mentioned. Moya will replace the angular brackets with &gt; and &lt; when the value is rendered in a template – and the user will see literal angular brackets.

There are some occasions where variables contain markup that you do want to be inserted in to the rendered output. In these situations, you can use the html: modifier to tell Moya not to escape the result of an expression. For example:

<p>${html:markup}</p>

The above template code will insert the value of markup directly in to the HTML without modification.

WARNING Exercise caution when inserting HTML in to your templates like this. It would be a significant security risk if an end user is able to directly influence the markup generated by your templates.

Template Inheritance

In a typical web page there will be some content that is unique to the page, but a large portion of it will be common to other (possibly all) pages. For instance, a page might have a menu system, columns, footer etc. And there will probably also be a number of common assets like Javascript and CSS. If would be tiresome if we had to construct all this common code for each page we want to render. Moya makes it possible to extract the common elements in a web page so they need only be written once, via template inheritance.

The {% extends %} template tag tells Moya that a template extends another template. Moya will combine the content in the extended template with the one being rendered. Let's look at an example of a template (product.html) which extends from a template called base.html:

{% extends "base.html" %}
{% block "content" %}
<h1>Order ${title:product} Here</h1>
{% endblock %}

Note that the above template is obviously incomplete and doesn't contain the HTML required for a working page.

The line {% extends "base.html" %} tells Moya to combine the contents of product.html with base.html. The {% block %} tag in product.html tells Moya that the markup it contains is a block with the name of content. The base template also contains a block of the same name, which will be replaced with the new block when the template is rendered.

Here's what base.html looks like:

<html>
    <head>
        <title>Sushifinder</title>
    </head>
    <body>
        {% block "content" %}
        <h1>Welcome to Sushifinder!</h1>
        <p>Order Sushi from your nearest restaurant</p>
        {% endblock %}
    </body>
</html>

It's this base template which contains the standard HTML markup for a complete page. The {% block %} tag in base.html will be replaced with the contents of the similarly named block in [c]product.html.

Note, that if product.html did not contain a content block, then the markup in the base template's content block would not be changed. In this way, a template may selectively override parts of the template it extends.

There is no limit to the number of times a template can be extended. You could have a base.html template with a header and footer, and templates for page layout that extend base.html. If you find that you are cutting and pasting large blocks of markup for new templates, then it is a good indication you should create a new base template to extend from.

Extending Blocks

When Moya extends a template it will replace blocks in the base template with content from the template being rendered. Occasionally, you may want to keep the content in the base template as well as adding new content. The {% block %} template tag accepts an extra argument that defines what will happen to the base content; replace is the default behaviour, but you may also use append which renders the new markup after the base markup, or prepend which puts the new markup before the base markup. Let's look at an example of this. The following is a block in a base template:

<html>
    <head>
    {% block "css" %}
    <link href="/media/css/site.css" rel="stylesheel" />
    {% endblock %}
    </head>
    <body>
        <!-- content here -->
    </body>
</html>

If we were to extend a template with the css block above, we would loose that stylesheet link (by default). If we want to keep it, we can define our new block as follows:

{% extends "base.html" %}
{% block "css" append %}
<link href="/media/css/page.css" rel="stylesheel" />
{% endblock %}

If we were to render the above template, we would get the following output:

<html>
    <head>

    <link href="/media/css/site.css" rel="stylesheel" />
    <link href="/media/css/page.css" rel="stylesheel" />

    </head>
    <body>
        <!-- content here -->
    </body>
</html>

As you can see, the rendered template includes the code from the css block, from both templates.

Tags

All template tags following a similar pattern; the first word inside the {% %} syntax is the name of the tag. The name may be followed by zero or more required parameters (text or expressions). Optional parameters are introduced by a single word followed by an expression.

Some template tags enclose a section of template code. These tags must be paired with an end tag which marks the end of the associated template code. For example, every {% for %} template tag must be paired with an {% endfor %}. It is also possible to mark the end of the most recently opened tag with {% end %}. However, it is generally recommended to use the explicit end tag, which is self-documenting and allows the template system to detect errors in your template code. The exception would be if the associated template code is short, perhaps on a single line, and you want it to be more compact.

Conventions

Because a project is assembled from a number of libraries, it is important to provide a way to make all pages look like they belong to the same site regardless of which library rendered them. The following conventions emerged from the design of the built in libraries to do just that. As with all conventions, you should follow them only as long as they make sense for your use case.

NOTE The following only applies to templates that create an entire page – and not to widget templates, or other templates that render individual components of a page.

Put a template in the library's template directory called base.html which other templates should ultimately extend. This ensures that there is a base template per library that may be overriden to customize look & feel / branding. So templates in a library should start with the following line (unless they extend another base):

{% extend "base.html" %}

Your base template should be empty apart from the following:

{% extends "/base.html" %}

This ensures that all templates ultimately extend /base.html which would contain the markup that should be common to all pages.

REMINDER relative paths in extends will use a path relative to the library, absolute paths (starting with /) will be relative to the root of the templates filesystem.

If you created a project with the moya start command, it will have created a /base.html template as follows:

{% extends "/moya.twitter.bootstrap/base.html" %}

This further extends from a template in the moya.twitter.bootstrap library. This template is a based on one of the example in http://getbootstrap.com/, and creates a simple blank page with a navbar (menu). You can use this as a starting point for your project, or write a base from scratch.

Tag Reference

The following are the tags you can use in Moya Templates:

{% attrib %}

{% attrib [attributes] %}

Renders a sequence of html attributes from a dict or dict-like collection. For example:

<div {% attrib id="body", style="enhance" %}>
    Test
</div>

This produces the following output:

<div id="body" style="enhance">
    Test
</div>

If the values of the dictionary are a list, Moya will render them with a space between each word.

<div {% attrib id="message", class=['alert', 'alert-error'] %}>
    That didn't work
</div>

This would product the following output:

<div id="message" class="alert alert-error">
    That didn't work
</div>

If any of the values are missing or None, then the attribute will be omitted entirely. For example, take the following template code:

<div {% attrib class=post.extra_class %}>
    ${html:post.html}
</div>

if post.extra_class is not None, Moya will render a class attribute on the <div>. If post.extra_class is None, then there will be no class attribute in the output.

The preceding example is equivalent to the following:

<div {% if not isnone:post.extra_class %}class="${post.extra_class}"{% endif %}>
    ${html:post.html}
</div>

{% block %}

{% block <name> [<replace|append|prepend>] %}{% endblock %}

Creates a named block, which may be extended in a derived template. If a template with a named block extends another template with a similarly named block, then the contents will be combined with the block in the extended template.

For example, lets say we have the following template, named "base.html":

<html>
    <body>
        {% block "body" %}
        <p>Content in base.html</p>
        {% endblock %}
    </body>
</html>

And we are rendering the following template, which extends from "base.html":

{% extends "base.html" %}
{% block "body" %}
<p>This content replaces the block in base.html</p>
{% endblock %}

If we render the template above, it will render "base.html", but with the "body" block replaced with new code. The output will look like this:

<html>
    <body>
        <p>This content replaces the block in base.html</p>
    </body>
</html>

The default for a block is to completely replace the contents of the block it has extended. You can also opt to append the new content to the content in the extended template, or to prepend it (render it before the content in the extended template). You can select which by specifying one of 'append', 'prepend' or 'replace' (the default) in the block tag.

Here's how we might modify our template to include the content in block and the new content:

{% extends "base.html" %}
{% block "body" append %}
<p>This content will be appended to the block in base.html</p>
{% endblock %}

If we render the above template, we will get the following output:

<html>
    <body>
        <p>Content in base.html</p>
        <p>This content will be appended to the block in base.html</p>
    </body>
</html>

{% cache %}

{% cache for <timespan> [key <key expression>] [in <cache name>] %}{% endcache %}

This tag caches the enclosed template code for a period of time. The first time Moya encounter this template tag, it renders the enclosed block and stores the result in a cache, with a key generated from a key expression, which should be either a string or a list of objects that will be converted in to a string. The next time Moya renders the same tag it will replace the block with the markup stored in the cache. For example:

{% cache for 1d key [news.id, news.update_time] %}
<div class="news">${news.text}</div>
{% endcache %}

This will store the html in the cache for the news object, so that it doesn't have to render it every time. Note that the key is a combination of news.id and news.update_time, so a unique copy of the template code will be produced for every combination of these two variables. The value of update_time is used so that html is re-generated if the news is updated, otherwise it would not change for a full day.

Note that the primary reason for using this tag is to speed up rendering of templates. The simple example given here is likely quicker to render than it would be to look it up in the cache. A better candidate would be if either the template code inside the tag is particularly complex or it uses a slow database query. Good use of caching can reduce the load on the server significantly.

{% call %}

{% call <macro> [with <parameters>] [only] %}

Call a previously defined template macro with optional parameters. If given, parameters should be a dict or similar object with parameters to be used as arguments to the template macro.

By default, a template macro has access to all the variables passed in to the template. This is generally useful, but if you specify the 'only' clause then the template macro will only have access to the arguments passed to it. The follow is an example of calling a template macro.

{% def greet %}
<p>Hello, ${name}!</p>
{% enddef %}

{% call 'greet' with name="Scorpius" %}
{% call 'greet' with name="Rygel" %}

This will produce the following output:

<p>Hello, Scorpius!</p>
<p>Hello, Rygel!</p>

{% children %}

{% children [as <target>] [with <template arguments>] [set <options dict>] [unique] %}

Used in widgets and content, this will render the children of the content element.

{% console %}

{% console <text or object> %}

Used for debugging, Moya will write text or an object to the console when rendering a template.

{% data %}

{% data [as <name>] %}{% enddata %}

This will insert data in to the template context. The context of the tag should be JSON. If the as clause is specified, then this will be used as the name to store the JSON data. If no as clause is specified, then the JSON should be an object, and will update the template context with the objects keys / values.

Here's an example of creating a list in the template context called, "crew":

{% data as "crew" %}
[
    "Rygel",
    "Scorpius",
    "Aeryn",
    "John"
]
{% enddata %}

{% def %}

{% def <macro name> %}{% enddef %}

Defines a template macro, which is re-usable template code that may be invoked with different parameters. Here's an example of a simple template macro:

{% def "greet" %}
<p>Greet, ${name}</p>
{% enddef %}

Template macros may be invoked with the {% call %} tag.

{% elif %}

{% elif <condition> %}

May be used inside an {% if %} tag. If the condition of the parent {% if %} is false, and the condition for this tag is true then the enclosed template code will be rendered. For example:

{% if fuel > 100 %}
    <p>Taking off!</p>
{% elif fuel > 0 %}
    <p>Not enough fuel.</p>
{% else %}
    <p>Fuel tank is empty!</p>
{% endif %}

{% else %}

{% else %}

May be used inside an {% if %} tag. If the condition (in the parent if) is false then the code inside the {% else %} will be executed. For example:

{% if fuel > 100 %}
    <p>Taking off!</p>
{% else %}
    <p>Not enough fuel.</p>
{% endif %}

{% emit %}

{% emit <text> %}

Insert markup directly in to the output without any processing. This is primarily used for outputting markup that looks like a template tag or substitution without processing it. For example:

{% emit "<p>${literal}<p>" %}

This would produce the following output:

<p>${literal}<p>

{% empty %}

{% for %}{% empty %}{% endfor %}

Used in conjuction with a {% for %} tag, this template code between an {% empty %} tag and the {% endfor %} tag is rendered if there were no values in the for loop (i.e. it was empty).

{% for character in crew %}
<p>${character} is on board</p>
{% empty %}
<p>Nobody is on board!</p>
{% endfor %}

{% emptyblock %}

{% emptyblock <block name> %}

Shorthand for a {% block %} that has no content.

<html>
    <body>
        {% emptyblock "body" %}
    </body>
</html>

{% extends %}

{% extends <template path> [from <application name>] %}

Extends the current template from another template. If the path is relative, it is taken to be relative from the template directory associated with the current application. If it is absolute, it is assumed to be from the root of the templates filesystem.

For example, lets say we have the following template in a library called sushifinder.shop:

{% extends "shop.html" %}

Because the path above is relative, Moya will extend from the template /sushifinder.shop/shop.html (in the templates filesystem).

The behavior will be different if we use an absolute path. For example:

{% extends "/shop.html" %}

This tells Moya to extend from the template "shop.html" in the root of the templates filesystem.

It is also possible to extend from a different application by specifying either the application or library name in the from clause. For example, here's how to extend from a template in the moya.pages library.

{% extends "page.html" from "moya.pages" %}

This will extend from the template /moya.pages/page.html.

{% for %}

{% for <items list> in <collection> %}{% endfor %}

Repeat a block of code for every item in a collection. For example, if we have a list defined in Moya code as the following:

<list dst="crew">
    <var>['John', 'Human']</var>
    <var>['Rygel', 'Hynerian']</var>
    <var>['Aeryn', 'Peacekeeper']</var>
</list>

We can render each item in the list with the following template code:

{% for character, species in crew %}
<p>${character} is a ${species}</p>
{% for %}

See also the {% empty %} template tag.

{% if %}

{% if <condition> %}{% endfor %}

Renders the enclosed block if a condition evaluates to true. For example:

{% if fuel > 100 %}
    <p>Taking off!</p>
{% endif %}

{% include %}

{% include <template path> [from <application or library>] %}

Render another template in the current context. The included template has access to all the template variables from the template it was included from. The arguments are the same as the {% extends %} tag.

{% inspect %}

{% inspect <object> %}

This tag will generate an HTML <pre> tag containing information about an object. The generated HTML will produce output in the same format as writing the object to the console.

This tag is a debug aid; it can help you visualize the data being rendered by your template. You should probably remove all inspect tags before your application goes in to production.

{% let %}

{% let <dict> %}

Insert data in to the template context. The first argument should be a dict. Keys and values from this dict are inserted in to the current context, and may be used as any other template variable. Here's an example:

{% let foo="bar", baz="egg" %}
<p>${foo}</p>
<p>${baz}</p>

{% markup %}

{% markup <markup> [as <output type>] [target <target>] %}

Render markup, such as bbcode and markdown. The type of the markup should be specified in the as clause. The target clause should specify what the output should be (default is html). Here's an example:

{% markup "[b]Hello, World![/b]" as "bbcode" %}

{% media %}

{% media <media path> [media <media library>] [from <application or library>] %}

Get a URL to a media file. Here's an example:

<img src="{% media 'img/logo.png' from 'moyaproject.sushifinder' %}>

{% render %}

{% render <renderable object> [with <template data>] [to <target format>] [set <render options>] %}

Render an object.

{% renderall %}

{% renderall <renderable objects> [with <template data>] [to <target format>] [set <render options>] %}

Render a collection of objects.

{% singleline %}

{% singleline %}{% endsingleline %}

Removes all new-lines in a block of template code. Here's an example:

{% singleline %}
<p>
Hello, World!
</p>
{% endsingleline %}

This produces the following output:

<p>Hello, World!</p>

{% summarize %}

{% summarize chars NUMCHARS %}

This tag takes a block of HTML and converts it to text. If the text has less than NUMCHARS it is unchanged. Otherwise, Moya will truncate it at a word boundary and add ellipses.

This is intended for situations where you want to preview the content of a page in some kind of index. In a blog's recent posts list for example. Here's how it could be used:

<h2>${post.title}</h2>
<p class="summary">
{% summarize chars 120 %}${html:post.html}{% endsummarize %}
</p>
<a href="{% url 'post' with slug=post.slug %}">read more</a>

This would produce output such as the following:

<h2>Moya a Huge Success</h2>
<p class="summary">
Yesterday, Moya became the most successful web development platform of all time,
having made PHP obselete [&hellips;]
</p>
<a href="/blog/post/moya-huge-sucess/">read more</a>

{% trans %}

{% trans [number <number>] [comment <comment text>] [context] %}

Marks a block of text as translatable. The text within the trans block can be extracted with the moya extract command. If translation catalogs exist then the text will be replaced with the text for the given language.

Here's a simple template with translatable text:

<p>{% trans comment 'greeting' %}Hello{% endtrans %}</p>

If the translation catalogs exist, then 'Hello' will be replaced with 'Bonjour' or 'Hola' depending on the current locale.

{% url %}

{% url <url name> [with <url parameters>] [from <application or library>] [query <dict for query string>] [base <base url>] %}

Generate a named url from the project. The url name should be the name parameter in the <url> tag. If the url route contains any parameters, they should be supplied in the with clause. For example, let's say we have a url in our project defined like this:

<url route="/post/{year}/{month}/{day}/" view="view.post" />

If we want to link to a post in a template, we shouldn't hard-code the URL as the link would break if we mount the library in a different location. It's far better to use the {% url %} tag which will always generate a valid URL in the project. Here's how we would use it to generate a link to a particular post:

<a href="{% url 'post' with year=2014, month=7, day=5 %}">Birthday</a>

By default the url tag generates URLs from the current application (where the template is being rendered from). If the URL is not in the current application, you can specify it with the from clause. Here's an example:

<a href="{% url 'post' with year=2014, month=7, day=5 from 'blog' %}">Birthday</a>

The query clause should be a dict, and will be used to generate a query string if present. Here's how we can add a query string to the previous example:

<a href="{% url 'post' with year=2014, month=7, day=5 from 'blog' query view='list' %}">Birthday</a>

The url tag will generate a URL without a domain and scheme, which is fine if you are linking from within the same site. If you would like to create a fully qualified URL, you can supply the domain and scheme with the base clause. Here is an example:

<a href="{% url 'post' with year=2014, month=7, day=5 from 'blog' query view='list' base 'http://myblog.org' %}">Birthday</a>

{% urlencode %}

{% urlencode <dict data> %}

URL encodes a dict or mapping expression. For use in query strings. here's an example:

{% urlencode foo='bar', 'baz'='egg' %}

This will produce the following output:

foo=bar&baz=egg

{% verbatim %}

{% verbatim %}{% endverbatim %}

Suspends all processing of template tags inside the block. Useful for writing about template tags, without Moya attempting to render them. Here's an example:

{% verbatim %}
<p>{% will not be interpreted as a template tag %}</p>
{% endverbatim %}

{% with %}

{% with <template data> %}

Creates a temporary scope for template data. The code within the block will have access to the template data in addition to existing template data. Here's an example:

{% with character='Rygel' %}
    <p>${character} is my favorite character!</p>
{% endwith %}

Note that template data inside a {% with %} tag shadows data that already exists. In the above example, if a value called character already exists in the template context, it will have its original value restored when the with tag ends.