django CMS · djangocms-ponyglot

Every django CMS page, in every language, up to date.

Ponyglot understands placeholders and plugin trees. It translates the text inside them, tells you which sentences went stale when the source page changes, and hands the result to your editors as a draft.

Where django CMS translation gets hard

Getting a page translated once is easy. The work starts when the site keeps changing.

Pages are trees, not text

A page is placeholders full of nested plugins. Copying the tree and translating it by hand works once. After that, the language versions drift apart.

Edits go unnoticed

Someone rewords the English plan intro. Nothing tells you that the German, French and Italian pages now say something different.

Content lives elsewhere too

The blog runs on djangocms-stories, the catalog on another app. Each gets translated on its own, and "cart" comes out three different ways.

What Ponyglot adds to django CMS

Structure-aware translation

Text inside plugins is translated in place, and the plugin tree stays intact. QA checks catch broken links, placeholders, HTML and text that has grown too long.

Delta sync

Each segment gets a stable ID and a fingerprint. When the source changes, you see exactly which segments are stale in which language, and retranslate only those.

Glossary and translation memory

Product names, legal terms and your brand voice are applied on every page and in the blog. Translation memory hits don't count towards your characters.

Drafts, not surprises

Translations land as versioned drafts. An editor reviews and publishes them, and nothing goes live on its own.

Setup

One open-source, BSD-licensed connector. Use it with your own DeepL or LLM key, or connect it to the hosted service.

pip install djangocms-ponyglot

# settings.py
INSTALLED_APPS += [
    "ponyglot",
    "djangocms_ponyglot",
    "ponyglot.contrib.parler",      # e.g. for djangocms-stories
]
PONYGLOT = {
    "API_KEY": env("PONYGLOT_API_KEY"),  # or your own DeepL / LLM key
    "SOURCE_LANGUAGE": "en",
}

Planned API. It may change during early access.

django CMS questions

Does it translate plugin content or just page titles?

Plugin content too, including nested plugins. Alt text and meta descriptions are included.

What about djangocms-stories?

djangocms-stories stores its translations with django-parler, so the parler connector covers it. Blog posts share the same glossary and translation memory as your pages.

Will it publish translations automatically?

No. Every translation becomes a draft, and an editor approves it.

Do I need the hosted service?

No. The connector works on its own with your own DeepL or LLM key. The hosted service adds translation memory, glossary, delta sync, review and QA.

One layer, the whole Django stack

Pages, blog, product catalog and app content share one glossary and one translation memory.

Wagtail

wagtail-ponyglot

StreamField and rich text, plugs into wagtail-localize as a translation backend.

django-parler

ponyglot[parler]

Translated models like djangocms-stories, catalogs and app content.

django-modeltranslation

ponyglot[modeltranslation]

Per-language columns, including wagtail-modeltranslation projects.

Get early access

We're onboarding a small group of agencies and product teams running multilingual django CMS, Wagtail or Django sites.

Join early access