Skip to content

Commit 524881b

Browse files
committed
Merge branch '4.2' into 4.3
* 4.2: Yet another great review! Add link to usefull online editor Fixes after thorough reviews! Removed further usage of transchoice in the docs Added documentation on the ICU MessageFormat Some general fixes/improvements for translation guide
2 parents cea2d74 + 31175cf commit 524881b

File tree

6 files changed

+621
-368
lines changed

6 files changed

+621
-368
lines changed

components/translation/usage.rst

Lines changed: 0 additions & 208 deletions
Original file line numberDiff line numberDiff line change
@@ -21,79 +21,6 @@ In this example, the message *"Symfony is great!"* will be translated into
2121
the locale set in the constructor (``fr_FR``) if the message exists in one of
2222
the message catalogs.
2323

24-
.. _component-translation-placeholders:
25-
26-
Message Placeholders
27-
--------------------
28-
29-
Sometimes, a message containing a variable needs to be translated::
30-
31-
// ...
32-
$translated = $translator->trans('Hello '.$name);
33-
34-
var_dump($translated);
35-
36-
However, creating a translation for this string is impossible since the translator
37-
will try to look up the exact message, including the variable portions
38-
(e.g. *"Hello Ryan"* or *"Hello Fabien"*). Instead of writing a translation
39-
for every possible iteration of the ``$name`` variable, you can replace the
40-
variable with a "placeholder"::
41-
42-
// ...
43-
$translated = $translator->trans(
44-
'Hello %name%',
45-
['%name%' => $name]
46-
);
47-
48-
var_dump($translated);
49-
50-
Symfony will now look for a translation of the raw message (``Hello %name%``)
51-
and *then* replace the placeholders with their values. Creating a translation
52-
is done just as before:
53-
54-
.. configuration-block::
55-
56-
.. code-block:: xml
57-
58-
<?xml version="1.0"?>
59-
<xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2">
60-
<file source-language="en" datatype="plaintext" original="file.ext">
61-
<body>
62-
<trans-unit id="1">
63-
<source>Hello %name%</source>
64-
<target>Bonjour %name%</target>
65-
</trans-unit>
66-
</body>
67-
</file>
68-
</xliff>
69-
70-
.. code-block:: yaml
71-
72-
'Hello %name%': Bonjour %name%
73-
74-
.. code-block:: php
75-
76-
return [
77-
'Hello %name%' => 'Bonjour %name%',
78-
];
79-
80-
.. note::
81-
82-
The placeholders can take on any form as the full message is reconstructed
83-
using the PHP :phpfunction:`strtr function<strtr>`. But the ``%...%`` form
84-
is recommended, to avoid problems when using Twig.
85-
86-
As you've seen, creating a translation is a two-step process:
87-
88-
#. Abstract the message that needs to be translated by processing it through
89-
the ``Translator``.
90-
91-
#. Create a translation for the message in each locale that you choose to
92-
support.
93-
94-
The second step is done by creating message catalogs that define the translations
95-
for any number of different locales.
96-
9724
Creating Translations
9825
---------------------
9926

@@ -222,141 +149,6 @@ recommended format. These files are parsed by one of the loader classes.
222149
'user.login' => 'Login',
223150
];
224151
225-
.. _component-translation-pluralization:
226-
227-
Pluralization
228-
-------------
229-
230-
Message pluralization is a tough topic as the rules can be quite complex. For
231-
instance, here is the mathematical representation of the Russian pluralization
232-
rules::
233-
234-
(($number % 10 == 1) && ($number % 100 != 11))
235-
? 0
236-
: ((($number % 10 >= 2)
237-
&& ($number % 10 <= 4)
238-
&& (($number % 100 < 10)
239-
|| ($number % 100 >= 20)))
240-
? 1
241-
: 2
242-
);
243-
244-
As you can see, in Russian, you can have three different plural forms, each
245-
given an index of 0, 1 or 2. For each form, the plural is different, and
246-
so the translation is also different.
247-
248-
When a translation has different forms due to pluralization, you can provide
249-
all the forms as a string separated by a pipe (``|``)::
250-
251-
'There is one apple|There are %count% apples'
252-
253-
To translate pluralized messages, use the
254-
:method:`Symfony\\Component\\Translation\\Translator::transChoice` method::
255-
256-
// the %count% placeholder is assigned to the second argument...
257-
$translator->transChoice(
258-
'There is one apple|There are %count% apples',
259-
10
260-
);
261-
262-
// ...but you can define more placeholders if needed
263-
$translator->transChoice(
264-
'Hurry up %name%! There is one apple left.|There are %count% apples left.',
265-
10,
266-
// no need to include %count% here; Symfony does that for you
267-
['%name%' => $user->getName()]
268-
);
269-
270-
The second argument (``10`` in this example) is the *number* of objects being
271-
described and is used to determine which translation to use and also to populate
272-
the ``%count%`` placeholder.
273-
274-
Based on the given number, the translator chooses the right plural form.
275-
In English, most words have a singular form when there is exactly one object
276-
and a plural form for all other numbers (0, 2, 3...). So, if ``count`` is
277-
``1``, the translator will use the first string (``There is one apple``)
278-
as the translation. Otherwise it will use ``There are %count% apples``.
279-
280-
Here is the French translation:
281-
282-
.. code-block:: text
283-
284-
'Il y a %count% pomme|Il y a %count% pommes'
285-
286-
Even if the string looks similar (it is made of two sub-strings separated by a
287-
pipe), the French rules are different: the first form (no plural) is used when
288-
``count`` is ``0`` or ``1``. So, the translator will automatically use the
289-
first string (``Il y a %count% pomme``) when ``count`` is ``0`` or ``1``.
290-
291-
Each locale has its own set of rules, with some having as many as six different
292-
plural forms with complex rules behind which numbers map to which plural form.
293-
The rules are quite simple for English and French, but for Russian, you'd
294-
may want a hint to know which rule matches which string. To help translators,
295-
you can optionally "tag" each string:
296-
297-
.. code-block:: text
298-
299-
'one: There is one apple|some: There are %count% apples'
300-
301-
'none_or_one: Il y a %count% pomme|some: Il y a %count% pommes'
302-
303-
The tags are really only hints for translators and don't affect the logic
304-
used to determine which plural form to use. The tags can be any descriptive
305-
string that ends with a colon (``:``). The tags also do not need to be the
306-
same in the original message as in the translated one.
307-
308-
.. tip::
309-
310-
As tags are optional, the translator doesn't use them (the translator will
311-
only get a string based on its position in the string).
312-
313-
Explicit Interval Pluralization
314-
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
315-
316-
The easiest way to pluralize a message is to let the Translator use internal
317-
logic to choose which string to use based on a given number. Sometimes, you'll
318-
need more control or want a different translation for specific cases (for
319-
``0``, or when the count is negative, for example). For such cases, you can
320-
use explicit math intervals:
321-
322-
.. code-block:: text
323-
324-
'{0} There are no apples|{1} There is one apple|]1,19] There are %count% apples|[20,Inf[ There are many apples'
325-
326-
The intervals follow the `ISO 31-11`_ notation. The above string specifies
327-
four different intervals: exactly ``0``, exactly ``1``, ``2-19``, and ``20``
328-
and higher.
329-
330-
You can also mix explicit math rules and standard rules. In this case, if
331-
the count is not matched by a specific interval, the standard rules take
332-
effect after removing the explicit rules:
333-
334-
.. code-block:: text
335-
336-
'{0} There are no apples|[20,Inf[ There are many apples|There is one apple|a_few: There are %count% apples'
337-
338-
For example, for ``1`` apple, the standard rule ``There is one apple`` will
339-
be used. For ``2-19`` apples, the second standard rule
340-
``There are %count% apples`` will be selected.
341-
342-
An :class:`Symfony\\Component\\Translation\\Interval` can represent a finite set
343-
of numbers:
344-
345-
.. code-block:: text
346-
347-
{1,2,3,4}
348-
349-
Or numbers between two other numbers:
350-
351-
.. code-block:: text
352-
353-
[1, +Inf[
354-
]-1,2[
355-
356-
The left delimiter can be ``[`` (inclusive) or ``]`` (exclusive). The right
357-
delimiter can be ``[`` (exclusive) or ``]`` (inclusive). Beside numbers, you
358-
can use ``-Inf`` and ``+Inf`` for the infinite.
359-
360152
Forcing the Translator Locale
361153
-----------------------------
362154

reference/twig_reference.rst

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -359,6 +359,12 @@ Translates the text into the current language. More information in
359359
transchoice
360360
~~~~~~~~~~~
361361

362+
.. deprecated:: 4.2
363+
364+
The ``transchoice`` filter is deprecated since Symfony 4.2 and will be
365+
removed in 5.0. Use the :doc:`ICU MessageFormat </translation/message_format>` with
366+
the ``trans`` filter instead.
367+
362368
.. code-block:: twig
363369
364370
{{ message|transchoice(count, arguments = [], domain = null, locale = null) }}
@@ -588,6 +594,12 @@ Renders the translation of the content. More information in :ref:`translation-ta
588594
transchoice
589595
~~~~~~~~~~~
590596

597+
.. deprecated:: 4.2
598+
599+
The ``transchoice`` tag is deprecated since Symfony 4.2 and will be
600+
removed in 5.0. Use the :doc:`ICU MessageFormat </translation/message_format>` with
601+
the ``trans`` tag instead.
602+
591603
.. code-block:: twig
592604
593605
{% transchoice count with vars from domain into locale %}{% endtranschoice %}

0 commit comments

Comments
 (0)