An open API service indexing awesome lists of open source software.

https://github.com/phpmyadmin/twig-i18n-extension

The phpMyAdmin project's fork of the Twig i18n extension
https://github.com/phpmyadmin/twig-i18n-extension

Last synced: 12 months ago
JSON representation

The phpMyAdmin project's fork of the Twig i18n extension

Awesome Lists containing this project

README

          

Twig i18n Extension
===================

The ``i18n`` extension adds `gettext`_ support to Twig. It defines one tag,
``trans``.

Code status
-----------

.. image:: https://github.com/phpmyadmin/twig-i18n-extension/actions/workflows/tests.yml/badge.svg?branch=master
:alt: Tests
:target: https://github.com/phpmyadmin/twig-i18n-extension/actions/workflows/tests.yml?query=branch%3Amaster

.. image:: https://codecov.io/gh/phpmyadmin/twig-i18n-extension/branch/master/graph/badge.svg
:alt: Code coverage
:target: https://codecov.io/gh/phpmyadmin/twig-i18n-extension

Installation
------------

This library can be installed via Composer running the following from the
command line:

.. code-block:: bash

composer require phpmyadmin/twig-i18n-extension

Configuration
-------------

You need to register this extension before using the ``trans`` block

.. code-block:: php

use PhpMyAdmin\Twig\Extensions\I18nExtension;

$twig->addExtension(new I18nExtension());

Note that you must configure the ``gettext`` extension before rendering any
internationalized template. Here is a simple configuration example from the
PHP `documentation`_

.. code-block:: php

// Set language to French
putenv('LC_ALL=fr_FR');
setlocale(LC_ALL, 'fr_FR');

// Specify the location of the translation tables
bindtextdomain('myAppPhp', 'includes/locale');
bind_textdomain_codeset('myAppPhp', 'UTF-8');

// Choose domain
textdomain('myAppPhp');

.. caution::

The ``i18n`` extension only works if the PHP `gettext`_ extension is
enabled.

Usage
-----

Use the ``trans`` block to mark parts in the template as translatable:

.. code-block:: twig

{% trans "Hello World!" %}

{% trans string_var %}

{% trans %}
Hello World!
{% endtrans %}

In a translatable string, you can embed variables:

.. code-block:: twig

{% trans %}
Hello {{ name }}!
{% endtrans %}

During the gettext lookup these placeholders are converted. ``{{ name }}`` becomes ``%name%`` so the gettext ``msgid`` for this string would be ``Hello %name%!``.

.. note::

``{% trans "Hello {{ name }}!" %}`` is not a valid statement.

If you need to apply filters to the variables, you first need to assign the
result to a variable:

.. code-block:: twig

{% set name = name|capitalize %}

{% trans %}
Hello {{ name }}!
{% endtrans %}

To pluralize a translatable string, use the ``plural`` block:

.. code-block:: twig

{% trans %}
Hey {{ name }}, I have one apple.
{% plural apple_count %}
Hey {{ name }}, I have {{ count }} apples.
{% endtrans %}

The ``plural`` tag should provide the ``count`` used to select the right
string. Within the translatable string, the special ``count`` variable always
contain the count value (here the value of ``apple_count``).

To add notes for translators, use the ``notes`` block:

.. code-block:: twig

{% trans %}
Hey {{ name }}, I have one apple.
{% plural apple_count %}
Hey {{ name }}, I have {{ count }} apples.
{% notes %}
This is shown in the user menu. This string should be shorter than 30 chars
{% endtrans %}

You can use ``notes`` with or without ``plural``. Once you get your templates compiled you should
configure the ``gettext`` parser to get something like this: ``xgettext --add-comments=notes``

Within an expression or in a tag, you can use the ``trans`` filter to translate
simple strings or variables:

.. code-block:: twig

{{ var|default(default_value|trans) }}

Complex Translations within an Expression or Tag
------------------------------------------------

Translations can be done with both the ``trans`` tag and the ``trans`` filter.
The filter is less powerful as it only works for simple variables or strings.
For more complex scenario, like pluralization, you can use a two-step
strategy:

.. code-block:: twig

{# assign the translation to a temporary variable #}
{% set default_value %}
{% trans %}
Hey {{ name }}, I have one apple.
{% plural apple_count %}
Hey {{ name }}, I have {{ count }} apples.
{% endtrans %}
{% endset %}

{# use the temporary variable within an expression #}
{{ var|default(default_value|trans) }}

Extracting Template Strings
---------------------------

If you use the Twig I18n extension, you will probably need to extract the
template strings at some point.

Using Poedit 2
~~~~~~~~~~~~~~

Poedit 2 has native support for extracting from Twig files and no extra
setup is necessary (Pro version).

Using ``xgettext`` or Poedit 1
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Unfortunately, the ``xgettext`` utility does not understand Twig templates
natively and neither do tools based on it such as free versions of Poedit.
But there is a simple workaround: as Twig converts templates to
PHP files, you can use ``xgettext`` on the template cache instead.

Create a script that forces the generation of the cache for all your
templates. Here is a simple example to get you started

.. code-block:: php

use Twig\Environment;
use Twig\Loader\FilesystemLoader;
use PhpMyAdmin\Twig\Extensions\I18nExtension;

$tplDir = __DIR__ . '/templates';
$tmpDir = '/tmp/cache/';
$loader = new FilesystemLoader($tplDir);

// force auto-reload to always have the latest version of the template
$twig = new Environment($loader, [
'auto_reload' => true,
'cache' => $tmpDir,
]);
$twig->addExtension(new I18nExtension());
// configure Twig the way you want

// iterate over all your templates
foreach (new RecursiveIteratorIterator(new RecursiveDirectoryIterator($tplDir), RecursiveIteratorIterator::LEAVES_ONLY) as $file)
{
// force compilation
if ($file->isFile()) {
$twig->loadTemplate(str_replace($tplDir . '/', '', $file));
}
}

Use the standard ``xgettext`` utility as you would have done with plain PHP
code:

.. code-block:: text

xgettext --default-domain=messages -p ./locale --from-code=UTF-8 -n --omit-header -L PHP /tmp/cache/*.php

Another workaround is to use `Twig Gettext Extractor`_ and extract the template
strings right from `Poedit`_.

.. _`gettext`: https://www.php.net/gettext
.. _`documentation`: https://www.php.net/manual/en/function.gettext.php
.. _`Twig Gettext Extractor`: https://github.com/umpirsky/Twig-Gettext-Extractor#readme
.. _`Poedit`: https://poedit.net/

History
-------

This project was forked in 2019 by the phpMyAdmin team, since it was abandoned by the
`Twig project`_ but was still in use for phpMyAdmin.

.. _`Twig project`: https://github.com/twigphp/Twig-extensions

If you find this work useful, or have a pull request to contribute, please find us on
`Github`_.

.. _`Github`: https://github.com/phpmyadmin/twig-i18n-extension/