Templating

davidmoreno edited this page May 16, 2011 · 3 revisions

libonion sports a templating system based on Django's. It is called otemplate.

Currently is a work in progress. Changes may appear whithout previous notice, but they will be always to make it easier to use and more powerfull, making it closer to Django's.

Check at http://docs.djangoproject.com/en/dev/ref/templates/api/ for more information on syntax.

Django templates were chosen as they are quite flexible, do not set important limitations, and as way to appeal to Django developers. There is no need to reinvent the wheel here.

How to use it

  1. Create your template
  2. Compile it with otemplate into a C file.
  3. Compile this C file into your program.
  4. Call you renderer where needed, for example with filename_template(onion_dict *context, onion_request *req);

Basic syntax

There are two kinds of tags allowed: {{variables}} and {% templatetags %}. Variables are dict data straight from the context dict as passed. Template tags are builtin template tags or plugin loaded at template compile.

Variables

Variables can be navigated through the context using dots. For example {{session.username}} will search for key username on dict session. It can be nested as necessary, and if no data is found it will just print nothing.

Missing from Django templates are filters, but they are discarded by the moment as there is no dynamic data generation on dictionaries (yet), so the data can be set by the application as it will be really printed. If you need this functionality, add a bug report.

Template tags

Template tags are code instructions for the template. They may be a conditional branch ({% if %}), a loop, a translation.. or just anything. Built in template tags are:

  • if .. else .. endif The first gets an expression (simple ones by the moment), and if true goes on with the first part, if not with the second. This second part is optional.
  • for .. endfor Loops over the values of a given dictionary. If its not a dictionary its does nothing. This is different from pythons, but by the moment onion dictionaries only can have or strings or dictionaries. Access to values instead of key is preffered as normally the value is more valuable. This may change in the short future.
  • load Loads an external plugin to add more template tags
  • extends, block and endblock. With these you can create a template for a site, and set some block that will be changed later. Check https://github.com/davidmoreno/onion/tree/master/tests/07-otemplate for an exmaple (extended.html and base.html).

Included is the i18n template tag library, that adds the trans template tag: prints the quoted text using gettext, so its easily translatable.

Full example

template.html

{% load i18n %}
<html>
 <head><title>{{title}}</title></head>
 <body>
  <ul>
   <li>{% trans "Name" %} {{user.name}}</li>
   <li>{% trans "Year of birth" %} {{user.birth.year}}</li>
  </ul>
 </body>
</html>

server.c

int data(void *, onion_request *req){
  onion_dict *d=onion_dict_new();
  onion_dict *birth=onion_dict_new();
  onion_dict *user=onion_dict_new();

  onion_dict_add(birth, "year","1980",0);

  onion_dict_add(user, "birth", birth, OD_DICT|OD_FREE_VALUE);
  onion_dict_add(user, "name","David Moreno");

  onion_dict_add(d, "user", user, OD_DICT|OD_FREE_VALUE);
  onion_dict_add(d, "title","My title",0);

  return template_html(d, req);
}

Compile

otemplate template.html template_html.c

See also

Check https://github.com/davidmoreno/onion/tree/master/examples/fileserver_otemplate for a full working example.