Designer Documentation
If you have to design some templates for a application that uses ruty as template engine you are at the right place. This documentation is meant for you :-)
Printing Variables
Variables look like this:
{{ variable }}
When the template engine encounters a variable, it evaluates that variable and replaces it with the result. You can use a dot to access keys, indexes or attributes of a variable:
Get the username of the user:
{{ user.username }}
Get the username of the first user in the userlist
{{ user.0.username }}
Filters
Variables support filters which modify a variable. Filters look like this:
{{ variable|filter1|filter "with", "some", "arguments" }}.
Here a list of default filters:
lower
convert a value to lowercase
upper
convert a value to uppercase
capitalize
capitalizes a string
truncate n=80, ellipsis=’...’
truncates a string to n characters. If the string was truncated the ellipsis is appended.
join char=’‘
joins an array with a given string.
sort
return a sorted version of the value if sorting is supported
reverse
reverses an item if this is supported
first
return the first item of a array
last
return the last item of an array
escape attribute=false
xml-escape a string. If attribute is true it will also escape ” to "
urlencode
urlencodes a string (” ” will be converted to “%20” etc.)
length
return the length of an item with a length, else 0
For Loop
The for loop is useful if you want to iterate over something that supports iteration. For example arrays:
-
{% for item in iterable %}
- {{ item|escape }} {% endfor %}
Inside of a loop you have access to some loop variables:
loop.index The current iteration of the loop (1-indexed)
loop.index0 The current iteration of the loop (0-indexed)
loop.revindex The number of iterations from the end of
the loop (1-indexed)
loop.revindex0 The number of iterations from the end of the
loop (0-indexed)
loop.first true if this is the first time through the loop
loop.last true if this is the last time through the loop
loop.even true if this is an even iteration
loop.odd true if this is an odd iteration
loop.parent For nested loops, this is the loop "above" the
current one
For loops also have an optional else block that is just rendered if the iteration was empty:
{% for user in users %}
...
{% else %}
no users found
{% endfor %}
Important Note: Ruty requires objects to not only provide a valid each method for iteration but also a size or length method that returns the number of items. If size and length isn’t provided ruty fails silently and renders the else block if given. The same happens if you try to iterate over a number or any other object without an each method.
If Conditions
If Conditions are very low featured, they only support boolean checks. But they do boolean checks a clever way, so not the ruby way ^^. For example empty objects are considered false, zero, nil and false too.
Syntax:
{% if item %}
...
{% endif %}
Or:
{% if not item %}
...
{% else %}
...
{% endif %}
There is neither or/and or elsif by now. But that’s something that is on the todo list.
Cycle
Cycle among the given objects each time this tag is encountered. Within a loop, cycles among the given strings each time through the loop:
{% for item in iterable %}
...
{% endfor %}
Capture
Captures the wrapped data and puts it into a variable:
{% capture as title block title endblock endcapture %}
That allows using the data of a block multiple times. Note that the variable is only available in the current and lower scopes. If you use this block to capture something inside a for loop tag for example (or inside of a block) it won’t be available outside of the loop/block.
IfChanged
Check if a value has changed from the last iteration of a loop. If a variable is given as first argument it’s used for testing, otherwise the output of the tag:
{% for day in days %}
{% ifchanged {{ date.hour }}{ endifchanged %}
...
{% endfor %}
Or:
{% for day in days %}
{% ifchanged date.hour %}
...
{% endifchanged %}
{% endfor %}
Giving the tag a variable to check against will speed out the rendering process.
Filter
Applies some filters on the wrapped content:
{% filter upper|escape %}
<some content here & that includes < invalid
html we want to escape convert to uppercase
{% endfilter %}
Debug
This tag outputs a pretty printed represenation of the context passed to the template:
{% debug %}
If you want to use the output in a html document use this to get a readable output:
{% filter escape %}{% debug %}{% endfilter %}
Block / Extends
Now to the template inheritance system. Template inheritance allows you to build a base “skeleton” template that contains all the common elements of your site and defines blocks that child templates can override:
{% block head %}Saved as layout.html it can act as a layout template for the child template (for example called userlist.html):
{% extends 'layout.html' %}
{% block title endblock %}
{% block body %}
{% for user in users %}
- {{ user|escape }}
{% endfor %}
{% endblock %}
As you can see block override each other, because of that block names must be unique! You can render the output of an overridden block by outputting block.super. The name of a block is available as block.name, the depth of the current inheritance as block.depth.
Note that extends must be the first tag of a template. Otherwise the whole process fails with an error message.
Ruty Namespace
Inside the context there is a special key ruty which gives you access to some ruty information:
ruty.block_start the string representing a block start ( {% )
ruty.block_end same for block end ( %} )
ruty.var_start same for variable start ( {{ )
ruty.var_end same for variable end ( }} )
ruty.comment_start same for comments ( {# }
ruty.comment_end end comment ends ( #} )
ruty.version the ruty version as string