Skip to content

Commit c1baf7b

Browse files
committed
[TASK] Update translate ViewHelper page
* Link to related topics * Demonstrate what the corresponding XLIFF files look like * use f:format.html or f:sanitize.html and not format.raw as best practice * Explain using placeholders and arguments * Demonstrate using a translation in an alt tag Releases: main, 13.4, 12.4
1 parent 49053c6 commit c1baf7b

File tree

4 files changed

+217
-45
lines changed

4 files changed

+217
-45
lines changed

Documentation/Global/Translate.rst

Lines changed: 168 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -8,85 +8,208 @@ Translate ViewHelper `<f:translate>`
88
====================================
99

1010
.. typo3:viewhelper:: translate
11-
:source: ../Global.json
12-
:display: tags,description,gitHubLink,arguments
11+
:source: /Global.json
12+
:display: tags,description,gitHubLink
13+
:noindex:
14+
15+
.. seealso::
16+
* `Working with XLIFF files <https://docs.typo3.org/permalink/t3coreapi:xliff-api>`_
17+
* `Multi-language Fluid templates <https://docs.typo3.org/permalink/t3coreapi:extension-localization-fluid>`_
18+
19+
.. contents:: Table of contents
1320

1421
.. _typo3-fluid-translate-example:
1522

1623
Examples
1724
========
1825

19-
Translate key
20-
-------------
26+
.. _typo3-fluid-translate-example-key-only:
27+
28+
Short key - Usage in Extbase
29+
----------------------------
30+
31+
The :ref:`key <t3viewhelper:viewhelper-argument-typo3-cms-fluid-viewhelpers-translateviewhelper-key>`
32+
argument alone works only within the Extbase context.
33+
34+
.. tabs::
35+
36+
.. group-tab:: Fluid
37+
38+
.. code-block:: html
39+
40+
<f:translate key="domain_model.title" />
41+
42+
.. group-tab:: Language file example
43+
44+
.. literalinclude:: _Translate/_locallang.xlf
45+
:language: xml
46+
:caption: packages/my_extension/Resources/Private/Language/locallang.xlf
47+
48+
Alternatively, you can use `id` instead of `key`, producing the same output.
49+
If both `id` and `key` are set, `id` takes precedence.
50+
51+
If the translate ViewHelper is used with only the language key, the template
52+
**must** be rendered within an Extbase request, usually from an Extbase
53+
controller action. The default language file must be located in the same
54+
extension as the Extbase controller and must be saved in the file
55+
:file:`Resources/Private/Language/locallang.xlf`.
56+
57+
.. _typo3-fluid-translate-example-key-extension:
58+
59+
Short key and extension name
60+
----------------------------
61+
62+
When the ViewHelper is called from outside Extbase, it is mandatory to either
63+
pass the extension name or use the full `LLL:` reference for the key.
64+
65+
.. code-block:: html
66+
67+
<f:translate key="domain_model.title" extension="my_extension" />
68+
69+
The default language file must be saved in the extension specified in the
70+
argument, in the file :file:`Resources/Private/Language/locallang.xlf`.
2171

22-
::
72+
.. _typo3-fluid-translate-example-key-full:
2373

24-
<f:translate key="key1" />
74+
Full `LLL:` reference key
75+
-------------------------
2576

26-
Value of key ``key1`` in the current website language. Alternatively id can
27-
be used instead of key::
77+
Using the `LLL:` language reference syntax, a language key from any `.xlf`
78+
file can be used.
2879

29-
<f:translate id="key1" />
80+
.. code-block:: html
3081

31-
This will output the same as above. If both id and key are set, id will take precedence.
82+
<f:translate
83+
key="LLL:EXT:my_extension/Resources/Private/Language/my_locallang.xlf:domain_model.title"
84+
/>
3285

33-
Keep HTML tags
34-
--------------
86+
.. _typo3-fluid-translate-example-html:
3587

36-
::
88+
Keeping HTML tags within translations
89+
-------------------------------------
3790

38-
<f:format.raw><f:translate key="htmlKey" /></f:format.raw>
91+
HTML in language labels can be used when you surround the translate ViewHelper
92+
with a ViewHelper that allows HTML output, such as the
93+
`Sanitize.html ViewHelper <f:sanitize.html> <https://docs.typo3.org/permalink/t3viewhelper:typo3-fluid-sanitize-html>`_
94+
in the backend or the `Format.html ViewHelper <f:format.html> <https://docs.typo3.org/permalink/t3viewhelper:typo3-fluid-format-html>`_
95+
in the frontend.
3996

40-
Value of key ``htmlKey`` in the current website language, no :php:`htmlspecialchars()` applied.
97+
.. tabs::
4198

42-
Translate key from custom locallang file
43-
----------------------------------------
99+
.. group-tab:: Fluid
44100

45-
::
101+
.. code-block:: html
46102

47-
<f:translate key="key1" extensionName="MyExt"/>
103+
<f:format.html>
104+
<f:translate
105+
key="LLL:EXT:my_extension/Resources/Private/Language/my_locallang.xlf:myKey"
106+
/>
107+
</f:format.html>
48108

49-
or
109+
.. group-tab:: Language file example
50110

51-
::
111+
.. literalinclude:: _Translate/_locallang_html.xlf
112+
:language: xml
113+
:caption: packages/my_extension/Resources/Private/Language/locallang.xlf
52114

53-
<f:translate key="LLL:EXT:myext/Resources/Private/Language/locallang.xlf:key1" />
115+
The entry in the `.xlf` language file must be surrounded by `<![CDATA[...]]>`.
54116

55-
Value of key ``key1`` in the current website language.
117+
.. warning::
118+
When allowing HTML tags in translations, ensure all translators are
119+
educated about `Cross-site scripting (XSS) <https://docs.typo3.org/permalink/t3coreapi:security-xss>`_.
120+
121+
.. _typo3-fluid-translate-example-placeholder:
122+
123+
Displaying translated labels with placeholders
124+
----------------------------------------------
125+
126+
.. tabs::
127+
128+
.. group-tab:: Fluid
129+
130+
.. code-block:: html
131+
132+
<f:translate
133+
key="LLL:EXT:my_extension/Resources/Private/Language/locallang.xlf:domain_model.title"
134+
arguments="{0: '{myVariable}'}"
135+
/>
136+
137+
Or with several numbered placeholders:
138+
139+
<f:translate
140+
key="LLL:EXT:my_extension/Resources/Private/Language/locallang.xlf:domain_model.title"
141+
arguments="{1: '{myVariable}', 2: 'Some String'}"
142+
/>
143+
144+
.. group-tab:: Language file example
145+
146+
.. literalinclude:: _Translate/_locallang_arguments.xlf
147+
:language: xml
148+
149+
The placeholder `%s` is used to insert dynamic values, passed as the parameter
150+
:ref:`arguments <t3viewhelper:viewhelper-argument-typo3-cms-fluid-viewhelpers-translateviewhelper-arguments>`
151+
to the translate ViewHelper. If `%s` appears multiple times, it references
152+
subsequent array entries in order.
153+
154+
To avoid dependency on order, use indexed placeholders like `%1$s`. This
155+
explicitly refers to the first value and ensures that it is treated as a string
156+
(`$s`). This method is based on PHP’s
157+
`vsprintf function <https://www.php.net/manual/en/function.vsprintf.php>`,
158+
which allows for more flexible and readable formatting.
159+
160+
.. _typo3-fluid-translate-example-inline:
56161

57162
Inline notation with arguments and default value
58163
------------------------------------------------
59164

60-
::
165+
Like all other ViewHelpers, the translate ViewHelper can be used with the
166+
`Inline syntax <https://docs.typo3.org/permalink/fluid:viewhelper-inline-notation>`_.
167+
168+
.. code-block:: html
61169

62-
{f:translate(key: 'someKey', arguments: {0: 'dog', 1: 'fox'}, default: 'default value')}
170+
{f:translate(key: 'someKey', arguments: {0: 'dog', 1: 'fox'}, default: 'default value')}
63171

64-
Value of key ``someKey`` in the current website language
65-
with the given arguments (``dog`` and ``fox``) assigned for the specified
66-
``%s`` conversions, using `PHP sprintf() notation <https://www.php.net/sprintf>`__ in the
67-
language file::
172+
This is especially useful if you want to pass the translated label to another
173+
ViewHelper, for example, as the `alt` parameter of an image:
68174

69-
<trans-unit id="someKey">
70-
<source>Some text about a %s and a %s.</source>
71-
</trans-unit>
175+
.. code-block:: html
72176

73-
The output will be :html:`Some text about a dog and a fox`.
177+
<f:image src="EXT:my_extension/Resources/Public/icons/Edit.svg"
178+
alt="{f:translate(key: 'icons.edit', default: 'Edit')}"
179+
/>
74180

75-
If the key ``someKey`` is not found in the language file, the output is :html:`default value`.
181+
.. _typo3-fluid-translate-example-console:
76182

77-
As in PHP's :php:`sprintf()` you can order placeholders (:php:`Second %2$s, first %1$s`)
78-
or use specific types like :php:`A padded number: %'.09d`, returning ``000000123`` for a number
79-
passed as ``123``.
80-
See the `sprintf`_ PHP Documentation for more information on possible formatting.
183+
The translation ViewHelper in console/CLI context
184+
-------------------------------------------------
81185

82-
Inline notation with extension name
83-
-----------------------------------
186+
The translation ViewHelper determines the target language based on the current
187+
frontend or backend request.
84188

85-
::
189+
If you are rendering your template from a console/CLI context, for example,
190+
when you `Send emails with FluidEmail <https://docs.typo3.org/permalink/t3coreapi:mail-fluid-email>`_,
191+
use the argument :ref:`languageKey <t3viewhelper:viewhelper-argument-typo3-cms-fluid-viewhelpers-translateviewhelper-languagekey>`
192+
to specify the desired language for the ViewHelper:
86193

87-
{f:translate(key: 'someKey', extensionName: 'SomeExtensionName')}
194+
.. code-block:: html
88195

89-
Value of key ``someKey`` in the current website language.
90-
The locallang file of extension "some_extension_name" will be used.
196+
Salutation in Danish:
197+
<f:translate
198+
key="LLL:EXT:my_extension/Resources/Private/Language/my_locallang.xlf:salutation"
199+
languageKey="da"
200+
/>
91201

92-
.. _sprintf: https://www.php.net/sprintf
202+
Salutation in English:
203+
<f:translate
204+
key="LLL:EXT:my_extension/Resources/Private/Language/my_locallang.xlf:salutation"
205+
languageKey="default"
206+
/>
207+
208+
.. _typo3-fluid-translate-arguments:
209+
210+
Arguments of the f:translate ViewHelper
211+
=======================================
212+
213+
.. typo3:viewhelper:: translate
214+
:source: /Global.json
215+
:display: arguments-only
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
<?xml version="1.0" encoding="UTF-8" ?>
2+
<xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2">
3+
<file source-language="en" datatype="plaintext"
4+
original="EXT:my_extension/Resources/Private/Language/locallang.xlf"
5+
date="2020-10-18T18:20:51Z" product-name="my_extension"
6+
>
7+
<header />
8+
<body>
9+
<trans-unit id="domain_model.title">
10+
<source>My Model</source>
11+
</trans-unit>
12+
</body>
13+
</file>
14+
</xliff>
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
<?xml version="1.0" encoding="UTF-8" ?>
2+
<xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2">
3+
<file source-language="en" datatype="plaintext"
4+
original="EXT:my_extension/Resources/Private/Language/locallang.xlf"
5+
date="2020-10-18T18:20:51Z" product-name="my_extension"
6+
>
7+
<header />
8+
<body>
9+
<label index="domain_model.title">Title of: %s</label>
10+
<trans-unit id="domain_model.description">
11+
<source>Some text about a %1$s and a %2$s.</source>
12+
</trans-unit>
13+
</body>
14+
</file>
15+
</xliff>
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
<?xml version="1.0" encoding="UTF-8" ?>
2+
<xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2">
3+
<file source-language="en" datatype="plaintext"
4+
original="EXT:my_extension/Resources/Private/Language/locallang.xlf"
5+
date="2020-10-18T18:20:51Z" product-name="my_extension"
6+
>
7+
<header />
8+
<body>
9+
<trans-unit id="myKey">
10+
<source>
11+
<![CDATA[By default, ordered and unordered lists are formatted
12+
with bullets and decimals. <br>
13+
By adding <code>class="list-unstyled"</code> to the ol or ul tag, it
14+
is possible to structure content in list form without the
15+
typical list styling.]]>
16+
</source>
17+
</trans-unit>
18+
</body>
19+
</file>
20+
</xliff>

0 commit comments

Comments
 (0)