Skip to content

Commit

Permalink
Some general fixes/improvements for translation guide
Browse files Browse the repository at this point in the history
  • Loading branch information
wouterj committed May 4, 2019
1 parent 737cc7f commit a6dabc1
Show file tree
Hide file tree
Showing 2 changed files with 132 additions and 121 deletions.
142 changes: 21 additions & 121 deletions translation.rst
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,11 @@ wrapping each with a function capable of translating the text (or "message")
into the language of the user::

// text will *always* print out in English
dump('Hello World');
die();
echo 'Hello World';

// text can be translated into the end-user's language or
// default to English
dump($translator->trans('Hello World'));
die();
echo $translator->trans('Hello World');

.. note::

Expand Down Expand Up @@ -163,15 +161,15 @@ different formats, XLIFF being the recommended format:
// translations/messages.fr.php
return [
'Symfony is great' => 'J\'aime Symfony',
'Symfony is great' => "J'aime Symfony",
];
For information on where these files should be located, see
:ref:`translation-resource-locations`.

Now, if the language of the user's locale is French (e.g. ``fr_FR`` or ``fr_BE``),
the message will be translated into ``J'aime Symfony``. You can also translate
the message inside your :ref:`templates <translation-tags>`.
the message inside your `templates <Translations in Templates>`.

The Translation Process
~~~~~~~~~~~~~~~~~~~~~~~
Expand All @@ -184,7 +182,8 @@ To actually translate the message, Symfony uses the following process:
resources defined for the ``locale`` (e.g. ``fr_FR``). Messages from the
:ref:`fallback locale <translation-fallback>` are also loaded and
added to the catalog if they don't already exist. The end result is a large
"dictionary" of translations.
"dictionary" of translations. This catalog is cached in production, to
minimize performance impact.

* If the message is located in the catalog, the translation is returned. If
not, the translator returns the original message.
Expand Down Expand Up @@ -240,112 +239,14 @@ Translations in Templates
-------------------------

Most of the time, translation occurs in templates. Symfony provides native
support for both Twig and PHP templates.
support for both Twig and PHP templates:

.. _translation-tags:
.. code-block:: html+twig

Twig Templates
~~~~~~~~~~~~~~
<h1>{% trans %}Symfony is great!{% endtrans %}</h1>

Symfony provides specialized Twig tags (``trans`` and ``transchoice``) to
help with message translation of *static blocks of text*:

.. code-block:: twig
{% trans %}Hello %name%{% endtrans %}
{% transchoice count %}
{0} There are no apples|{1} There is one apple|]1,Inf[ There are %count% apples
{% endtranschoice %}
The ``transchoice`` tag automatically gets the ``%count%`` variable from
the current context and passes it to the translator. This mechanism only
works when you use a placeholder following the ``%var%`` pattern.

.. caution::

The ``%var%`` notation of placeholders is required when translating in
Twig templates using the tag.

.. tip::

If you need to use the percent character (``%``) in a string, escape it by
doubling it: ``{% trans %}Percent: %percent%%%{% endtrans %}``

You can also specify the message domain and pass some additional variables:

.. code-block:: twig
{% trans with {'%name%': 'Fabien'} from 'app' %}Hello %name%{% endtrans %}
{% trans with {'%name%': 'Fabien'} from 'app' into 'fr' %}Hello %name%{% endtrans %}
{% transchoice count with {'%name%': 'Fabien'} from 'app' %}
{0} %name%, there are no apples|{1} %name%, there is one apple|]1,Inf[ %name%, there are %count% apples
{% endtranschoice %}
.. _translation-filters:

The ``trans`` and ``transchoice`` filters can be used to translate *variable
texts* and complex expressions:

.. code-block:: twig
{{ message|trans }}
{{ message|transchoice(5) }}
{{ message|trans({'%name%': 'Fabien'}, 'app') }}
{{ message|transchoice(5, {'%name%': 'Fabien'}, 'app') }}
.. tip::

Using the translation tags or filters have the same effect, but with
one subtle difference: automatic output escaping is only applied to
translations using a filter. In other words, if you need to be sure
that your translated message is *not* output escaped, you must apply
the ``raw`` filter after the translation filter:

.. code-block:: html+twig

{# text translated between tags is never escaped #}
{% trans %}
<h3>foo</h3>
{% endtrans %}

{% set message = '<h3>foo</h3>' %}

{# strings and variables translated via a filter are escaped by default #}
{{ message|trans|raw }}
{{ '<h3>bar</h3>'|trans|raw }}
.. tip::

You can set the translation domain for an entire Twig template with a single tag:

.. code-block:: twig
{% trans_default_domain 'app' %}
Note that this only influences the current template, not any "included"
template (in order to avoid side effects).

PHP Templates
~~~~~~~~~~~~~

The translator service is accessible in PHP templates through the
``translator`` helper:

.. code-block:: html+php

<?= $view['translator']->trans('Symfony is great') ?>

<?= $view['translator']->transChoice(
'{0} There are no apples|{1} There is one apple|]1,Inf[ There are %count% apples',
10,
['%count%' => 10]
) ?>
Read :doc:`/translation/templates` for more information about the Twig tags and
filters for translation.

Extracting Translation Contents and Updating Catalogs Automatically
-------------------------------------------------------------------
Expand Down Expand Up @@ -381,11 +282,9 @@ Translation Resource/File Names and Locations

Symfony looks for message files (i.e. translations) in the following default locations:

* the ``translations/`` directory (at the root of the project);

* the ``src/Resources/<bundle name>/translations/`` directory;

* the ``Resources/translations/`` directory inside of any bundle.
#. the ``translations/`` directory (at the root of the project);
#. the ``src/Resources/<bundle name>/translations/`` directory;
#. the ``Resources/translations/`` directory inside of any bundle.

.. deprecated:: 4.2

Expand Down Expand Up @@ -486,6 +385,12 @@ For more options, see :ref:`component-translator-message-catalogs`.
$ php bin/console cache:clear
Handling the User's Locale
--------------------------

Translating happens based on the user's locale. Read :doc:`/translation/locale`
to learn more about how to handle it.

.. _translation-fallback:

Fallback Translation Locales
Expand All @@ -510,12 +415,6 @@ checks translation resources for several locales:
add the missing translation to the log file. For details,
see :ref:`reference-framework-translator-logging`.

Handling the User's Locale
--------------------------

Translating happens based on the user's locale. Read :doc:`/translation/locale`
to learn more about how to handle it.

Translating Database Content
----------------------------

Expand Down Expand Up @@ -555,6 +454,7 @@ Learn more
.. toctree::
:maxdepth: 1

translation/templates
translation/locale
translation/debug
translation/lint
Expand Down
111 changes: 111 additions & 0 deletions translation/templates.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
Using Translation in Templates
==============================

Twig Templates
--------------

.. _translation-tags:

Using Twig Tags
~~~~~~~~~~~~~~~

Symfony provides specialized Twig tags (``trans`` and ``transchoice``) to
help with message translation of *static blocks of text*:

.. code-block:: twig
{% trans %}Hello %name%{% endtrans %}
{% transchoice count %}
{0} There are no apples|{1} There is one apple|]1,Inf[ There are %count% apples
{% endtranschoice %}
The ``transchoice`` tag automatically gets the ``%count%`` variable from
the current context and passes it to the translator. This mechanism only
works when you use a placeholder following the ``%var%`` pattern.

.. caution::

The ``%var%`` notation of placeholders is required when translating in
Twig templates using the tag.

.. tip::

If you need to use the percent character (``%``) in a string, escape it by
doubling it: ``{% trans %}Percent: %percent%%%{% endtrans %}``

You can also specify the message domain and pass some additional variables:

.. code-block:: twig
{% trans with {'%name%': 'Fabien'} from 'app' %}Hello %name%{% endtrans %}
{% trans with {'%name%': 'Fabien'} from 'app' into 'fr' %}Hello %name%{% endtrans %}
{% transchoice count with {'%name%': 'Fabien'} from 'app' %}
{0} %name%, there are no apples|{1} %name%, there is one apple|]1,Inf[ %name%, there are %count% apples
{% endtranschoice %}
.. _translation-filters:

Using Twig Filters
~~~~~~~~~~~~~~~~~~

The ``trans`` and ``transchoice`` filters can be used to translate *variable
texts* and complex expressions:

.. code-block:: twig
{{ message|trans }}
{{ message|transchoice(5) }}
{{ message|trans({'%name%': 'Fabien'}, 'app') }}
{{ message|transchoice(5, {'%name%': 'Fabien'}, 'app') }}
.. tip::

Using the translation tags or filters have the same effect, but with
one subtle difference: automatic output escaping is only applied to
translations using a filter. In other words, if you need to be sure
that your translated message is *not* output escaped, you must apply
the ``raw`` filter after the translation filter:

.. code-block:: html+twig

{# text translated between tags is never escaped #}
{% trans %}
<h3>foo</h3>
{% endtrans %}

{% set message = '<h3>foo</h3>' %}

{# strings and variables translated via a filter are escaped by default #}
{{ message|trans|raw }}
{{ '<h3>bar</h3>'|trans|raw }}
.. tip::

You can set the translation domain for an entire Twig template with a single tag:

.. code-block:: twig
{% trans_default_domain 'app' %}
Note that this only influences the current template, not any "included"
template (in order to avoid side effects).

PHP Templates
-------------

The translator service is accessible in PHP templates through the
``translator`` helper::

<?= $view['translator']->trans('Symfony is great') ?>

<?= $view['translator']->transChoice(
'{0} There are no apples|{1} There is one apple|]1,Inf[ There are %count% apples',
10,
['%count%' => 10]
) ?>

0 comments on commit a6dabc1

Please sign in to comment.