Language localization plugin


1Presentation

This plugin allows two things:

  • Manage URLs that are prefixed by language. The plugin will therefore automatically redirect the user to the requested page with /en/ (for example) at the beginning of the URL.
  • Automatically load the translations corresponding to the language used, to make the translated strings available to the templates.

2Configuration

In the etc/temma.php file, add the pre-plugin and configure it:

[
    // loading the plugin
    'plugins' => [
        '_pre' => [
            '\Temma\Plugin\\Language'
        ]
    ],
    // plugin configuration
    'x-language' => [
        // list of languages supported by the site
        'supported' => [ 'fr', 'en', 'de' ],
        // default language, if the browser is not compatible with
        // any of the languages listed above
        'default' => 'fr',
        // (optional) you can indicate not to use
        // template prefixes (see below)
        'templatePrefix' => false,
        // (optionnel) you can indicate the URLs for which
        // language management is not activated
        'protectedUrls' => [
            '/robots.txt',
            '/sitemap.xml',
        ]
    ],
    // configuration of the Smarty view
    'x-smarty-view' => [
        'pluginsDir' => '/path/to/project/lib/smarty-plugins'
    ]
]
  • Lines 3 to 7: Plugins configuration.
    • Line 5: Activation of the pre-plugin that supports language management.
  • Lines 9 to 24: Plugin configuration.
    • Line 11: List of languages supported on the site.
    • Line 14: Definition of the default language (used if the browser is not compatible with any of the languages listed.
    • Lines 20 to 23: Definition of the list of URLs for which language management is disabled.
  • Lines 26 to 28: Configuration of the Smarty view.
    • Line 27: Addition of the directory containing the Smarty plugins provided by Temma, so that the Smarty interpreter is able to find the extension (see below).

3Operation

In the example of the configuration above, we indicate that the site has translations in French, English and German.

When a browser requests a page, two cases can occur:

  • The requested URL does not start with /fr/, /en/ nor /de/. In this case, the plugin will redirect the user to the requested URL, adding the language prefix. The language chosen will be the first one supported by the browser which is also supported by the site (if none is suitable, the default language of the site will be used).
  • The requested URL begins with a language prefix. In this case, the plugin will check that the requested language is well supported by the site (if this is not the case, we are back in the previous case). If the language is well supported, the plugin will extract the language, and modify all the information relating to the controller, the action and the parameters, to pretend that this prefix did not exist in the URL. Beside that, the plugin loads the corresponding translation file, and adds a prefix to the path leading to the template files.

For example, if the user requests page /page/list/date/5, with a browser that supports French, the plugin will redirect her to /fr/page/list/date/5.

When arriving on /fr/page/list/date/5, the plugin will extract the language (fr), will load the translation file in French. Then it will modify several things:

  • The requested controller becomes page (and no longer fr).
  • The requested action becomes list (and no longer page).
  • The list of parameters becomes ['date', '5'] (and no longer ['list', 'date', '5']).

The template variables $CONTROLLER, $ACTION and $URL are also modified accordingly.


4Management of query methods

If the requested URL begins with language information (and this language is authorized by the configuration), the processing explained above will always be carried out.

On the other hand, if the language information is absent, the redirection (to the same URL to which the language prefix is added) is not carried out if the request had a POST or PUT method. In this case, the plugin does nothing and the processing continues normally.


5Protected URLs

It is possible to define a list of URLs which will not be managed by the language plugin. This is useful if, for example, you have controllers that automatically generate the content of robots.txt or sitemap.xml files.

Please note that URLs must begin with the '/' character.


6Prefix to templates path

Unless the templatePrefix configuration variable has been set to false, the plugin will modify the path leading to the template files, prepending a directory corresponding to the requested language.

Thus, if the URL is /fr/article/list, the template used will be (by default) the file templates/fr/article/list.tpl

If the controller uses another file, the prefix will be added anyway.
For example, if the controller contains the following line:

$this->_template('cms/content/article_list.tpl');

Temma will use the file templates/fr/cms/content/article_list.tpl


7Translation files

The plugin loads files containing the translations. These are files in INI format, placed in the etc/lang/ directory of the project, and named according to the language (fr.ini, en.ini, etc.).

Here is an example of an fr.ini file:

[default]
Controllers="Contrôleurs"
Model="Modèle"
Views="Vues"

[header]
title="Temma : framework PHP simple et performant"
Home="Accueil"
Download="Télécharger"
Community="Communauté"
Examples="Exemples"

[footer]
Designed by="Conception par"

As you can see, the translated strings are sorted by sections (here default, header and footer). These sections correspond to translation domains.

Here again, the basic strings are in English, and each one provides their translation into French.

Important: If you try to translate a string, but it cannot be found in the translation file, it will be used as is.
In the example above, we can see that the base strings are in English, and that a French translation has been provided. It will therefore not be necessary to provide an English translation file.


8Use in templates

In Smarty templates, two additional variables are created by the plugin:

  • $lang: Contains the current language (fr, en, etc.).
  • $l10n: Contains the table of translations. Must not be used.

8.1Language variable

You can use the $lang variable directly in your templates:

{if $lang == 'fr'}
    Bonjour tout le monde
{else}
    Hello everyone
{/if}

Displayed in French, this will look like this:

    Bonjour tout le monde

In English:

    Hello everyone

8.2Modifier

To translate strings, you can use the l10n modifier. It looks for the translation of the string it receives as input, and returns it after escaping any special characters.

<h1>{"Model"|l10n}</h1>
<h1>{"Views"|l10n}</h1>

{"header#Home"|l10n}
{"header#Download"|l10n}

{"zkwx<hyq"|l10n}

Displayed in French:

<h1>Modèle</h1>
<h2>Vues</h2>

Accueil
Télécharger

zkwx&lt;hyq

In English:

<h1>Model</h1>
<h2>Views</h2>

Home
Download

zkwx&lt;hyq
  • Lines 1 and 2: The strings listed in the default section of the translation file can be used directly.
  • Lines 4 and 5: Strings listed in other sections must be prefixed with the section name, followed by the hash character (#).
  • Line 7: If the string is not found in the translation file, it is used as is. The special < character is escaped as &lt;.

8.3Block tag

You can also use the Smarty {l10n} block tag. The default domain is always the one named default. Another domain can be specified using the _domain attribute on the opening tag.

{l10n}Model{/l10n}
{l10n _domain='header'}Home{/l10n}

Displayed in French:

Modèle
Accueil

Unlike modifiers, translation blocks do not escape special characters.


8.4Modifier with parameters

It is possible to provide parameters to the modifier, which will be used to replace portions of text using printf syntax.

If the translation file contains the following definitions:

[default]
Hello %s="Bonjour %s"
%s has %d kids="%d a %s enfants"

Your template may contain:

{"Hello %s"|l10n:'James'}
{"%s has %d kids"|l10n:'Alice':3}

Displayed in French:

Bonjour James
Alice a 3 enfants

8.5Block tag with parameters

As with modifiers, translation blocks can be assigned parameters. These parameters are passed as attributes to the opening {l10n} tag, and used in strings in the form %parameter_name%.

If the translation file contains the following definitions:

[default]
Hello %name%="Bonjour %name%"
%name% has %count% kids="%name% a %count% enfants"

Your template may contain:

{l10n name='Marie'}Hello %name%{/l10n}
{l10n name='Alice' count='3'}%name% has %count% kids{/l10n}

Displayed in French:

Bonjour Marie
Alice a 3 enfants

9Prefix to error files

When this plugin is used, it is necessary to translate the error files defined in the errorPages section of the etc/temma.php file (see the documentation).

The paths defined in the configuration then take a prefix consisting of an error-pages directory, followed by a directory corresponding to the language used.

For example, for the following configuration file:

[
    'errorPages' => [
        '404' => 'error404.html'
    ]
]

If we ask for a page that does not exist in French (for example the URL /fr/sdsjnzeoizoueh), Temma will look for the file www/error-pages/fr/error404.html
If we ask for the same page in English (for example the URL /en/sdsjnzeoizoueh), Temma will look for the file www/error-pages/en/error404.html