Overview
Writing in Markdown is great, but sometimes you run into limitations. For those cases, Urubu supports a feature gratefully borrowed from Jekyll: using templating constructs in content pages.
Basically, all content pages are processed by the templating engine before going to the Markdown processor. The full power of Jinja2 is thus available in your content pages.
The usage of templating constructs in content pages is best explained with examples. Therefore, we will start with some examples, and review the concepts afterwards.
Example usage
Task list icons
Suppose you want to emulate GitHub style task lists, as follows:
- Task 1
- Task 2
- Task 1
An icon is used to show whether a task is still open or not.
We can support this by defining well-named reusable variables in a dedicated template file, as follows:
{% set open = '<i class="fa fa-square-o"></i>' %}
{% set done = '<i class="fa fa-check-square-o"></i>' %}
Variables open
and done
now hold HTML code that refers to icons. In these
examples, I use the Font Awesome icon library. You will need to add the
appropriate reference to the icon stylesheet in your base template.
Suppose these variables are defined in the file _layouts/util.html
. We can
import them in any content page as follows:
{% from 'util.html' import open, done %}
Note that Urubu knows to look up util.html
in the _layouts/
directory,
because that is where templates should be located.
Within the content page, we can use the variables as follows, to get the result as above:
* {{ open }} Task 1
* {{ done }} Task 2
* {{ open }} Task 1
General icon interface
Suppose you want a more general interface to icons, so that you can easily refer to any icon by name. This can be done with a Jinja2 macro. A macro is like a function that can take parameters:
{% macro fa(name, class='') %}
<i class="fa fa-{{name}} {{class}}"></i>
{% endmacro %}
Again, we can import the macro fa
in content pages:
{% from 'util.html' import fa %}
Then we can use it as follows, for example to refer to the Github icon:
{{ fa('github') }}
This gives the following result:
We can pass additional CSS classes via the optional class
parameter. The
following example gets the alternative Github icon in twice the basic size:
{{ fa('github-alt', 'fa-2x') }}
This gives the following result:
Figure
Standard Markdown does not support the HTML5 <figure>
tag, and the related
<figcaption>
tag to add captions. We can support this with the following
macro:
{% macro figure(fn, caption='') %}
<figure>
<img src="/img/{{fn}}" class="img-responsive" alt="{{caption}}">
{% if caption %}
<figcaption class="text-center">{{caption}}</figcaption>
{% endif %}
</figure>
{% endmacro %}
This macro assumes that images will be placed in an img/
directory. In
addition, it makes the image responsive using a Bootstrap class, and centers
the optional caption. Again, we can use the macro by importing:
{% from 'util.html' import figure %}
This is an example usage:
{{ figure('urubu.jpg', "An Urubu - a brazilian vulture") }}
This gives the following result:
Templating concepts
Template processing is done first
The examples illustrate how you can use template variables and macros to construct HTML code. However, it is important to understand that template processing is done first, before Markdown processing (for good reasons). Thus, the HTML code from variables and macros first becomes part of Markdown source code. This works well because Markdown is designed to handle HTML transparently.
Full template power available
The examples demonstrate the use of variables, macros, and imports. This is merely the beginning: in fact, the full power of Jinja2 templates is available. This is a vast subject. To learn what is possible, see the Jinja2 Template Designer Documentation.
Context variables
When Urubu invokes template processing on a page, it automatically passes
certain context variables. This works exactly like for regular templates, as
described in Context Variables. Basically, variable this
provides access to the page attributes, and variable site
provides access to
the global site attributes.
Template delimiters
Template support introduces new delimiters as follows:
{# ... #}
for comments not included in the output{{ ... }}
for expressions, to print to the output{% ... %}
for statements
These delimiters deserve some attention.
First, the comment delimiters are interesting because they add a functionality that is not available in Markdown: comments that will not show up in the output.
Secondly, as always with delimiters, there is the problem of how to escape them if you want to use them literally in source code, without interpretation.
For an inline literal or snippet you can use literal expressions. For example,
to get {{
you can write {{ '{{' }}
.
For a larger section, you can mark a block raw. For example, to get the list shown earlier in this section, you can write:
{% raw %}
* `{# ... #}` for comments not included in the output
* `{{ ... }}` for expressions, to print to the output
* `{% ... %}` for statements
{% endraw %}