зеркало из https://github.com/mozilla/bedrock.git
Add wagtail-localize-smartling to the project, for Smartling L10N support (#14794)
* Add wagtail-localize-smartling to the project, for Smartling L10N support
* Add docs for wagtail-localize-smartling
* Minor reformatting
* Fix duplicated env var reference 🤦
* Add a management command that wraps the sync_smartling command so we can monitor it with a DMS
This commit is contained in:
Родитель
5fd5d4f524
Коммит
1829904358
|
@ -0,0 +1,34 @@
|
|||
# This Source Code Form is subject to the terms of the Mozilla Public
|
||||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
# file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
|
||||
|
||||
import sys
|
||||
|
||||
from django.core.management import call_command
|
||||
from django.core.management.base import BaseCommand
|
||||
|
||||
import requests
|
||||
|
||||
from bedrock.base.config_manager import config
|
||||
|
||||
|
||||
class Command(BaseCommand):
|
||||
help = """Wraps the sync_smartling management command from
|
||||
wagtail-localize-smartling so that we can monitor its
|
||||
operation via a Dead Man's Snitch"""
|
||||
|
||||
def handle(self, *args, **kwargs):
|
||||
SMARTLING_SYNC_SNITCH_URL = config("SMARTLING_SYNC_SNITCH_URL", default="")
|
||||
|
||||
try:
|
||||
call_command("sync_smartling")
|
||||
|
||||
sys.stdout.write(
|
||||
"\nsync_smartling executed successfully\n",
|
||||
)
|
||||
if SMARTLING_SYNC_SNITCH_URL:
|
||||
requests.get(SMARTLING_SYNC_SNITCH_URL)
|
||||
sys.stdout.write("Snitch pinged\n")
|
||||
except Exception as ex:
|
||||
sys.stderr.write(f"\nsync_smartling did not execute successfully: {ex}\n")
|
|
@ -749,6 +749,7 @@ INSTALLED_APPS = [
|
|||
"wagtail.users",
|
||||
"wagtail.snippets",
|
||||
"wagtail.images",
|
||||
"wagtail_localize_smartling", # Has to come before wagtail_localize
|
||||
"wagtail_localize",
|
||||
"wagtail_localize.locales", # This replaces "wagtail.locales"
|
||||
"wagtail.search",
|
||||
|
@ -2122,6 +2123,29 @@ else:
|
|||
# Wagtailed, but we need something valid so Pocket mode will boot up
|
||||
WAGTAIL_CONTENT_LANGUAGES = [("en", "English")]
|
||||
|
||||
# Settings for https://github.com/mozilla/wagtail-localize-smartling
|
||||
WAGTAIL_LOCALIZE_SMARTLING = {
|
||||
# Required settings (get these from "Account settings" > "API" in the Smartling dashboard)
|
||||
"PROJECT_ID": config("WAGTAIL_LOCALIZE_SMARTLING_PROJECT_ID", default="setme"),
|
||||
"USER_IDENTIFIER": config("WAGTAIL_LOCALIZE_SMARTLING_USER_IDENTIFIER", default="setme"),
|
||||
"USER_SECRET": config("WAGTAIL_LOCALIZE_SMARTLING_USER_SECRET", default="setme"),
|
||||
# Optional settings and their default values
|
||||
"REQUIRED": config(
|
||||
"WAGTAIL_LOCALIZE_SMARTLING_ALWAYS_SEND",
|
||||
default="False",
|
||||
parser=bool,
|
||||
), # Set this to True to always send translations to Smartling
|
||||
"ENVIRONMENT": config(
|
||||
"WAGTAIL_LOCALIZE_SMARTLING_ENVIRONMENT",
|
||||
default="production",
|
||||
), # Set this to "staging" to use Smartling's staging API
|
||||
"API_TIMEOUT_SECONDS": config(
|
||||
"WAGTAIL_LOCALIZE_SMARTLING_API_TIMEOUT_SECONDS",
|
||||
default="5",
|
||||
parser=float,
|
||||
), # Timeout in seconds for requests to the Smartling API
|
||||
}
|
||||
|
||||
# Custom settings, not a core Wagtail ones, to scope out RichText options
|
||||
WAGTAIL_RICHEXT_FEATURES_FULL = [
|
||||
# https://docs.wagtail.org/en/stable/advanced_topics/customisation/page_editing_interface.html#limiting-features-in-a-rich-text-field
|
||||
|
|
67
docs/cms.rst
67
docs/cms.rst
|
@ -415,6 +415,68 @@ This approach will not be a problem if we stick to image filter-specs from the
|
|||
'approved' list. Note that extending the list of filter-specs is possible, if
|
||||
we need to.
|
||||
|
||||
L10N and Translation Management
|
||||
-------------------------------
|
||||
|
||||
.. important::
|
||||
|
||||
Localization via Wagtail is something we are ramping up on, so please
|
||||
do not assume the following notes are final, or that the workflows are
|
||||
currently all rock-solid. We're learning as we go.
|
||||
|
||||
Page-tree concept
|
||||
=================
|
||||
|
||||
Our Wagtail setup uses the official `wagtail-localize`_ package to manage
|
||||
localization of pages.
|
||||
|
||||
This package supports page-level localization rather than field-level localization, which means that each locale has its own distinct tree of pages, rather than each page having a stack of duplicate fields, one per destination language.
|
||||
|
||||
These language-specific trees can be "synchronised" with the default ``en-US`` page tree, so would have the same page structure, field by field) — or they can not be synchronised, so can have their own extra pages, or some specific pages in the tree can be made not "synchronised", while others are.
|
||||
|
||||
Basically, there is plenty of flexibility. The flipside of that flexibility is we may also create an edge-case situation that ``wagtail-localize`` won't work with, but we'll have to see and deal with it.
|
||||
|
||||
.. note::
|
||||
|
||||
It's worth investing 15 mins in watching the `Wagtail Localize original demo`_ to get a good feel of how it can work.
|
||||
|
||||
Localization process
|
||||
====================
|
||||
|
||||
Manual updates
|
||||
~~~~~~~~~~~~~~
|
||||
|
||||
At its most basic, there's nothing stopping us using copy-and-paste to enter translations into lang-specific pages, which might work well if we have a page in just one non-en-US lang and an in-house colleague doing the translation.
|
||||
|
||||
Automated via Smartling
|
||||
~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
However, we also have automation available to send source strings to translation vendor Smartling. This uses the ``wagtail-localize-smartling`` package.
|
||||
|
||||
Here's the workflow:
|
||||
|
||||
1. CMS page "MyPage" is created in the default lang (``en-US``)
|
||||
2. The "Translate this page" option is triggered for MyPage, and relevant langs are selected from the configured langs that Smartling supports. (We don't have to translate into all of them)
|
||||
3. A translation Job is created in Smartling, awaiting authorization by our L10N team
|
||||
4. A L10N team colleague authorizes the Job and selects the relevant translation workflow(s) for the relevant lang(s)
|
||||
5. Once the jobs are completed, the localised strings flow back to Wagtail and populate a draft version of each language-specific page
|
||||
6. A human reviews these draft pages and publishes them
|
||||
|
||||
**Notes:**
|
||||
|
||||
* Smartling/``wagtail-localize-smartling`` will only translate pages from the base lang (``en-US``) to another lang - it won't treat, say, a Page in ``fr`` as a source-language document.
|
||||
* If a string is received from Smartling into the CMS and then manually edited on the CMS side, the change will `not` be overwritten by subsequent Smartling syncs and the manual edit needs to be added on the Smartling side for consistency and stability.
|
||||
* If a page is translated from ``en-US`` once, then has new ``en-US`` content added that is sent for translation, that will trigger a new Smartling Job. When that job is complete, it `will` overwrite any manual edits made to a translation within the CMS. This is why it's important to make sure Smartling contains any manual tweaks done to translations in the CMS.
|
||||
|
||||
|
||||
Automated via Pontoon
|
||||
~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
It should also be possible to use `Pontoon`_ with `wagtail-localize`. (There are notes on the `Pontoon integration`_ here, but we have not yet tried to enable this alongside `wagtail-localize-smartling`).
|
||||
|
||||
Additionally using Pontoon would let us benefit from community translations across a broad range of languages. However, we have yet to try to set this up and would need to agree which parts of the site do and do not use Pontoon.
|
||||
|
||||
|
||||
Infrastructure notes
|
||||
====================
|
||||
|
||||
|
@ -451,3 +513,8 @@ admin user in your local build.
|
|||
.. _Custom Block types: https://docs.wagtail.org/en/stable/advanced_topics/customisation/streamfield_blocks.html#custom-streamfield-blocks
|
||||
.. _Django migrations docs: https://docs.djangoproject.com/en/4.2/topics/migrations/
|
||||
.. _Squashing migrations: https://docs.djangoproject.com/en/4.2/topics/migrations/
|
||||
.. _wagtail-localize: https://wagtail-localize.org/
|
||||
.. _wagtail-localize-smartling: https://github.com/mozilla/wagtail-localize-smartling
|
||||
.. _Pontoon: https://pontoon.mozilla.org/
|
||||
.. _Pontoon integration: https://wagtail-localize.org/stable/how-to/integrations/pontoon/
|
||||
.. _Wagtail Localize original demo: https://www.youtube.com/watch?v=mEzQcOMUzoc
|
||||
|
|
|
@ -478,6 +478,7 @@ django==4.2.14 \
|
|||
# mozilla-django-oidc
|
||||
# wagtail
|
||||
# wagtail-localize
|
||||
# wagtail-localize-smartling
|
||||
django-allow-cidr==0.7.1 \
|
||||
--hash=sha256:11126c5bb9df3a61ff9d97304856ba7e5b26d46c6d456709a6d9e28483bff47f \
|
||||
--hash=sha256:382c5d7a9807279e3e96e4f4892b59163a2b30128c596902bf5f80e133e1ccbb
|
||||
|
@ -567,6 +568,7 @@ djangorestframework==3.15.2 \
|
|||
# via
|
||||
# -r requirements/prod.txt
|
||||
# wagtail
|
||||
# wagtail-localize-smartling
|
||||
docutils==0.21.2 \
|
||||
--hash=sha256:3a6b18732edf182daa3cd12775bbb338cf5691468f91eeeb109deff6ebfa986f \
|
||||
--hash=sha256:dafca5b9e384f0e419294eb4d2ff9fa826435bf15f15b7bd45723e8ad76811b2
|
||||
|
@ -1885,6 +1887,7 @@ requests==2.32.3 \
|
|||
# pytest-selenium
|
||||
# responses
|
||||
# wagtail
|
||||
# wagtail-localize-smartling
|
||||
responses==0.25.0 \
|
||||
--hash=sha256:01ae6a02b4f34e39bffceb0fc6786b67a25eae919c6368d05eabc8d9576c2a66 \
|
||||
--hash=sha256:2f0b9c2b6437db4b528619a77e5d565e4ec2a9532162ac1a131a83529db7be1a
|
||||
|
@ -2209,6 +2212,7 @@ wagtail==6.1.3 \
|
|||
# -r requirements/prod.txt
|
||||
# wagtail-factories
|
||||
# wagtail-localize
|
||||
# wagtail-localize-smartling
|
||||
wagtail-factories==4.2.1 \
|
||||
--hash=sha256:7a180fc1b074af7a78648c634740ee89d4dbb45899917744b66431d38155b6ae \
|
||||
--hash=sha256:bfe158092982a2b30a3e603c482242905df0b163fc69573fa6f159df482175c5
|
||||
|
@ -2216,6 +2220,12 @@ wagtail-factories==4.2.1 \
|
|||
wagtail-localize==1.9 \
|
||||
--hash=sha256:a680fc33c17145e6726f03a57b2ec465405847ae7cb77943ecc0e56463ad68c7 \
|
||||
--hash=sha256:f4fa9c36d8dbab5c27d1b675ed6fd7b9e8f012cf4bb308464168de7ebbad8324
|
||||
# via
|
||||
# -r requirements/prod.txt
|
||||
# wagtail-localize-smartling
|
||||
wagtail-localize-smartling==0.2.3 \
|
||||
--hash=sha256:0701444976c6b5392616d5dcdbf202fdce730b591e9d6794efee99c613107dc5 \
|
||||
--hash=sha256:6bef31958c24229a663b81b889879c845bed021dde0eba44a9527eb45e6cf3ed
|
||||
# via -r requirements/prod.txt
|
||||
wcwidth==0.2.13 \
|
||||
--hash=sha256:3da69048e4540d84af32131829ff948f1e022c1c6bdb8d6102117aac784f6859 \
|
||||
|
|
|
@ -57,3 +57,4 @@ timeago==1.0.16
|
|||
whitenoise==6.7.0
|
||||
Wagtail==6.1.3
|
||||
wagtail-localize==1.9
|
||||
wagtail-localize-smartling==0.2.3
|
||||
|
|
|
@ -325,6 +325,7 @@ django==4.2.14 \
|
|||
# mozilla-django-oidc
|
||||
# wagtail
|
||||
# wagtail-localize
|
||||
# wagtail-localize-smartling
|
||||
django-allow-cidr==0.7.1 \
|
||||
--hash=sha256:11126c5bb9df3a61ff9d97304856ba7e5b26d46c6d456709a6d9e28483bff47f \
|
||||
--hash=sha256:382c5d7a9807279e3e96e4f4892b59163a2b30128c596902bf5f80e133e1ccbb
|
||||
|
@ -401,7 +402,9 @@ django-watchman==1.3.0 \
|
|||
djangorestframework==3.15.2 \
|
||||
--hash=sha256:2b8871b062ba1aefc2de01f773875441a961fefbf79f5eed1e32b2f096944b20 \
|
||||
--hash=sha256:36fe88cd2d6c6bec23dca9804bab2ba5517a8bb9d8f47ebc68981b56840107ad
|
||||
# via wagtail
|
||||
# via
|
||||
# wagtail
|
||||
# wagtail-localize-smartling
|
||||
docutils==0.21.2 \
|
||||
--hash=sha256:3a6b18732edf182daa3cd12775bbb338cf5691468f91eeeb109deff6ebfa986f \
|
||||
--hash=sha256:dafca5b9e384f0e419294eb4d2ff9fa826435bf15f15b7bd45723e8ad76811b2
|
||||
|
@ -1365,6 +1368,7 @@ requests==2.32.3 \
|
|||
# mozilla-django-oidc
|
||||
# pygithub
|
||||
# wagtail
|
||||
# wagtail-localize-smartling
|
||||
rich-text-renderer==0.2.8 \
|
||||
--hash=sha256:74e28bde639f737e2bc50f3dfb147bdbad4b2d7ab3f8f76a9db2d444edb8d13b \
|
||||
--hash=sha256:e4680109372b55611250ebe0745f59cbf3f8932afa6f5cb5d1f3cc282a4bf95c
|
||||
|
@ -1591,9 +1595,16 @@ wagtail==6.1.3 \
|
|||
# via
|
||||
# -r requirements/prod.in
|
||||
# wagtail-localize
|
||||
# wagtail-localize-smartling
|
||||
wagtail-localize==1.9 \
|
||||
--hash=sha256:a680fc33c17145e6726f03a57b2ec465405847ae7cb77943ecc0e56463ad68c7 \
|
||||
--hash=sha256:f4fa9c36d8dbab5c27d1b675ed6fd7b9e8f012cf4bb308464168de7ebbad8324
|
||||
# via
|
||||
# -r requirements/prod.in
|
||||
# wagtail-localize-smartling
|
||||
wagtail-localize-smartling==0.2.3 \
|
||||
--hash=sha256:0701444976c6b5392616d5dcdbf202fdce730b591e9d6794efee99c613107dc5 \
|
||||
--hash=sha256:6bef31958c24229a663b81b889879c845bed021dde0eba44a9527eb45e6cf3ed
|
||||
# via -r requirements/prod.in
|
||||
webencodings==0.5.1 \
|
||||
--hash=sha256:a0af1213f3c2226497a97e2b3aa01a7e4bee4f403f95be16fc9acd2947514a78 \
|
||||
|
|
Загрузка…
Ссылка в новой задаче