1The i18n Extension
2==================
3
4Configuration
5-------------
6
7The ``i18n`` extension adds `gettext`_ support to Twig. It defines one tag,
8``trans``.
9
10To use it, first, :ref:`install the Extensions library<extensions-install>`.
11
12You need to register this extension before using the ``trans`` block::
13
14    $twig->addExtension(new Twig_Extensions_Extension_I18n());
15
16Note that you must configure the ``gettext`` extension before rendering any
17internationalized template. Here is a simple configuration example from the
18PHP `documentation`_::
19
20    // Set language to French
21    putenv('LC_ALL=fr_FR');
22    setlocale(LC_ALL, 'fr_FR');
23
24    // Specify the location of the translation tables
25    bindtextdomain('myAppPhp', 'includes/locale');
26    bind_textdomain_codeset('myAppPhp', 'UTF-8');
27
28    // Choose domain
29    textdomain('myAppPhp');
30
31.. caution::
32
33    The ``i18n`` extension only works if the PHP `gettext`_ extension is
34    enabled.
35
36Usage
37-----
38
39Use the ``trans`` block to mark parts in the template as translatable:
40
41.. code-block:: jinja
42
43    {% trans "Hello World!" %}
44
45    {% trans string_var %}
46
47    {% trans %}
48        Hello World!
49    {% endtrans %}
50
51In a translatable string, you can embed variables:
52
53.. code-block:: jinja
54
55    {% trans %}
56        Hello {{ name }}!
57    {% endtrans %}
58
59During the gettext lookup these placeholders are converted. ``{{ name }}`` becomes ``%name%`` so the gettext ``msgid`` for this string would be ``Hello %name%!``.
60
61.. note::
62
63    ``{% trans "Hello {{ name }}!" %}`` is not a valid statement.
64
65If you need to apply filters to the variables, you first need to assign the
66result to a variable:
67
68.. code-block:: jinja
69
70    {% set name = name|capitalize %}
71
72    {% trans %}
73        Hello {{ name }}!
74    {% endtrans %}
75
76To pluralize a translatable string, use the ``plural`` block:
77
78.. code-block:: jinja
79
80    {% trans %}
81        Hey {{ name }}, I have one apple.
82    {% plural apple_count %}
83        Hey {{ name }}, I have {{ count }} apples.
84    {% endtrans %}
85
86The ``plural`` tag should provide the ``count`` used to select the right
87string. Within the translatable string, the special ``count`` variable always
88contain the count value (here the value of ``apple_count``).
89
90To add notes for translators, use the ``notes`` block:
91
92.. code-block:: jinja
93
94    {% trans %}
95        Hey {{ name }}, I have one apple.
96    {% plural apple_count %}
97        Hey {{ name }}, I have {{ count }} apples.
98    {% notes %}
99        This is shown in the user menu. This string should be shorter than 30 chars
100    {% endtrans %}
101
102You can use ``notes`` with or without ``plural``. Once you get your templates compiled you should
103configure the ``gettext`` parser to get something like this: ``xgettext --add-comments=notes``
104
105Within an expression or in a tag, you can use the ``trans`` filter to translate
106simple strings or variables:
107
108.. code-block:: jinja
109
110    {{ var|default(default_value|trans) }}
111
112Complex Translations within an Expression or Tag
113------------------------------------------------
114
115Translations can be done with both the ``trans`` tag and the ``trans`` filter.
116The filter is less powerful as it only works for simple variables or strings.
117For more complex scenario, like pluralization, you can use a two-step
118strategy:
119
120.. code-block:: jinja
121
122    {# assign the translation to a temporary variable #}
123    {% set default_value %}
124        {% trans %}
125          Hey {{ name }}, I have one apple.
126        {% plural apple_count %}
127          Hey {{ name }}, I have {{ count }} apples.
128        {% endtrans %}
129    {% endset %}
130
131    {# use the temporary variable within an expression #}
132    {{ var|default(default_value|trans) }}
133
134Extracting Template Strings
135---------------------------
136
137If you use the Twig I18n extension, you will probably need to extract the
138template strings at some point.
139
140Using Poedit 2
141~~~~~~~~~~~~~~
142
143Poedit 2 has native support for extracting from Twig files and no extra
144setup is necessary (Pro version).
145
146Using ``xgettext`` or Poedit 1
147~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
148
149Unfortunately, the ``xgettext`` utility does not understand Twig templates
150natively and neither do tools based on it such as free versions of Poedit.
151But there is a simple workaround: as Twig converts templates to
152PHP files, you can use ``xgettext`` on the template cache instead.
153
154Create a script that forces the generation of the cache for all your
155templates. Here is a simple example to get you started::
156
157    $tplDir = dirname(__FILE__).'/templates';
158    $tmpDir = '/tmp/cache/';
159    $loader = new Twig_Loader_Filesystem($tplDir);
160
161    // force auto-reload to always have the latest version of the template
162    $twig = new Twig_Environment($loader, array(
163        'cache' => $tmpDir,
164        'auto_reload' => true
165    ));
166    $twig->addExtension(new Twig_Extensions_Extension_I18n());
167    // configure Twig the way you want
168
169    // iterate over all your templates
170    foreach (new RecursiveIteratorIterator(new RecursiveDirectoryIterator($tplDir), RecursiveIteratorIterator::LEAVES_ONLY) as $file)
171    {
172        // force compilation
173        if ($file->isFile()) {
174            $twig->loadTemplate(str_replace($tplDir.'/', '', $file));
175        }
176    }
177
178Use the standard ``xgettext`` utility as you would have done with plain PHP
179code:
180
181.. code-block:: text
182
183    xgettext --default-domain=messages -p ./locale --from-code=UTF-8 -n --omit-header -L PHP /tmp/cache/*.php
184
185Another workaround is to use `Twig Gettext Extractor`_ and extract the template
186strings right from `Poedit`_.
187
188.. _`gettext`:                http://www.php.net/gettext
189.. _`documentation`:          http://fr.php.net/manual/en/function.gettext.php
190.. _`Twig Gettext Extractor`: https://github.com/umpirsky/Twig-Gettext-Extractor
191.. _`Poedit`:                 http://www.poedit.net/
192