@@ -21,79 +21,6 @@ In this example, the message *"Symfony is great!"* will be translated into
2121the locale set in the constructor (``fr_FR ``) if the message exists in one of
2222the 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-
9724Creating 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