Skip to content

Commit

Permalink
Merge pull request plone#1528 from plone/erral-language-redirect-docu…
Browse files Browse the repository at this point in the history
…mentation

document how to override the language negotiation/redirect
  • Loading branch information
stevepiercy authored Oct 5, 2023
2 parents 17967e5 + 0e5b94f commit a43cecc
Show file tree
Hide file tree
Showing 3 changed files with 59 additions and 9 deletions.
3 changes: 2 additions & 1 deletion docs/i18n-l10n/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ language tag
: A language tag is a string used as an identifier for a language.
A language tag may have one or more subtags.
The basic form of a language tag is `LANGUAGE-[SUBTAG]`.

```{seealso}
- W3C article [Language tags in HTML and XML](https://www.w3.org/International/articles/language-tags/)
- W3C Working Draft [Language Tags and Locale Identifiers for the World Wide Web](https://www.w3.org/TR/ltli/)
Expand Down Expand Up @@ -145,6 +145,7 @@ These differences depend upon the programming language, either Python or JavaScr
translating-text-strings
language-negotiation
language-negotiation-volto
translating-content
contributing-translations
resync-translations
Expand Down
34 changes: 34 additions & 0 deletions docs/i18n-l10n/language-negotiation-volto.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
---
myst:
html_meta:
"description": "Accessing and changing the language state of Plone programmatically."
"property=og:description": "Accessing and changing the language state of Plone programmatically."
"property=og:title": "Language negotiation in Volto"
"keywords": "Plone, Internationalization, i18n, language, negotiation, translation, localization, volto"
---

(language-negotiation-volto-label)=

# Language negotiation in Volto

Volto does not rely on the configuration set in Plone's Language Control Panel to handle the redirection from the root of the site to the Language Root Folder.

Volto has a setting in its own configuration stating whether a site is multilingual or not: `isMultilingual`.

First of all, you need to set that setting to `true`.

Then you need to add the list of supported languages to the `supportedLanguages` setting, and match them with the languages configured in Plone's Language Control Panel.

As a last thing, you need to set your site's `defaultLanguage` to one of the `supportedLanguages`.

When all these settings are configured, Volto's [`MultilingualRedirector`](https://github.com/plone/volto/blob/main/src/components/theme/MultilingualRedirector/MultilingualRedirector.jsx) will handle the language negotiation and the redirect.

In its configuration, the component tries to match the `I18N_LANGUAGE` cookie set in the user's browser with the list of supported languages, and if the match does not succeed, it selects the default language configured in Volto.

After that it does the redirection to the matched Language Root Folder.

If the site is not configured to be multilingual, Volto doesn't do any redirect.

## Overriding the default behavior

To do so, you need to provide your own `MultilingualRedirector` component {doc}`customizing it </volto/recipes/customizing-components>`.
31 changes: 23 additions & 8 deletions docs/i18n-l10n/language-negotiation.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,13 @@ myst:
html_meta:
"description": "Accessing and changing the language state of Plone programmatically."
"property=og:description": "Accessing and changing the language state of Plone programmatically."
"property=og:title": "Language negotiation"
"property=og:title": "Language negotiation in Classic UI"
"keywords": "Plone, Internationalization, i18n, language, negotiation, translation, localization"
---

(language-negotiation-label)=

# Language negotiation
# Language negotiation in Classic UI

```{todo}
This section may contain incorrect information.
Expand All @@ -19,7 +19,7 @@ If you find errors, please submit a pull request to correct them.
Language negotiation is a function of the HTTP protocol.
It lets a server choose among several language versions of a page based on the URL and preference information sent by the browser.

Plone uses specific rules to select the language in which the user interface is presented to the end user.
Plone Classic UI uses specific rules to select the language in which the user interface is presented to the end user.
There are two distinct use cases: when `plone.app.multilingual` is not enabled and when it is.


Expand Down Expand Up @@ -60,7 +60,7 @@ For instance, if the site is being presented in a sub-folder (`www.domain.com/en

Another common configuration is to use the browser language request negotiation.
This means that Plone relies on the `Accept-Language` HTTP header sent by the user's browser.
The user can configure the list of languages to use in their preferred order, such as in German (de), French (fr), and English (en).
The user can configure the list of languages to use in their preferred order, such as German (de), French (fr), and English (en).
In this scenario, Plone will compare its language list with the user's preferences, and will determine in which language to present the site.

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`.
Expand All @@ -69,11 +69,13 @@ Plone also sets a cookie with the language preference of the user.
This cookie is called `I18N_LANGUAGE`.
It must be declared as a "technical cookie".
It is a session cookie, which means that it will be deleted after the user leaves the site.
To obey the cookie the setting, {guilabel}`Use cookie for manual override` should be set along with {guilabel}`Set the language cookie always`.
To obey the cookie setting, {guilabel}`Use cookie for manual override` should be set along with {guilabel}`Set the language cookie always`.

Building websites with user interfaces in multiple languages is complicated due to the different expectations of the users and the difficulty of the configuration.

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.
As we will see in the {doc}`translating-content` chapter, Plone will set a special view for the Plone root object called `@@language-switcher` whose implementation relies 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 they visit the root of the site.


(language-negotiation-plone.app.multilingual-is-enabled-label)=

Expand All @@ -86,13 +88,26 @@ For example, if `en` and `es` are enabled, Plone will create `www.domain.com/en`
Plone will assume that all the content below `en` is in English, and all content below `es` is in Spanish.
It will rely on that assumption to present the user interface in those languages when the user is browsing those parts of the site.

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`.
As we will see in the {doc}`translating-content` chapter, Plone will set a special view for the Plone root object called `@@language-switcher` whose implementation relies 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 they visit the root of the site.

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.
As such, there are two options.

- They may override the `@@language-switcher` view.
- They may write their own view, and configure the ZMI.
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`.
Set the value of `Default view method` to the name of the view.


## Changing the default behavior

If for any reason you want to change the default behavior set when using `plone.app.multilingual`, you have two options.

1. Override the `language-switcher` view.
Plone has a view called `language-switcher` defined in [plone.app.multilingual.browser.switcher.py](https://github.com/plone/plone.app.multilingual/blob/master/src/plone/app/multilingual/browser/switcher.py) which handles the redirection from the root of the Plone site to the proper Language Root Folder.
You can override this view using the usual techniques to provide your own implementation.

1. Create a new view.
You can create your own view with your own implementation, configure it properly, and then set it as a `default view` for `Plone Site` objects.
To do so, you may need to provide your own installation profile with a {file}`Plone Site.xml` file and with the proper configuration.

0 comments on commit a43cecc

Please sign in to comment.