Cross-cutting · Multi-language content authoring

Every customer-facing entity carries a per-language record for its translatable fields, and the editors expose languages as wizard steps — the default language marked with an asterisk — so content is authored once per language in the same form.

AreaCross-cutting
Routescms.proposals.new · cms.categories.new · cms.mofs.index · marketing.campaigns.new · marketing.activity-campaigns.new · cms.multicentre-proposals.new · configuration.centers.new · crm.commerces.new · configuration.extra-attributes.new
Centre modulesalways available
Staff levelsas per the host screen
Modelslanguage
UI labelerror.all-translation-fields.required
Coverage4 use cases · 1 happy · 4 failure

Known issues (1)

How it works

Nine *-language models exist (proposal, category, mof, campaign, activity-campaign, center, commerce, extra and multicentre), all keyed on the centre’s configured languages with one marked default. The campaign editor’s steps getter is the clearest example: it sorts languages with the default first and appends * to its label. Enforcement is inconsistent — the multicentre-proposal editor checks every language before submitting and blocks with error.all-translation-fields.required, while most other editors only validate the default language, so a proposal can be published with an untranslated secondary language. The centre form also supports bulk uploadTranslations.

Use cases

Why someone opens this (4)

  • A bilingual centre publishing a proposal in both languages from one form.
  • Adding a third language to an existing centre and filling in the gaps.
  • Bulk-uploading a translation file instead of editing strings one by one.
  • Making sure a group-wide multicentre proposal is complete in every language before it goes out.

Path map

flowchart LR
    F(["Multi-language content authoring"]):::feat
    F --> H1["Proposal authored in two languages"]:::ok
    F -.-> X1["Incomplete translations enforced"]:::bad
    F -.-> X2["Incomplete translations unenforced"]:::bad
    F -.-> X3["Translation upload fails"]:::bad
    F -.-> X4["Default language not set"]:::bad
    classDef feat fill:#8c5a3c,stroke:#8c5a3c,color:#ffffff,font-weight:bold
    classDef ok fill:#e3f1ea,stroke:#0d6b42,color:#0d4a2e
    classDef bad fill:#f7e6e2,stroke:#9a2d1c,color:#6e1f13

Happy paths

Proposal authored in two languages

  1. Centre has two languages configured, one default.
  2. User fills the default-language step (marked *) and then the second step.
  3. The *-language records are saved alongside the entity.
  4. The app serves each user the content for their language.

Failure paths

QA checklist

Tick these off while regression-testing this feature. The boxes are plain Markdown, so progress is visible in git diffs.

  • ✅ Proposal authored in two languages
  • ⛔ Incomplete translations (enforced)
  • ⛔ Incomplete translations (unenforced)
  • ⛔ Translation upload fails
  • ⛔ Default language not set

Implementation


Generated from doc/feature-inventory.json · id xc-multilanguage · commit 276788ca6