You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: docs/i18n-l10n/translating-text-strings.md
+71-37Lines changed: 71 additions & 37 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -11,8 +11,8 @@ html_meta:
11
11
# Translating text strings
12
12
13
13
```{todo}
14
-
This entire chapter contains cruft dating back to Plone 3 in some parts.
15
-
It is perfectly fine to purge obsolete information.
14
+
This chapter may contains outdated or incorrect information.
15
+
Please submit a pull request to make a correction.
16
16
```
17
17
18
18
```{note}
@@ -21,44 +21,47 @@ This chapter concerns only *code-level* translations of text strings.
21
21
For *user-generated content* translations, see {doc}`translating-content`.
22
22
```
23
23
24
-
# Translating text strings
25
-
26
-
This chapter describes how to translate Python and TAL template source code text strings using
27
-
the {term}`gettext` framework and other Plone/Zope {term}`i18n` facilities.
24
+
This chapter describes how to translate Python and TAL template source code text strings using the {term}`gettext` framework and other Plone/Zope {term}`i18n` facilities.
28
25
29
26
Plone internally uses the UNIX standard {term}`gettext` tool to perform {term}`i18n`.
30
27
28
+
29
+
(translating-text-strings-zope.i18n-label)=
30
+
31
31
## `zope.i18n`
32
32
33
33
The package `zope.i18n` implements several APIs related to internationalization and localization.
34
34
35
35
- Follows {term}`gettext` best practices.
36
-
- Translations are stored in the `locales` folder of your application.
37
-
Example: `locales/fi/LC_MESSAGES/your.app.po`
38
-
- Uses the package [`zope.i18nmessageid`](https://pypi.org/project/zope.i18nmessageid/)
36
+
- Translations are stored in the `locales` folder of your application, such as `locales/fi/LC_MESSAGES/your.app.po`.
37
+
- Uses the package [`zope.i18nmessageid`](https://pypi.org/project/zope.i18nmessageid/).
39
38
This provides a string-like class which allows storing the translation domain with translatable text strings.
40
-
-`.po` files must usually be manually converted to `.mo`binary files every time the translations are updated.
39
+
-{term}`PO file`s must usually be manually converted to binary {term}`MO file`s every time the translations are updated.
41
40
See {term}`i18ndude`.
42
-
It is also possible to set an environment variable to trigger recompilation of `.mo` files.
43
-
See {ref}`i18n-i18ndude-label` below for details.
41
+
It is also possible to set an environment variable to trigger recompilation of MO files.
42
+
See {ref}`translating-text-strings-i18ndude-label` below for details.
44
43
45
44
```{seealso}
46
45
[`zope.i18n` on PyPI](https://pypi.org/project/zope.i18n/)
47
46
```
48
47
49
48
Plone searches only the filename and path for the translation files.
### Generating a `.pot` template file for your packages
54
55
55
56
[`i18ndude`](https://pypi.org/project/i18ndude/) should be used to create a script which searches particular packages for translation strings.
56
57
57
-
If you have created you addon using [bobtemplates.plone](https://pypi.org/project/bobtemplates.plone/)you will already have a `update.sh`script inside your package and an `update_locale` script in your buildout to extract the messages from your code.
58
+
If you have created your add-on using [bobtemplates.plone](https://pypi.org/project/bobtemplates.plone/), then you will already have a script `update.sh` inside your package and a script `update_locale` in your buildout to extract the messages from your code.
58
59
59
-
After running that script a new `domain.pot` file will be created in your `locales` directory where all the messages will be saved.
60
+
After running that script, a new `domain.pot` file will be created in your `locales` directory where all the messages will be saved.
60
61
61
-
To have those messages translated into some languages, you will need to create a language directory inside the `locales` directory, and a `LC_MESSAGES` directory inside it. This follows the `gettext` standard. After doing that, the directory structure will be as follows:
62
+
To have those messages translated into some languages, you will need to create a language directory inside the `locales` directory, and a `LC_MESSAGES` directory inside it.
63
+
This follows the gettext standard.
64
+
After doing that, the directory structure will be as follows.
62
65
63
66
```console
64
67
./locales/en/LC_MESSAGES/domain.po
@@ -68,9 +71,9 @@ To have those messages translated into some languages, you will need to create a
68
71
69
72
You will need to provide your translations in those `domain.po` files.
70
73
71
-
If you add new strings in your package, you will only need to run the `update.sh` script to update all language files with the new strings or remove the old ones.
74
+
If you add, update, or remove strings in your package, you will need to run only the `update.sh` script to update all language files.
72
75
73
-
You also need to have the following ZCML entry to signal Plone that the files stored in the `locales` folder follow the gettext standard and it needs to use them when requesting translated strings:
76
+
You also need to have the following ZCML entry to signal Plone that the files stored in the `locales` folder follow the gettext standard and that it needs to use them when requesting translated strings.
You will need to declare you own `MessageFactory` which is a callable and marks strings with a translation domain. `MessageFactory` is usually declared in the main `__init__.py` file of your package and imported from wherever is needed in your package. `_` is the standard name that is used in `gettext` to identify the translation function, and the previous scripts will use that assumption to identify translatable strings.
89
+
You will need to declare you own `MessageFactory`.
90
+
This is a callable that marks strings with a translation domain.
91
+
`MessageFactory` is usually declared in the main `__init__.py` file of your package.
92
+
It is imported from wherever it is needed in your package.
93
+
`_` is the standard name that is used in gettext to identify the translation function, and the previous scripts will use that assumption to identify translatable strings.
85
94
86
95
```python
87
96
from zope.i18nmessageid import MessageFactory
@@ -90,8 +99,7 @@ from zope.i18nmessageid import MessageFactory
90
99
_ = MessageFactory('youpackage.name')
91
100
```
92
101
93
-
94
-
After the setup above, you can use the message factory to mark strings with translation domains.
102
+
Now you can use the message factory to mark strings with translation domains.
95
103
96
104
```python
97
105
from your.app.package import _
@@ -105,7 +113,7 @@ The object will still look like a string:
105
113
u'My text'
106
114
```
107
115
108
-
But in reality it is a `zope.i18nmessageid.message.Message` object:
116
+
But in reality, it is a `zope.i18nmessageid.message.Message` object:
109
117
110
118
```pycon
111
119
>>> my_translatable_text.__class__
@@ -115,7 +123,7 @@ But in reality it is a `zope.i18nmessageid.message.Message` object:
115
123
'your.app.package'
116
124
```
117
125
118
-
To see the translation in python code you will need to manually call the `translate` function in `zope.i18n`:
126
+
To see the translation in Python code you will need to manually call the `translate` function in `zope.i18n`:
119
127
120
128
```pycon
121
129
>>> from zope.i18n import translate
@@ -124,9 +132,11 @@ u"The text of the translation." # This is the corresponding msgstr from the .po
@@ -144,9 +154,11 @@ It will use the text content of the element as `msgid`.
144
154
Use attributes `i18n:translate`, `i18n:attributes`, and so on.
145
155
For examples, look at any core Plone `.pt` files.
146
156
147
-
This`i18n:translate` will hook into the translation machinery, and will look up the corresponding translated string to the one stated there, looking in the relevant `domain.po` file corresponding to the `i18n:domain` stated in the file and the language negotiated by Plone.
157
+
The`i18n:translate`attribute will hook into the translation machinery, and will look up the corresponding translated string to the one stated there, while looking in the relevant `domain.po` file corresponding to the `i18n:domain` stated in the file and the language negotiated by Plone.
If you need to manipulate translated text outside page templates, you need to perform the final translation manually. For instance this is needed when you are building human readable strings in python code, for instance when creating some messages that are sent by e-mail to the end user.
181
+
If you need to manipulate translated text outside page templates, then you need to perform the final translation manually.
182
+
This is needed when you are building human-readable strings in Python code, for example when creating some messages that are sent by email to the end user.
168
183
169
184
Translation always needs context.
170
185
That means under which site the translation happens.
Translation string substitutions must be used when the final translated message contains variable strings.
@@ -223,15 +243,15 @@ class SomeView(BrowserView):
223
243
```
224
244
225
245
226
-
(i18n-i18ndude-label)=
246
+
(translating-text-strings-i18ndude-label)=
227
247
228
248
## `i18ndude`
229
249
230
-
{term}`i18ndude` is a developer-oriented command-line utility to manage `.po` and `.mo` files.
250
+
{term}`i18ndude` is a developer-oriented command-line utility to manage PO and MO files.
231
251
232
-
Usually you build our own shell script wrapper around `i18ndude` to automate generation of `.mo` files of your package's `.po` files.
252
+
Usually you build our own shell script wrapper around `i18ndude` to automate generation of MO files from your package's PO files.
233
253
234
-
Plone will automatically compile all po files to mo on start up if an specific environment variable is enabled.
254
+
Plone will automatically compile all PO files to MO files on start up if a specific environment variable is enabled.
235
255
236
256
In your `buildout.cfg` in the part using `plone.recipe.zope2instance`, you can set an environment variable for this.
237
257
@@ -241,11 +261,15 @@ environment-vars =
241
261
```
242
262
243
263
Note that the value does not matter.
244
-
The code in `zope.i18n` looks for the existence of the variable and does not care what is its value.
264
+
The code in `zope.i18n` looks for the mere existence of the variable, and does not care what is its value.
245
265
246
-
If you do not add that environment variable, you will need to provide the mo files in your package. To ease this and if you use [zest.releaser](https://pypi.org/project/zest.releaser/) to publish your packages, you can use [zest.pocompile](https://pypi.org/project/zest.pocompile/) a script that hooks into the release process and builds the mo files for you.
266
+
If you do not add that environment variable, you will need to provide the MO files in your package.
267
+
To make this easier, and if you use [zest.releaser](https://pypi.org/project/zest.releaser/) to publish your packages, you can use [zest.pocompile](https://pypi.org/project/zest.pocompile/).
268
+
This script hooks into the release process and builds the MO files for you.
If you need to change a translation from a `.po` file, you could create a new Python package and register your own `.po` files.
404
+
If you need to change a translation from a PO file, you could create a new Python package and register your own PO files.
371
405
372
406
To do this, create the package and add a `locales` directory in there, along the lines of what [plone.app.locales](https://pypi.org/project/plone.app.locales/) does.
373
407
Then you can add your own translations in the language that you need.
0 commit comments