Skip to content

Commit 7bf9b68

Browse files
authored
Merge branch '6-dev' into MrTango-views-templates
2 parents b247258 + 69f1cb5 commit 7bf9b68

23 files changed

+1214
-26
lines changed

.github/workflows/build_deploy.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ jobs:
2020
run: |
2121
python -m pip install --upgrade pip
2222
pip install -q -r requirements.txt
23+
pip freeze
2324
2425
# - name: Run spellcheck
2526
# run: make spellcheck
114 KB
Loading
117 KB
Loading

docs/glossary.md

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -480,5 +480,4 @@ interface
480480
```{seealso}
481481
See also https://zopeinterface.readthedocs.io/en/latest/.
482482
```
483-
484483
```
Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
---
2+
myst:
3+
html_meta:
4+
"description": "How to contribute to Plone core translations."
5+
"property=og:description": "How to contribute to Plone core translations."
6+
"property=og:title": "Contributing Plone Core Translations"
7+
"keywords": "Plone, Internationalization, i18n, language, translation, localization"
8+
---
9+
10+
(contributing-plone-core-translations-label)=
11+
12+
# Contributing Plone Core Translations
13+
14+
```{admonition} Description
15+
How to contribute to the Plone translations.
16+
```
17+
18+
This chapter of the documentation describes how to contribute to Plone's translations.
19+
Plone fully supports {term}`internationalization` and {term}`localization`.
20+
Plone Classic UI comes with 65 local language translations, and the new default frontend Volto comes with 12, at the time of this writing.
21+
However, some translations are incomplete, or certain languages have not yet been added.
22+
Translations can be added or updated as needed by the citizens of Earth.
23+
You will need to work in one repository for Plone core, and optionally another one for Volto.
24+
25+
26+
(contributing-plone-core-translations-pre-requisites-label)=
27+
28+
## Pre-requisites
29+
30+
Request write access to https://github.com/collective/plone.app.locales to be able to commit your translation directly.
31+
32+
To do so, [join the collective GitHub organization](https://collective.github.io/).
33+
34+
Optionally sign the [Plone Contributor Agreement](https://plone.org/foundation/contributors-agreement) for translating Volto.
35+
36+
37+
(contributing-plone-core-translations-translate-plone-classic-ui-label)=
38+
39+
## Translate Plone Classic UI
40+
41+
The process of translating Plone Classic UI is the following.
42+
43+
1. Go to https://github.com/collective/plone.app.locales and clone it into your computer.
44+
45+
2. Create a new branch to work on your translations.
46+
Name the branch with something identifiable.
47+
For example: `{language}-{date}` (`fr-20220731`).
48+
49+
3. Either update or create a translation.
50+
51+
- To _update_ an existing translation, translate the {term}`PO file`s under your language of choice at `plone/app/locales/locales/{language_code}/LC_MESSAGES/*.po`.
52+
In Classic UI, we have several language files because some of the original messages are spread over several language domains and products.
53+
- To _create_ a translation, create a new directory at `plone/app/locales/locales/{language_code}/LC_MESSAGES`, copy all the `.pot` files in `plone/app/locales/locales` to your new directory, rename the files in your directory by changing the file extension to `.po`, and start translating.
54+
55+
4. Commit your changes, and create a pull request with them.
56+
Request a review from a colleague, especially if you are translating a file that already has some translations.
57+
You can check the file's commit history with `git blame <filename>` to see previous contributors and request a review from them.
58+
This is to ensure coherent translations throughout Plone.
59+
60+
61+
(contributing-plone-core-translations-translate-volto-label)=
62+
63+
## Translate Volto
64+
65+
The process of translating the Volto frontend is the following.
66+
67+
1. Go to https://github.com/plone/volto and clone it into your computer.
68+
69+
2. Create a new branch to prepare the translations.
70+
Name the branch with something identifiable.
71+
For example: `{language}-{date}` (`fr-20220731`).
72+
73+
3. Either update or create a translation.
74+
75+
- To update a translation, translate your language's `po` file found at `locales/{language_code}/LC_MESSAGES/volto.po`.
76+
- To create a new translation, create a new directory at `locales/{language_code}/LC_MESSAGES/`, copy the file `locales/volto.pot` to `locales/{language_code}/LC_MESSAGES/volto.po` (note to drop the trailing `t`), and start translating.
77+
78+
4. Commit your changes, and create a pull request.
79+
80+
81+
(contributing-plone-core-translations-support-label)=
82+
83+
## Support
84+
85+
Please ask questions on the Plone Community Forum category [Translations and i18n/l10n](https://community.plone.org/c/development/i18nl10n/42).

docs/i18n-l10n/index.md

Lines changed: 152 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,152 @@
1+
---
2+
myst:
3+
html_meta:
4+
"description": "Internationalization (i18n) and localization (l10n) in Plone 6"
5+
"property=og:description": "Internationalization (i18n) and localization (l10n) in Plone 6"
6+
"property=og:title": "Internationalization (i18n) and localization (l10n) in Plone 6"
7+
"keywords": "Plone, Internationalization, i18n, language, translation, localization"
8+
---
9+
10+
(i18n-l10n-label)=
11+
12+
# Internationalization and Localization
13+
14+
{term}`Internationalization` is the process of preparing an application for displaying content in languages and formats specifically to the audience.
15+
Developers and template authors usually internationalize the application.
16+
"i18n" is shorthand for "internationalization" (the letter "I", a run of 18 letters, the letter "N").
17+
18+
{term}`Localization` is the process of writing the translations of text and local formats for an application that has already been internationalized.
19+
Formats include dates, times, numbers, time zones, units of measure, and currency.
20+
Translators usually localize the application.
21+
"l10n" is shorthand for "localization" (the letter "L", a run of 10 letters, the letter "N").
22+
23+
Plone fully supports internationalization and localization.
24+
25+
```{seealso}
26+
Wikipedia article [Internationalization and localization](https://en.wikipedia.org/wiki/Internationalization_and_localization)
27+
```
28+
29+
30+
(i18n-l10n-code-versus-content-label)=
31+
32+
## Code versus content
33+
34+
We categorize the things that we want to internationalize and localize in a Plone application into two groups:
35+
36+
1. **Code-level elements.**
37+
This includes translations of the user interface elements' text strings and localization.
38+
The tools used in this group include {term}`gettext`, Plone and Zope {term}`i18n` facilities, and {term}`react-intl`.
39+
See the chapter {doc}`translating-text-strings`.
40+
2. **User-generated content.**
41+
For translating user-generated content, Plone uses the package [`plone.app.multilingual`](https://pypi.org/project/plone.app.multilingual/).
42+
See the chapter {doc}`translating-content`.
43+
44+
45+
(i18n-l10n-common-concepts-label)=
46+
47+
## Common concepts
48+
49+
When you internationalize and localize a Plone application, there are some common concepts used throughout these processes.
50+
51+
52+
(i18n-l10n-terms-label)=
53+
54+
### Terms
55+
56+
The following terms are used in this documentation.
57+
58+
locale
59+
: A locale is an identifier, such as a {term}`language tag`, for a specific set of cultural preferences for some country, together with all associated translations targeted to the same native language.
60+
61+
language tag
62+
: A language tag is a string used as an identifier for a language.
63+
A language tag may have one or more subtags.
64+
The basic form of a language tag is `LANGUAGE-[SUBTAG]`.
65+
66+
```{seealso}
67+
- W3C article [Language tags in HTML and XML](https://www.w3.org/International/articles/language-tags/)
68+
- W3C Working Draft [Language Tags and Locale Identifiers for the World Wide Web](https://www.w3.org/TR/ltli/)
69+
```
70+
71+
`.po`
72+
: Portable Object (PO) file.
73+
The message file format used by the {term}`gettext` translation system.
74+
See https://www.gnu.org/savannah-checkouts/gnu/gettext/manual/html_node/PO-Files.html.
75+
76+
`.pot`
77+
: Portable Object (PO) template file, not yet oriented towards any particular language.
78+
79+
`.mo`
80+
: Machine Object file.
81+
The binary message file compiled from the {term}`.po` message file.
82+
83+
84+
(i18n-l10n-locale-and-language-tag-conventions-label)=
85+
86+
### Locale and language tag conventions
87+
88+
Plone uses certain conventions for its locales and language tags.
89+
90+
- When identifying a language only, use two lowercase letters.
91+
Examples: `en`, `de`.
92+
- When identifying a language and a country, use two lowercase letters, an underscore (`_`), and two uppercase letters.
93+
Examples: `en_GB`, `pt_BR`.
94+
- When identifying a language and script or character set, use two lowercase letters, an at sign (`@`), and four title case letters.
95+
Example: `sr@Cyrl`.
96+
97+
98+
(i18n-l10n-general-procedure-label)=
99+
100+
### General procedure
101+
102+
```{note}
103+
This section concerns only *code-level* translations of text strings.
104+
105+
For *user-generated content* translations, see {doc}`translating-content`.
106+
```
107+
108+
In general, the process of internationalization and localization of a Plone application follows these steps.
109+
110+
1. Create translatable strings in your code.
111+
Plone has already done this step within its core code.
112+
However, when developing new features or add-ons, you will need to perform this step.
113+
2. Find and extract all translatable strings from your code with a script, and create a `.pot` template file out of all these.
114+
3. Create the `.po` files for all locales.
115+
4. Edit the `.po` files, adding the translated messages into them.
116+
5. Turn the `.po` files into `.mo` files.
117+
6. Compile and link the `.mo` files with the gettext library.
118+
119+
```{seealso}
120+
[Overview of GNU `gettext`](https://www.gnu.org/software/gettext/manual/html_node/Overview.html)
121+
```
122+
123+
124+
(i18n-l10n-implementation-details-label)=
125+
126+
## Implementation details
127+
128+
Depending on which part of your Plone application that you internationalize and localize, there are different implementation details and tools that are used.
129+
These differences depend upon the programming language, either Python or JavaScript, being used by that part.
130+
131+
- For the Plone 6 frontend {term}`Volto`, see {doc}`/volto/recipes/i18n`.
132+
Volto is based on the JavaScript library React, and uses both {term}`react-intl` and {term}`gettext`.
133+
- For the rest of Plone 6, see {doc}`translating-text-strings`.
134+
This is based on Python, and uses {term}`gettext`.
135+
- For user-generated content translations, see {doc}`translating-content`.
136+
137+
138+
139+
(i18n-l10n-contents-label)=
140+
141+
## Contents
142+
143+
```{toctree}
144+
:maxdepth: 1
145+
146+
translating-text-strings
147+
language-negotiation
148+
translating-content
149+
contributing-translations
150+
resync-translations
151+
```
152+
Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
---
2+
myst:
3+
html_meta:
4+
"description": "Accessing and changing the language state of Plone programmatically."
5+
"property=og:description": "Accessing and changing the language state of Plone programmatically."
6+
"property=og:title": "Language negotiation"
7+
"keywords": "Plone, Internationalization, i18n, language, negotiation, translation, localization"
8+
---
9+
10+
(language-negotiation-label)=
11+
12+
# Language negotiation
13+
14+
```{todo}
15+
This section may contain incorrect information.
16+
If you find errors, please submit a pull request to correct them.
17+
```
18+
19+
Language negotiation is a function of the HTTP protocol.
20+
It lets a server choose among several language versions of a page based on the URL and preference information sent by the browser.
21+
22+
Plone uses specific rules to select the language in which the user interface is presented to the end user.
23+
There are two distinct use cases: when `plone.app.multilingual` is not enabled and when it is.
24+
25+
26+
(language-negotiation-plone.app.multilingual-is-not-enabled-label)=
27+
28+
## `plone.app.multilingual` is not enabled
29+
30+
When `plone.app.multilingual` is not installed, but the site administrator configures multiple languages in Plone, Plone only allows changing the language of the user interface.
31+
This means that the language chooser links on the top of the page will only have effect for the user interface elements presented to the user.
32+
These user interface elements may include search form options, editing interface messages, portal message statuses, and so on.
33+
34+
By visiting the URI `@@language-controlpanel` ({guilabel}`Site Setup > General > Language`), the site administrator may configure language options for the site.
35+
36+
```{image} /_static/i18n-l10n/language-controlpanel-general.png
37+
:alt: Language Control Panel, General
38+
```
39+
40+
```{todo}
41+
Should we document all the options?
42+
Currently this is incomplete.
43+
```
44+
45+
```{todo}
46+
The next sentence might not be true.
47+
When I toggled it, nothing changed.
48+
Does it actually do anything?
49+
```
50+
51+
By default, the {guilabel}`Always show language selector` option is not enabled, but it is required if the user wants to offer the language change in the interface.
52+
53+
By selecting the {guilabel}`Negotiation scheme` tab, the site administrator can configure how Plone will select a language to present to each user.
54+
55+
```{image} /_static/i18n-l10n/language-controlpanel-negotiation-scheme.png
56+
:alt: Language Control Panel, Negotiation scheme
57+
```
58+
59+
For instance, if the site is being presented in a sub-folder (`www.domain.com/en`) or in a subdomain (`en.domain.com`), with either example using a language code such as `en`, then Plone can be configured to take that sub-folder or subdomain as the language code, and select that language to present to the user.
60+
61+
Another common configuration is to use the browser language request negotiation.
62+
This means that Plone relies on the `Accept-Language` HTTP header sent by the user's browser.
63+
The user can configure the list of languages to use in their preferred order, such as in German (de), French (fr), and English (en).
64+
In this scenario, Plone will compare its language list with the user's preferences, and will determine in which language to present the site.
65+
66+
The exact working of each of the negotiation options is implemented in the class [`LanguageUtility`](https://github.com/plone/plone.i18n/blob/fc05eb4c131574fd8a4353d5346e17866b3a5e2c/plone/i18n/utility.py#L73) in the module `utility.py` in the package `plone/plone.i18n`.
67+
68+
Plone also sets a cookie with the language preference of the user.
69+
This cookie is called `I18N_LANGUAGE`.
70+
It must be declared as a "technical cookie".
71+
It is a session cookie, which means that it will be deleted after the user leaves the site.
72+
To obey the cookie the setting, {guilabel}`Use cookie for manual override` should be set along with {guilabel}`Set the language cookie always`.
73+
74+
Building websites with user interfaces in multiple languages is complicated due to the different expectations of the users and the difficulty of the configuration.
75+
76+
As we will see in the (translating-content-label)= section, Plone will set a special view for the Plone root object called `@@language-switcher` whose implementation lies on `plone.app.multilingual.browser.switcher.LanguageSwitcher`. This language switcher will only rely on the user preferred language to decide where to send the user when she visits the root of the site.
77+
78+
(language-negotiation-plone.app.multilingual-is-enabled-label)=
79+
80+
## `plone.app.multilingual` is enabled
81+
82+
When `plone.app.multilingual` is enabled, Plone creates the `Language Root Folder`s (LRFs) for each of the languages.
83+
Thus, the language negotiation only applies for the users visiting the root domain of the site.
84+
85+
For example, if `en` and `es` are enabled, Plone will create `www.domain.com/en` and `www.domain.com/es`.
86+
Plone will assume that all the content below `en` is in English, and all content below `es` is in Spanish.
87+
It will rely on that assumption to present the user interface in those languages when the user is browsing those parts of the site.
88+
89+
As we will see in the {ref}`translating-content-label` chapter, Plone will set a special view for the Plone root object called `@@language-switcher` whose implementation relies on `plone.app.multilngual.browser.switcher.LanguageSwitcher`.
90+
This language switcher will only rely on the user preferred language to decide where to send the user when they visit the root of the site.
91+
92+
An integrator may want to modify this behavior to always send a user to a given language, or to negotiate the language selection in some other way, such as using the domain, a cookie, or some other techniques.
93+
As such, there are two options.
94+
95+
- They may override the `@@language-switcher` view.
96+
- They may write their own view, and configure the ZMI.
97+
To configure the ZMI, visit `www.domain.com/portal_types/Plone%20Site/manage_propertiesForm` or navigate there as an Admin user, {guilabel}`username > Site Setup`, {guilabel}`Advanced > Management Interface`, {guilabel}`portal_types`, and finally {guilabel}`Plone Site`.
98+
Set the value of `Default view method` to the name of the view.

0 commit comments

Comments
 (0)