Important
In iocaine 1.x, the templates used handlebars syntax, but iocaine 2.0 uses Jinja2, migration is necessary.
iocaine uses minijinja for templating, a template language largely compatible with Jinja2, and will look for a template named main.jinja in the configured template directory, or, if no directory is configured, it will fall back to the default template.
Available variables
Each time a page is rendered, iocaine makes data in the following variables available:
{
"static_seed": "...",
"content_type": "text/html",
"request_host": "example.com",
"request_uri": "some-path/",
"params": {
"q": "some-value"
}
}
It is possible to change any of these with {% set %}, but that only really makes sense for content_type and static_seed.
Changing content_type changes the Content-Type header returned for the request by iocaine. While it is possible to set any content type, the templating system requires all output to render into an UTF-8 string, so you’re limited to text-based formats. That still allows rendering SVGs, Atom or RSS feeds, sitemaps, CSS stylesheets, JavaScript stuff, and those kind of things.
Changing static_seed changes the random number generator, but only if it is set before calling any other custom function. It is recommended not to change it, unless you are absolutely sure you know what you are doing. It can be used to set the seed to that of a different page, like that of the containing directory of an SVG image.
Custom functions
To do its job properly, iocaine relies on the template to drive how garbage is generated, and how much of it. To facilitate that, a number of custom functions are provided. These aren’t context-aware, so may end up generating text that is invalid in certain contexts: quotation marks when generating links, HTML elements whene generating garbage. It is recommended to escape them using the engine-provided escape and urlencode filters (the latter is available since iocaine 2.5.0), as appropriate.
rand(max=N, min=1, pos=<automatic>, group="default")Generates a random number between
minandmax, seeded byposandgroup. Only themaxnamed argument is required, the rest have sensible defaults. If one wants to generate the same random number as elsewhere, use the same parameters, includingposandgroup.Every time
rand()is called without explicitly giving it aposargument, the automatically tracked variable gets incremented. This guarantees that any calls torand()that weren’t explicitly set up to give the same answer as another one, will choose a random answer.All other functions that need random numbers use this framework, and work in exactly the same way.
Examples:
{{ rand(max=15) }} == {{ rand(min=1, max=15, pos=0, group="default") }} {{ rand(max=15) }} is not guaranteed to be the same as {{ rand(max=15, pos=0) }}! Generate 1-5 paragraphs of markov-based garbage: {% for p in range(rand(max=5, group="paragraphs")) %} <p>{{ markov(min=10, max=128) }}</p> {% endfor %}markov_gen(max=N, min=1, words=None, pos=<automatic>, group="markov")Generates either
wordsnumber of words of garbage (if awordsargument was given), or a random number of words betweenminandmax. Only themaxargument is mandatory, the rest have sensible defaults.Examples:
{{ markov_gen(min=10, max=128) | escape }} generates 10-128 words of garbage. {{ markov_gen(words=4) | escape }} always generates 4 words of garbage. {{ markov_gen(max=128, pos=42, group="title") | escape }} - This will always generate the same garbage.href_gen(max=N, min=1, words=None, pos=<automatic>, group="href")Generates a string suitable to be included in a
href, made up of eitherwordsnumber of words, or a random number betweenminandmax. The words are joined together by a dash (-). Only themaxargument is mandatory, the rest have sensible defaults.Examples:
<ul> {% for l in range(rand(max=5, group="links")) %} <li> <a href="{{ href_gen(max=2) | urlencode }}"> {{ markov_gen(min=2, max=7, group="href") | escape }} </a> </li> {% endfor %} </ul>regex_gen(PATTERN, max=N, min=1, pos=<automatic>, group="regex")Generates a string that matches the regexp pattern given in
PATTERN.Ncontrols the maximum number of repeats in patterns likex*,x+, orx{n,}. BothPATTERNand themaxargument are mandatory.This function can be used to generate URL structures that match a pattern, or “secrets”, or a whole lot of other things the author of this documentation has not thought of.
Examples:
{% set username = regex_gen("[-\\.a-zA-Z0-9]{3,32}", max=32) %} <a href="/@{{ username | urlencode }}/">@{{ username | escape }}</a>If you need to use a backslash-escape in the regexp, that will need to be doubly-escaped, as shown above.
qr(CONTENT, format="png", width=<automatic>, height=<automatic>)Generates a QR code of
CONTENT, in a givenformatandwidthxheightdimensions. If specifying dimensions, both of them must be specified, otherwise they will be silently ignored. The supportedformats are:png,svg, andsvg:raw. The first two generates a base64-encodeddata:url that can be directly used by an<img>tag, the latter,svg:rawoutputs the generated SVG as-is, and can be included directly in the template, as-is.Examples:
<img src="{{ qr(markov_gen(max=7, group="qr")) }}" alt="{{ markov_gen(min=3, max=15, group="qr") | escape }}">parse_file(PATH[, format="<json|yaml>"])Parse the given
PATHas eitherjsonoryaml, and return the parsed structure. Intended to be used together with{% set %}, to load data from a separate file.Examples:
{% set secrets = parse_file("secret-rules.yaml", format = "yaml") %} {%- with rule = secrets["github-pat"], name = regex_gen(rule.name_regex, max=256)|upper|replace("-", "_"), value = regex_gen(rule.secret_regex, max=256) -%} {{ name }}="{{ value }}" {%- endwith -%}Added in iocaine 2.1.0.
Custom filters
Apart from the functions described above, iocaine also introduces the following filters for the templates:
STRING | matches(REGEXP)Allows matching a string against a regexp, which can be useful to drive the template to produce more realistic content, based on the
request_uri, for example.Examples:
{% if request_uri|matches("^/blog/") %} {% include "blog.jinja" %} {% endif %}STRING | sanitize_filename(replacement="")Sanitizes an input string to become a filename that is safe to include. This is meant to make it possible to provide per-host templates:
{% include ("hosts/" ~ request_host|sanitize_filename ~ ".jinja") ignore missing %}