Der Termin hat ein Datum, einen Ort, einen Referenten — und einen Titel auf Deutsch und Englisch. In vielen Systemen wird daraus ein Eintrag pro Sprache, und das Datum steht zweimal da, bis jemand nur eine Kopie korrigiert. RustyCMS lokalisiert pro Feld: Datum, Ort und Referent gibt es einmal, nur der Titel trägt eine Sprachkarte.
Ein Flag am Feld, kein Ordner pro Sprache
// types/page.json5
fields: {
headline: { type: "string", localized: true, required: true },
excerpt: { type: "string", localized: true },
publishedAt: { type: "datetime" }, // gemeinsam
author: { type: "reference", collection: "person" }, // gemeinsam
}
Gespeichert wird ein Eintrag pro Slug. Lokalisierte Felder sind darin eine Map { de: "…", en: "…" }, alles andere steht einmal da. Kein de/- oder en/-Ordner, keine Frage, welche Kopie die führende ist. Lokalisiere nur, was sich sprachlich unterscheidet — Daten, Referenzen und Layout-Schalter bleiben gemeinsam.
Lesen: eine Sprache anfordern, fertig
GET /api/content/page/home?_locale=en # headline: "Home"
GET /api/content/page/home?_locale=de # headline: "Startseite"
Die API packt die Map aus und liefert flache Werte, das Frontend sieht keine Sprachkarten. Fehlt ein Zweig, springt die Default-Sprache des Spaces ein — eine halb übersetzte Seite hat keine Lücken. Aufgelöste Referenzen werden mit ausgepackt: Eine englische Seite bekommt ihren Autor auf Englisch, ohne dass der Consumer daran denkt.
Schreiben: nur den eigenen Zweig anfassen
Die Übersetzerin ändert den englischen Teaser und soll den deutschen nicht überschreiben. ?_locale=en&_locale_partial=true am PUT: Der Server ersetzt nur den en-Zweig und lässt de stehen. Die komplette Map schicken geht weiterhin. In der Admin-UI schaltest du im Formular zwischen den Sprachen um und bearbeitest eine nach der anderen.
Validierung kennt die Zweige
required ist erfüllt, sobald ein Sprachzweig gefüllt ist — ein Entwurf darf erst nur auf Deutsch existieren. pattern, minLength, min/max gelten pro Zweig. unique wird pro Sprache geprüft; ein Konflikt wird als title[de] gemeldet, nicht als vages „Titel doppelt”. Auch der Referenz-Index unterscheidet Sprachen: Wird das deutsche Ziel umbenannt, ist nur deutscher Content betroffen.
Sprachen pro Space
RUSTYCMS_LOCALES=de,en setzt die globale Liste, der erste Eintrag ist die Default-Sprache. Jeder Space kann abweichen — eine Kundensite mit fr dazu, eine andere nur de — über die Space-Einstellungen in der Admin-UI oder per API. Die Admin-UI warnt außerdem, wenn auf der Platte noch ein Sprachordner liegt, der nicht mehr aktiv ist.
Umstieg von Ordner-pro-Sprache
Wer bisher de/ und en/ als getrennte Verzeichnisse hatte, lässt eine Migration laufen: Dry-Run zeigt, was passieren würde, --write fasst die Dateien pro Slug zusammen. Alte Sprachordner werden archiviert, nicht gelöscht. Weicht ein nicht-lokalisiertes Feld zwischen den Sprachen ab, gibt es eine Warnung statt einer stillen Entscheidung.