Obviel Template i18n


Obviel Template supports an i18n strategy for templates which allows the template developer to mark up those bits of the template that are translatable. This is very similar to the way code (such as JavaScript code) is marked up for i18n as well (typically using the _("string to translate") construct.

We recommend the use of the Babel i18n tool with code that uses Obviel. While was primarily written to support Python applications, it can also support JavaScript applications. We’ve written a special Obviel plugin for Babel which teaches it about Obviel Templates, so that messages ids can be extracted from them.

Basic i18n

We want to allow templates to be multi-lingual. To this end we need to be able to indicate which element content and which attributes are translatable.

We can do this with Obviel Template like this:

<p data-trans="">Hello world!</p>

Where trans is short for translate.

The translatable text is now:

Hello world!

and this is also used as its message id in the generated .po file.

So, an empty data-trans tells the system that the element content is translatable. You can also indicate that an attribute is translatable, by naming it in data-trans:

<a title="A title" data-trans="title"></a>

Multiple attributes can be indicated by separating them with a space:

<a title="A title" description="A description" data-trans="title description"></a>

You can also name both element content as well as attribute at the same time for translation:

<a title="A title" data-trans=". title"></a>

Here we use . to indicate the textual element content.


i18n works with {variable} notations. This:

<p data-trans="">I saw {thing}.</p>

will imply the following message id:

I saw {thing}.

And this could be translated to Dutch like this:

Ik heb {thing} gezien.

The translator simply moves the variable to that part in the text where it makes the most sense in that language.

Variables are also be re-orderable:

I saw {thing}. It was {color}.

could translate to the following Dutch:

{color} was {thing} dat ik gezien heb.

For HTML elements with simple textual content, and for any translatable content that’s in HTML attributes, we’re done with the explanations on how to mark up your template. But complexities occur when we mark up an element that contains not only text, but also HTML.

data-trans may not contain data-if and data-each

data-each and data-if may not be used on elements contained in an element with data-trans on it (when data-trans is used to indicate the content of the element as opposed to attributes).

So, the following template is illegal and will not compile:

<div data-trans=""><p data-if="foo">Blah</p></div>

data-with and data-if may however be on the same element as a data-trans attribute. In this case, they will be applied before the data-trans attribute is applied. So, this is allowed:

<p data-if="foo" data-trans="">Hello world</p>

If we’re just translating attribute content we’re fine as well:

<div title="A title" data-trans="title"><p data-if="foo">Blah</p></div>

For the sake of simplicity of implementation, data-with is also not allowed within a data-trans, though this is a restriction that could be lifted in the future.

We introduce this rule because programmatic manipulation of translatable text results in very hard-to-reason about situations that are not really possible to resolve. If you need specific reasoning on how to generate translatable text, we recommend you do this inside JavaScript in the view definition.

Elements in relation to data-trans

Let’s consider the following (illegal) template:

<div data-trans="">The <em>pink</em> elephant.</div>

Why is this illegal? After all, at first glance, the translatable text could be this:

The pink elephant.

But there is a problem: we have no reliable way of finding out where in the translation the pink will move. The French translation for instance is:

L'éléphant rose.

and we’d expect a translated template to look like this:

<div>L'éléphant <em>rose</em>.</div>

Obviel Template has no way however of knowing that rose is the French for pink, and that it should it be in the em` element.

The general problem will occur with any HTML element contained within an element with data-trans on it.

In these cases, we have to help the system a bit by marking up the em element with a data-tvar:

<div data-trans="">The <em data-tvar="color">pink</em> elephant.</div>

Obviel Template will now try to translate two message ids:

The {color} elephant.



So, data-tvar indicates that an element is to be treated as a variable in the content indicated by data-trans.

Nested data-trans and data-tvar

data-tvar on an element implies that its content is translatable as well; it is therefore very similar in behavior to data-trans. This means a data-tvar may be nested within another data-tvar element. For example:

<div data-trans="">This is a <em data-tvar="something">complicated <a data-tvar="thing" href="">scenario</a></em>.</div>

This results in the following pieces of text marked up for translation:

This is a {something}.

complicated {thing}


data-trans may not normally be used inside a data-trans, except when it is used to mark up attributes:

<p data-trans="">Hello <em title="Hello world!" data-trans="title" data-tvar="who">{who}</em>!</p>

This combination of data-trans within data-trans is illegal however:

<p data-trans="">Hello <em title="Hello world!" data-trans="" data-tvar="who">{who}</em>!</p>

Explicit message ids

In the above examples, the system will infer the message ids in the translation files from the text in the template itself. Because in some cases this can lead to ambiguous message ids, you may sometimes want to be more explicit. You can name message ids by using a special syntax in data-trans:

<p data-trans=":hello_world">Hello world!</p>

In this case, the content of the p element will get the message id hello_world, not Hello world! as would have been the default.

The template above is the equivalent of this:

<p data-trans=".:hello_world">Hello world!</p>

You can also do this for attributes:

<a title="A title" data-trans="title:some_title"></a>

and for titles and content combined:

<a title="A title" data-trans=".:some_content title:some_title">content</a>

data-tvar implies that the content contained in an element is translatable too, so we can give it an explicit message id too:

<p data-trans="">The <em data-tvar="color:elephant_color">pink</em> elephant.</p>

Shortcuts: implied data-tvar

In some cases you may omit data-tvar on sub-elements in a data-trans. This can be done when the name of the data-tvar can be deduced from the variable inside the data-tvar. This template for example:

<div data-trans="">The <em data-tvar="color">{color}</em> elephant.</div>

may also be expressed like this:

<div data-trans="">The <em>{color}</em> elephant.</div>

data-tvar here deduced the variable name from the content of the em element ({color}).

You can also always omit the data-tvar in case of a data-view element:

<p data-trans="">The great <span data-view="foo"></span>.</p>

This will result in a message id like this:

The great {foo}.

Omitting data-tvar not allowed when an element contains something else than just a single variable, such as text or sub-elements. This for instance is illegal as it contains text (*) within the em element:

<div data-trans="">The <em>*{color}*</em> elephant.</div>

In this case, you need to actually mark up the data-tvar:

<div data-trans="">The <em data-tvar="color">*{color}*</em> elephant.</div>

This will result in the following two message ids to translate:

The {color} elephant