Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
bc25c97
document the changes in p.a.multilingual
erral Dec 12, 2025
b28bfa7
Update docs/backend/upgrading/version-specific-migration/upgrade-to-6…
erral Dec 14, 2025
b175c75
Update docs/backend/upgrading/version-specific-migration/upgrade-to-6…
erral Dec 14, 2025
e159ccf
Update docs/backend/upgrading/version-specific-migration/upgrade-to-6…
erral Dec 14, 2025
22e7fb1
Update docs/backend/upgrading/version-specific-migration/upgrade-to-6…
erral Dec 14, 2025
ba77dab
Update docs/i18n-l10n/use-an-external-translation-service.md
erral Dec 14, 2025
ff1775f
Update docs/i18n-l10n/use-an-external-translation-service.md
erral Dec 14, 2025
a77be2d
Update docs/i18n-l10n/use-an-external-translation-service.md
erral Dec 14, 2025
24350bb
Update docs/i18n-l10n/use-an-external-translation-service.md
erral Dec 14, 2025
d88c421
Update docs/i18n-l10n/use-an-external-translation-service.md
erral Dec 14, 2025
e584a8d
Merge branch '6.0' into erral-external-translations
erral Dec 14, 2025
a67f76f
Update docs/i18n-l10n/use-an-external-translation-service.md
erral Dec 14, 2025
b0c8c6a
Apply suggestions from code review
erral Dec 14, 2025
97e2756
rename file
erral Dec 15, 2025
bfa3a57
add upgrade guide to the toctree
erral Dec 15, 2025
f9d10a6
Update docs/backend/upgrading/version-specific-migration/upgrade-to-6…
erral Dec 15, 2025
9fff06e
Update docs/backend/upgrading/version-specific-migration/upgrade-to-6…
stevepiercy Dec 15, 2025
472a56c
Apply suggestions from code review
erral Dec 15, 2025
39cbfaa
Update docs/backend/upgrading/version-specific-migration/upgrade-to-6…
stevepiercy Dec 15, 2025
25a7bf4
Add translate.svg icon, assuming it's correct
stevepiercy Dec 15, 2025
6afb984
Update docs/i18n-l10n/use-an-external-translation-service.md
erral Dec 15, 2025
7b61aa9
Update docs/i18n-l10n/use-an-external-translation-service.md
stevepiercy Dec 15, 2025
3b0f87b
Update docs/i18n-l10n/use-an-external-translation-service.md
stevepiercy Dec 15, 2025
10239d3
Merge branch '6.0' into erral-external-translations
stevepiercy Dec 16, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions docs/_static/translate.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions docs/backend/upgrading/version-specific-migration/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,5 +27,6 @@ upgrade-to-python3
upgrade-zodb-to-python3
upgrade-to-60
upgrade-to-61
upgrade-to-62
migrate-to-volto
```
36 changes: 36 additions & 0 deletions docs/backend/upgrading/version-specific-migration/upgrade-to-62.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
---
myst:
html_meta:
"description": "How to upgrade to Plone 6.2"
"property=og:description": "How to upgrade to Plone 6.2"
"property=og:title": "How to upgrade to Plone 6.2"
"keywords": "Upgrade, Plone 6"
---

(backend-upgrade-plone-v62-label)=

# Upgrade Plone 6.1 to 6.2

Plone 6.2 has seen the following major changes.
Some may require changes in your setup.


## Replaced Google Translate integration with generic translation integration

`plone.app.multilingual` had an integration to use only Google Translate to translate the content in the `babel_view`, where the content in two languages is shown side-by-side.
This integration was limited to only Google Translate.
In Plone 6.2, this integration has been replaced with a generic translation service integration hook.

[`collective.translators`](https://github.com/collective/collective.translators) provides some implementations for that hook, supporting AWS, Deepl, Deepseek, Google Translate, Libre Translate, and Ollama.
It can be extended to support more translation providers.

It is not mandatory to use `collective.translator`.
Any developer can write the integration with the tool of their choice.

See the {doc}`/i18n-l10n/use-an-external-translation-service` chapter for details.

To achieve that integration, the previously existing `gtranslation_service` browser view has been removed from `plone.app.multilingual`.

Due to not needing it anymore, the `plone.google_translation_key` registry entry has been removed, and it will be removed when performing the upgrade step to Plone 6.2.

The `babel_view` has been modified to call a new REST API endpoint instead of the old `gtranslation_service` browser view.
106 changes: 30 additions & 76 deletions docs/i18n-l10n/use-an-external-translation-service.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,88 +14,42 @@ myst:
When translating content items in Plone, you can connect to an external translation service to translate your content.


## Using Google Cloud Translation API
The `plone.app.multilingual` product that turns Plone into a multilingual content site supports a pluggable way to hook any translation service into Plone.

The `plone.app.multilingual` product that turns Plone into a multilingual-content site supports [Google Cloud Translation API](https://docs.cloud.google.com/translate/docs/reference/rest), which allows the content editor to use its translations.
To do so, one has to implement a utility that implements an `IExternalTranslationService` interface.

To use this service as a site administrator, you need to create a project in Google Cloud, enable the Cloud Translation API, and create an API key under the Credentials of the Google Cloud Console.
You should enter this API key in the {guilabel}`Multilingual Settings` control panel in Plone.
This utility class must implement the `IExternalTranslationService` interface from `plone.app.multilingual.interfaces` and it should provide at least these methods and an attribute:

After doing so, as a content editor, when you edit a translation of a given content page, an icon will display next to the original content.
When you click this icon, it invokes the Google Cloud Translation API, and the translation obtained through the service will be entered automatically in the corresponding field.
`is_available()`
: Returns `True` if the service is enabled and ready.

```{note}
The usage of Google Cloud Translation API may create extra cost for the site administrator.
See [Cloud Translation pricing](https://cloud.google.com/translate/pricing) for details.
```
`available_languages()`
: Returns a list of supported language codes or pairs that can be used (source, target).

`translate_content(content, source_language, target_language)`
: Performs the translation and returns the translated text.

## Using other translation services

If you want to use another service beside Google Cloud Translation API, you will need to override the view that calls Google Cloud Translation API.

To do so, `plone.app.multilingual` registers a view called `gtranslation_service`.
Its code is in [`plone.app.multilingual.brwoser.translate.gtranslation_service_dexterity`](https://github.com/plone/plone.app.multilingual/blob/7aedd0ab71d3edf5d1fb4cb86b9f611d428ed76b/src/plone/app/multilingual/browser/translate.py#L52).
This view gets three parameters:

`context_uid`
: The UID of the object to be translated.

`field`
: The name of the field of the object that needs to be translated.
This view's job is to extract the value of that field from the object.

`lang_source`
: The source language code.

The first part of the view—that which gets the object and the field content to be translated—can be copied from the original code.
You need to write only the call to the translation service.
The required code would be something like the following example:

```python
class TranslateUsingMyService(BrowserView):
def __call__(self):
if self.request.method != "POST" and not (
"field" in self.request.form.keys()
and "lang_source" in self.request.form.keys()
):
return _("Need a field")
else:
manager = ITranslationManager(self.context)
context_uid = self.request.form.get("context_uid", None)
if context_uid is None:
# try with context if no translation uid is present
manager = ITranslationManager(self.context)
else:
catalog = getToolByName(self.context, "portal_catalog")
brains = catalog(UID=context_uid)
if len(brains):
context = brains[0].getObject()
manager = ITranslationManager(context)
else:
manager = ITranslationManager(self.context)

registry = getUtility(IRegistry)
settings = registry.forInterface(
IMultiLanguageExtraOptionsSchema, prefix="plone"
)
lang_target = ILanguage(self.context).get_language()
lang_source = self.request.form["lang_source"]
orig_object = manager.get_translation(lang_source)
field = self.request.form["field"].split(".")[-1]
if hasattr(orig_object, field):
question = getattr(orig_object, field, "")
if hasattr(question, "raw"):
question = question.raw
else:
return _("Invalid field")

# And here do the call to the external translation service
return call_to_my_service(question, lang_target, lang_source)
```
`order`
: The order in which this utility will be executed.
This way, one can prioritize some services over others with given conditions.

After doing so, as a content editor, when you edit a translation of a given content page, a translate icon <img alt="Translate icon" src="../_static/translate.svg" class="inline"> will display next to the original content.

When you click this icon, it will invoke the translation utility, and the translation obtained through the service will be entered automatically in the corresponding field.

Plone does not implement this interface by itself in any of its utilities.

You'll need to use an external package that offers this service as described in {ref}`pre-configured-services-label`, or create your own utility.

(pre-configured-services-label)=

## Using the translation service with pre-configured services

To use some external tools, the Plone community has implemented a package called [`collective.translators`](https://github.com/collective/collective.translators) that implements this functionality for AWS, Deepl, Deepseek, Google Translate, Libre Translate, and Ollama.

Each of those services provides a control panel to tweak the configuration, including API keys, languages, service endpoints, and other configuration items.

```{note}
Due to the way that the Google Translate integration is built in `plone.app.multilingual`, you will need to enter something in the {guilabel}`Google Translate API Key` field in the {guilabel}`Multilingual Settings`
control panel of your site.
It doesn't need to be a valid Google Translate API Key; it can be a random string.
The usage of some of those services may create extra cost for the site administrator.
Check the terms of use of each of the tools for details.
```