Skip to main content

Wagtail Translate

License: MIT PyPI version Translate CI

Wagtail Translate adds machine translation to Wagtail. It listens for Wagtail's copy_for_translation_done signal. Wagtail emits this signal after it copies an object to another locale. Wagtail Translate sends the supported content to a translation backend and applies the result to the copy.

Wagtail Simple Translation is a good fit for this workflow. It provides the user interface to copy content to another locale.

Wagtail Translate collects the content from a page or snippet in one translation document structured as HTML. This document keeps titles, fields, rich text, and StreamField blocks together. It gives the backend maximum context while preserving data that should not be translated.

For example, the title The match can describe a sports game or a stick used to start a fire. Content elsewhere on the page tells the backend whether to use Le match or L’allumette in French.

Wagtail Translate validates the returned document and restores the preserved data. It then updates the copied object.

Wagtail Translate includes backends for:

You can also write your own custom backend.

Wagtail Translate is developed and tested on Python 3.14. Python versions >=3.10 should work but are not tested.

Internationalisation and Simple Translation

Configure your project for authoring content in multiple languages.

See Wagtail documentation on internationalization and Simple Translation.

For short:

# settings.py
INSTALLED_APPS = [
    # ...
    "wagtail.contrib.simple_translation",
    "wagtail.locales",
    # ...
]

USE_I18N = True
WAGTAIL_I18N_ENABLED = True

LANGUAGE_CODE = "en"
WAGTAIL_CONTENT_LANGUAGES = LANGUAGES = [
    ("en", "English"),
    ("fr", "French"),
]
MIDDLEWARE = [
    # ...
    "django.contrib.sessions.middleware.SessionMiddleware",
    "django.middleware.locale.LocaleMiddleware",
    # ...
]
# urls.py
from django.conf.urls.i18n import i18n_patterns
from django.urls import include, path
from wagtail import urls as wagtail_urls

urlpatterns += i18n_patterns(
    path("", include(wagtail_urls)),
)

Run migrations: python manage.py migrate.

Create locales at: /admin/locales/new/.

Installation

Install Wagtail Translate:

pip install wagtail-translate

Add to to INSTALLED_APPS and define a WAGTAIL_TRANSLATE_TRANSLATOR.

# settings.py
INSTALLED_APPS = [
    # ...
    "wagtail_translate",
    "wagtail_translate.default_behaviour",
    # ...
]

WAGTAIL_TRANSLATE_TRANSLATOR = "wagtail_translate.translators.rot13.ROT13HTMLDocumentTranslator"

In the Wagtail admin interface, go to the homepage, in the dot-dot-dot-menu, choose "Translate".

The contents should be translated! 🥳

Translation backends

DeepL

Install the DeepL extra:

pip install "wagtail-translate[deepl]"

Add the backend and API key to your settings:

WAGTAIL_TRANSLATE_TRANSLATOR = (
    "wagtail_translate.translators.deepl.DeepLHTMLDocumentTranslator"
)
WAGTAIL_TRANSLATE_DEEPL_KEY = "your-api-key"

OpenAI-compatible LLM

Install the LLM extra:

pip install "wagtail-translate[llm]"

The backend uses an OpenAI-compatible Chat Completions API. The default endpoint is a local Ollama server.

Configure a local model:

WAGTAIL_TRANSLATE_TRANSLATOR = (
    "wagtail_translate.translators.openai_compatible.LLMHTMLDocumentTranslator"
)
WAGTAIL_TRANSLATE_LLM_MODEL = "translategemma:27b"
WAGTAIL_TRANSLATE_LLM_BASE_URL = "http://localhost:11434/v1/"
WAGTAIL_TRANSLATE_LLM_API_KEY = "ollama"

ROT13

ROT13HTMLDocumentTranslator replaces each letter with the letter 13 positions later in the alphabet. Applying ROT13 twice restores the original text.

This backend is deterministic and does not use an external service. Use it for tests and demonstrations, not for real translations.

Default behaviour

The wagtail_translate.default_behaviour app adds the copy_for_translation_done signal handler.

The handler initiates the translation and saves the Wagtail object.

Use a custom app if you'd like to customize. For more details:

Development and testing

Install the package with its test dependencies:

make install

Activate the virtual environment:

source .venv/bin/activate

Run all checks and tests:

make test

Fix code style:

make fix-codestyle

Demo project

Use the tests/testproject Django and Wagtail project for manual tests and demonstrations:

python tests/testproject/manage.py migrate
python tests/testproject/manage.py createsuperuser
python tests/testproject/manage.py createcontent
python tests/testproject/manage.py runserver

The createcontent command resets the demo page tree. It then creates pages with ambiguous words, rich text, nested StreamField blocks, images, documents, and related snippets.

The demo uses the ROT13 backend by default. Change the translator settings in tests/testproject/settings.py to test DeepL or a local LLM.

Release

GitHub Actions publishes a release to PyPI when a v* tag is pushed.

Update the project version with uv:

uv version 1.0.0
git add pyproject.toml
git commit -m "Release 1.0.0"
git tag v1.0.0
git push
git push origin v1.0.0

The Git tag must match the package version with a v prefix. For example, version = "1.0.0" uses the tag v1.0.0.

You can create a GitHub Release after you push the tag. If GitHub creates the tag, make sure that the version commit is already on the target branch.

Build and inspect the package locally before a release:

uv build

This command writes the release artifacts to dist/. Check the generated files and make sure that they contain the package modules:

tar -tf dist/wagtail_translate-*.tar.gz
unzip -l dist/wagtail_translate-*.whl

Metadata

Release files for wagtail-translate 1.0.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for wagtail-translate 1.0.0
File Size Uploaded Provenance Actions
wagtail_translate-1.0.0.tar.gz 13.7 kB Without provenance Details for wagtail_translate-1.0.0.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for wagtail-translate 1.0.0
File Interpreter ABI Platform Actions
wagtail_translate-1.0.0-py3-none-any.whl Python 3 none any Details for wagtail_translate-1.0.0-py3-none-any.whl

Total release size: 29.9 kB

Release files / wagtail_translate-1.0.0.tar.gz

Download URL wagtail_translate-1.0.0.tar.gz
Size 13.7 kB
Tags Source
SHA-256 checksum
How to use checksums
9d76ccd78199e3741aa65d6f01e47ba3901222c83d74f0caba80f7c5accfc997
BLAKE2b-256 checksum
How to use checksums
746fb41809e69bd2da50b565f509fbc0fcaf5ad66b8976264572191f36d9cc5f
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.13.1 {"installer":{"name":"uv","version":"0.13.1","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release files / wagtail_translate-1.0.0-py3-none-any.whl

Download URL wagtail_translate-1.0.0-py3-none-any.whl
Size 16.2 kB
Tags Python 3
SHA-256 checksum
How to use checksums
330f217b31a5e0faed611bc5798e348162ccbb78e4618ad7c1ea2dcb23cc5065
BLAKE2b-256 checksum
How to use checksums
91f5901c011d90bffa5e0498b8b20d80f5b3248a6d859564a09fcf422e9e4a3f
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.13.1 {"installer":{"name":"uv","version":"0.13.1","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Security for wagtail-translate 1.0.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page