Skip to content

Commit 40f4416

Browse files
committed
Clean up translating-text-strings.md
1 parent 19cc135 commit 40f4416

File tree

1 file changed

+71
-37
lines changed

1 file changed

+71
-37
lines changed

docs/i18n-l10n/translating-text-strings.md

Lines changed: 71 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,8 @@ html_meta:
1111
# Translating text strings
1212

1313
```{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.
1616
```
1717

1818
```{note}
@@ -21,44 +21,47 @@ This chapter concerns only *code-level* translations of text strings.
2121
For *user-generated content* translations, see {doc}`translating-content`.
2222
```
2323

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.
2825

2926
Plone internally uses the UNIX standard {term}`gettext` tool to perform {term}`i18n`.
3027

28+
29+
(translating-text-strings-zope.i18n-label)=
30+
3131
## `zope.i18n`
3232

3333
The package `zope.i18n` implements several APIs related to internationalization and localization.
3434

3535
- 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/).
3938
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.
4140
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.
4443

4544
```{seealso}
4645
[`zope.i18n` on PyPI](https://pypi.org/project/zope.i18n/)
4746
```
4847

4948
Plone searches only the filename and path for the translation files.
50-
Information in the `.po` file headers is ignored.
49+
Information in the PO file headers is ignored.
50+
5151

52+
(translating-text-strings-generating-a-.pot-template-file-for-your-packages-label)=
5253

5354
### Generating a `.pot` template file for your packages
5455

5556
[`i18ndude`](https://pypi.org/project/i18ndude/) should be used to create a script which searches particular packages for translation strings.
5657

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.
5859

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.
6061

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.
6265

6366
```console
6467
./locales/en/LC_MESSAGES/domain.po
@@ -68,9 +71,9 @@ To have those messages translated into some languages, you will need to create a
6871

6972
You will need to provide your translations in those `domain.po` files.
7073

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.
7275

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.
7477

7578
```xml
7679
<configure xmlns:i18n="http://namespaces.zope.org/i18n">
@@ -79,9 +82,15 @@ You also need to have the following ZCML entry to signal Plone that the files st
7982
```
8083

8184

85+
(translating-text-strings-marking-translatable-strings-in-python-label)=
86+
8287
### Marking translatable strings in Python
8388

84-
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.
8594

8695
```python
8796
from zope.i18nmessageid import MessageFactory
@@ -90,8 +99,7 @@ from zope.i18nmessageid import MessageFactory
9099
_ = MessageFactory('youpackage.name')
91100
```
92101

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.
95103

96104
```python
97105
from your.app.package import _
@@ -105,7 +113,7 @@ The object will still look like a string:
105113
u'My text'
106114
```
107115

108-
But in reality it is a `zope.i18nmessageid.message.Message` object:
116+
But in reality, it is a `zope.i18nmessageid.message.Message` object:
109117

110118
```pycon
111119
>>> my_translatable_text.__class__
@@ -115,7 +123,7 @@ But in reality it is a `zope.i18nmessageid.message.Message` object:
115123
'your.app.package'
116124
```
117125

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`:
119127

120128
```pycon
121129
>>> from zope.i18n import translate
@@ -124,9 +132,11 @@ u"The text of the translation." # This is the corresponding msgstr from the .po
124132
```
125133

126134

135+
(translating-text-strings-marking-translatable-strings-in-tal-page-templates-label)=
136+
127137
### Marking translatable strings in TAL page templates
128138

129-
Declare the XML namespace `i18n` and translation domain at the beginning of your template, at the first element.
139+
Declare the XML namespace `i18n` and translation domain at the beginning of your template, in the first element.
130140

131141
```html
132142
<div id="mobile-header" xmlns:i18n="http://xml.zope.org/namespaces/i18n" i18n:domain="plomobile">
@@ -144,9 +154,11 @@ It will use the text content of the element as `msgid`.
144154
Use attributes `i18n:translate`, `i18n:attributes`, and so on.
145155
For examples, look at any core Plone `.pt` files.
146156

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.
148158

149159

160+
(translating-text-strings-automatically-translated-message-ids-label)=
161+
150162
### Automatically translated message IDs
151163

152164
Plone will automatically perform translation for message IDs which are output in page templates.
@@ -162,9 +174,12 @@ Since `my_translateable_text` is a `zope.i18nmessageid.message.Message` instance
162174
```
163175

164176

177+
(translating-text-strings-manually-translated-message-ids-label)=
178+
165179
### Manually translated message IDs
166180

167-
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.
168183

169184
Translation always needs context.
170185
That means under which site the translation happens.
@@ -184,6 +199,9 @@ translated = translate(msgid, context=getRequest())
184199
# translated is now u"Käännetty teksti" (in Finnish)
185200
```
186201

202+
203+
(translating-text-strings-non-python-message-ids-label)=
204+
187205
### Non-Python message IDs
188206

189207
There are other message ID markers in code outside the Python domain that have their own mechanisms:
@@ -193,6 +211,8 @@ There are other message ID markers in code outside the Python domain that have t
193211
- TAL page templates
194212

195213

214+
(translating-text-strings-translation-string-substitution-label)=
215+
196216
## Translation string substitution
197217

198218
Translation string substitutions must be used when the final translated message contains variable strings.
@@ -223,15 +243,15 @@ class SomeView(BrowserView):
223243
```
224244

225245

226-
(i18n-i18ndude-label)=
246+
(translating-text-strings-i18ndude-label)=
227247

228248
## `i18ndude`
229249

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.
231251

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.
233253

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.
235255

236256
In your `buildout.cfg` in the part using `plone.recipe.zope2instance`, you can set an environment variable for this.
237257

@@ -241,11 +261,15 @@ environment-vars =
241261
```
242262

243263
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.
245265

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.
247269

248270

271+
(translating-text-strings-installing-i18ndude-label)=
272+
249273
### Installing i18ndude
250274

251275
The recommended method is to have {term}`i18ndude` installed via your [buildout](https://www.buildout.org/en/latest/).
@@ -278,9 +302,11 @@ server:mfabrik.plonezohointegration moo$ ../../bin/i18ndude
278302
```
279303

280304

305+
(translating-text-strings-setting-up-folder-structure-for-finnish-and-english-label)=
306+
281307
### Setting up folder structure for Finnish and English
282308

283-
Example:
309+
Start by creating folders to hold the translation files.
284310

285311
```console
286312
mkdir locales
@@ -291,6 +317,8 @@ mkdir locales/en/LC_MESSAGES
291317
```
292318

293319

320+
(translating-text-strings-creating-.pot-base-file-label)=
321+
294322
### Creating `.pot` base file
295323

296324
Example:
@@ -300,7 +328,9 @@ i18ndude rebuild-pot --pot locales/mydomain.pot --create your.app.package .
300328
```
301329

302330

303-
### Manual `.po` entries
331+
(translating-text-strings-manual-.po-entries-label)=
332+
333+
### Manual PO entries
304334

305335
`i18ndude` scans source `.py` and `.pt` files for translatable text strings.
306336
On some occasions this is not enough, for example, when you dynamically generate message IDs in your code.
@@ -327,6 +357,8 @@ msgstr ""
327357
```
328358

329359

360+
(translating-text-strings-dynamic-content-label)=
361+
330362
## Dynamic content
331363

332364
If your HTML template has dynamic content similar to the following:
@@ -335,13 +367,13 @@ If your HTML template has dynamic content similar to the following:
335367
<h1 i18n:translate="search_form_heading">Search from <span tal:content="context/@@plone_portal_state/portal_title" /></h1>
336368
```
337369

338-
…then it will produce a `.po` entry like this:
370+
…then it will produce a PO entry like this:
339371

340372
```po
341373
msgstr "Hae sivustolta <span>${DYNAMIC_CONTENT}</span>"
342374
```
343375

344-
You need to give the name to the dynamic part so the po file can handle it like a variable:
376+
You need to give the name to the dynamic part so the PO file can handle it like a variable:
345377

346378
```html
347379
<h1 i18n:translate="search_form_heading">
@@ -365,9 +397,11 @@ https://web.archive.org/web/20131018150303/http://permalink.gmane.org/gmane.comp
365397
```
366398

367399

400+
(translating-text-strings-overriding-translations-label)=
401+
368402
## Overriding translations
369403

370-
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.
371405

372406
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.
373407
Then you can add your own translations in the language that you need.

0 commit comments

Comments
 (0)