Moya's template language is a spiritual successor to Django, and Jinja templates. It borrows a number of constructs from both, and adds a few of its own.

There is a slight difference in the syntax in that variables are substituted with ${variable} rather than {{ variable }}, but tags still use the familiar {% tag %} syntax.

Template languages are generally quite extensible, so there is probably nothing that Moya templates can do that Django / Jinja can't (via a plugin or extension), but there are a few things which are I think are more elegant in Moya's templates language (and built-in). I'm going to talk about a few of them in this post.

The Attrib Tag

How often have you written code like this?

<div id="{{ article_id }}"
    class="{% if type %}{{ type }}{% endif %}{% if active %} active{% endif %}{% if highlight %} highlight{% endif %}">
    {{ content }}

This code renders a div with an id attribute and a few optional classes. It is easy to follow, but verbose. It's also a little error prone to write; we have to be careful about the whitespace between the classes, or we could end up generating the nonsense class activehighlight.

Moya offers the the {% attrib %} template tag which is a shortcut to generate a sequence of attributes. Here is the equivalent Moya code using {% attrib %}:

<div {% attrib (id=article_id, class=[type, active and 'active', highlight and 'highlight']) %}>

The attrib tag takes a dictionary and generates attributes based the keys and values. If the value is a list, Moya joins strings with a space, and ignores any value that evaluates to false. It will also omit any attributes that would evaluate to an empty string (compared to the original which could potentially render a superfluous class="").

The attrib tag is also faster, since there is less template logic to run.

The Markup Tag

It is not uncommon to have to write copy in templates. But writing copy in HTML is a pain, and somewhat error prone. You can easily break the entire page with a typo.

Moya has a {% markup-block %} tag which renders the enclosed text in the markup of your choice, so you can embed markdown (for example) directly in to your template. Here's an example:

{% markup-block as 'markdown' %}
# Our Coffees
All our coffees are *organically produced* and from [sustainable sources](/where-we-get-our-coffee/) only. 
{% end-markup-block %}

This produces the following markup:

<h1>Our Coffees</h1>
<p>All our coffees are <em>organically produced</em> and from <a href="/where-we-get-our-cofee/">sustainable sources</a> only.</p>

Another way of rendering markups is with the {% markup %} tag which renders a template variable rather than enclosed text. This is more suitable for rendering content stored in the database. Here's an example:

{% markup post.content as 'markdown' %}

This will render the string content in an object called post as markdown.

The Sanitize Tag

Web developers will no-doubt be familiar with the dangers of rendering untrusted markup (i.e. from comments). Since Moya has a batteries included attitude to templates, there is a built-in tag for this.

The {% sanitize %} tag escapes any potentially dangerous markup based on a set of rules. The defaults are quite conservative and only permit basic formatting markup. Here's an example:

{% sanitize %}
My <b>exploit</b>!
<script>alert('how annoying')</script>
{% end-sanitize %}

This generates the following markup:

My <b>exploit</b>!
&lt;script&gt;alert(&#39;how annoying&#39;)&lt;/script&gt;

The script tag has been escaped, so it will display as text (you can also opt to remove untrusted markup entirely).

This tag uses the excellent bleach library to do the sanitizing.

More Information

To read more about the Moya template languages, see the docs. The docs are currently in a catch-up faze after 3 months of development, so are missing a few recently added template tags. Feel free to ask me about those, but I will be writing them up in the coming weeks.

Use Markdown for formatting
*Italic* **Bold** `inline code` Links to [Google]( > This is a quote > ```python import this ```
your comment will be previewed here
Ian Price

Very cool! Looking forward to checking this out!