© 2026 phis.dev. Alle Rechte vorbehalten.
Brand logo
phis.dev
  • Startseite
  • Dokumentation
Zwei Sprechblasen, von denen eine auf die andere antwortet
Übersetzungen

Jeder Text, jede Sprache

Texte werden an der Stelle übersetzt, an der sie angezeigt werden – einmal für die Plattform und einmal pro Website für deren eigene Texte –, und jede Antwort kann bearbeitet werden.
Auf dieser Seite
Helfer
Etikettensätze
Platzhalter für Website-Texte
Ant Design und Datumsformatierung
Ländereinstellung anfordern
Transport der Quell-Lokalisierung
Kontext und Format
Strukturierte Dokumente
Metadaten des Laufzeitmoduls
phis.dev
Schnellzugriff
AGB
Kontakt

Übersetzungsvertrag

Dieses Dokument befasst sich mit dem @phis/ui -Bereich der Übersetzung: den rein serverseitigen Hilfsfunktionen, den Label-Sets, den Quell- Lokalisierungen, den strukturierten Dokumenten sowie der Verarbeitung der aufgelösten Anforderungslokalisierung durch das Paket. Persistenz, kanonische Speicherhüllen, Anbieteranfragen und Änderungsmarkierungen fallen in den Zuständigkeitsbereich von @phis/server (TRANSLATIONS.md ). Die Obermenge der Sprachumgebungsfunktionen, die validierte Teilmenge jeder Website sowie GET /api/v1/site/locale fallen in den Zuständigkeitsbereich von @phis/server (phis-server TRANSLATIONS.md, „Locale capability“ ). Wie Übersetzungen in einem Website-Prozess zwischengespeichert werden, ist in gateway/CACHES.md beschrieben.

Helfer

Die Übersetzungshelfer sind ausschließlich serverbasiert und werden aus @phis/ui/server-helpers (server-helpers/translate.ts ) exportiert:
  • tr(msg, params?, ctx?, format?) und trForLocale(locale, msg, params?, ctx?, format?) übersetzen eine auf die Website bezogene Meldung.
  • trBulk(msgs, ctx?, format?, sourceLocale?) und trBulkForLocale(locale, msgs, ctx?, format?, sourceLocale?) übersetzen mehrere Nachrichten im Site-Bereich in einer einzigen Anfrage und behalten dabei deren Reihenfolge bei: eine Antwort pro Nachricht, an ihrer jeweiligen Position. Eine leere Nachricht wird mit einem leeren Text beantwortet und nicht gesendet, sodass ein Aufrufer die Antworten anhand des Indexes abgleichen kann (gateway/tr.ts ). Würde man dies weglassen, wie es früher bei der Stapelverarbeitung der Fall war, würden alle nachfolgenden Antworten auf die falsche Nachricht verschoben.
  • trGlobal(msg, params?, ctx?, format?) , trGlobalForLocale(...) , trGlobalBulk(msgs, ctx?, format?) sowie trGlobalBulkForLocale(...) übersetzen globale Phi-Kopien, deren Quellsprache stets en (PHI_CANONICAL_SOURCE_LOCALE ) ist. Bei einer Anfrage für en wird der Quelltext ohne weitere Anfrage zurückgegeben.
Regeln:
  • Die Helfer ohne Locale lesen die Locale der Anfrage über `resolvePhiRequestLocale()` aus und die Site aus dem auf die Anfrage beschränkten Laufzeitsatz, der durch das CMS-Root-Rendering festgelegt wird.
  • ctx ist standardmäßig leer. Legen Sie diesen Wert nur fest, wenn derselbe sichtbare Text in einem anderen semantischen Kontext unterschiedlich übersetzt werden muss. Gemeinsam genutzte UI-Texte verwenden die festen Register PHI_TR_CTX_WEB_UI_LABEL (Beschriftungen auf Steuerelementen) und PHI_TR_CTX_WEB_UI_MESSAGE (Meldungen der Benutzeroberfläche: Leerzustände, Fehler); Modulbeschreibungen verwenden PHI_TR_CTX_MODULE_DESCRIPTION. Erstellen Sie keine standortspezifischen Kontexte für gemeinsam genutzte UI-Texte.
  • Das format ist standardmäßig auf text eingestellt. Verwenden Sie html nur für bewusst übersetzbare HTML-Markups.
  • Bei einer fehlgeschlagenen Anfrage wird der Quelltext zurückgegeben; die Hilfsfunktionen lösen bei einem Übersetzungsfehler niemals eine Ausnahme aus.
  • Dynamische Werte sind niemals Bestandteil einer übersetzten Zeichenfolge: keine Namen, Benutzernamen, E-Mail-Adressen, Firmennamen, Kundennummern, Seitennamen, URLs oder ähnliche Daten. Der Quelltext verwendet die positionsbezogenen Platzhalter %1, %2, … (beispielsweise Login history for %1), und die Werte werden nach der Übersetzung eingesetzt. Die Helper für einzelne Nachrichten nehmen diese als params auf; Massenausgaben und Label-Sets werden vom Aufrufer formatiert, und Client-Komponenten formatieren bereits übersetzte Vorlagen lokal, anstatt Labels mit Werten zu verknüpfen.
  • Für Freitextseiten und Website-Inhalte wird ein einzelner Aufruf von trBulk(...) gegenüber mehreren Aufrufen von tr(...) bevorzugt.
  • Die Übersetzung erfolgt unabhängig vom Datenquellenvertrag und vom Absenden des Formulars.
  • phiRuntime() (@phis/ui/server-helpers) dient den Metadaten der Laufzeit selbst – apiBaseUrl, internalToken, siteKey, locale und fetchSiteLocaleConfig() – und nicht der Übersetzung.

Etikettensätze

Die UI-Inhalte im Besitz von Phi werden über Label-Sets (gateway/label-set.ts) geladen. Woher die Helper stammen, hängt davon ab, wer sie importiert:
  • Ein Modulpaket außerhalb von @phis/ui bezieht diese aus @phis/ui/module/labels, niemals aus @phis/ui/server-helpers. Der Server-Barrel enthält dieselben Namen, jedoch zusammen mit server-helpers/cms-root und next/headers; eine Moduldefinition ist auch über den Browser-Graphen erreichbar, da Client-Widgets die damit verknüpften Label-Sets rendern; werden sie also aus dem „Barrel“ bezogen, führt dies zu einer Kompilierung und anschließend zu einem 500-Fehler auf jeder Seite der Website (siehe THIRD_PARTY_MODULES.md).
  • Der eigene Servercode einer Website kann diese aus dem Verzeichnis @phis/ui/server-helpers beziehen.
  • Die First-Party-Module in diesem Paket importieren gateway/label-set direkt, das ebenso spezifisch ist wie @phis/ui/module/labels.
Die Helfer:
  • definePhiLabelSet({ key, ctx, sourceLocale?, labels }) deklariert eine Menge. labels ordnet semantische Schlüssel dem Standardtext zu. Ein Eintrag kann sein eigenes Register als { text, ctx } benennen; definePhiMessageLabel(text) kennzeichnet einen Satz innerhalb einer Menge von Beschriftungen.
  • definePhiRuntimeModuleLabelSet(moduleDefinition, { key, ctx, labels }) deklariert eine dem Modul zugehörige Menge. Ihr Schlüssel lautet module:<moduleId>:<key>, und ihre Quellsprache ist die sourceLocale des Moduls.
  • Die Funktion getPhiLabelSet(options, definition) gibt die Texte unter denselben semantischen Schlüsseln zurück. Sie sendet eine Sammelanfrage pro Register; die positionelle Stapelverarbeitung ist ein internes Transportdetail. Die Sätze werden nicht als Sätze zwischengespeichert; jede Nachricht durchläuft den Übersetzungscache.
  • Der Widget-Code liest Bezeichnungen anhand semantischer Schlüssel aus, niemals über Freitext-Abfragen oder Positionen.
  • Label-Sätze sind statische UI-Texte. Sie können Platzhaltervorlagen wie Edit user %1 enthalten, werden jedoch niemals aus aufgelösten Benutzer-, Profil-, Unternehmens- oder E-Mail-Daten generiert.
  • In der Datenbank werden niemals Schlüssel für Label-Sets, Loader-Pfade oder Kennungen für Übersetzungsbündel gespeichert.
  • First-Party-Widget-Loader befinden sich unter components/widgets/label-sets/* und sind semantisch benannt (account.ts, inspector.ts), nicht anhand numerischer IDs. Ihre Label-Typen und Standardtexte befinden sich unter components/widgets/label-types/*; ein Loader importiert diese, anstatt sie zu wiederholen. Die Server- Hälfte eines Widgets importiert ihren eigenen Loader; der CMS-Renderer und das Gateway verfügen über keine konkreten Widget-Labels.
  • Die Eigenschaft labels eines Blocks enthält die von Phi verwalteten Benutzeroberflächen- und Steuerungstexte; defaultLabels enthält lokalisierte Standardinhalte, die nur angezeigt werden, wenn kein CMS- oder Konfigurationstext vorhanden ist. Expliziter Konfigurationstext wie beispielsweise config.label, config.title oder config.tooltip hat Vorrang vor beiden. Ein Block ohne Text verwendet den Typ PhiNoLabels (types/widget-runtime.ts) anstelle der Übergabe eines leeren labels-Objekts.
  • Semantische Befehle wie „Speichern“, „Veröffentlichen“, „Überprüfen“, „Wiederherstellen“, „Zurücksetzen“, „Neu laden“ und „Hochladen“ stammen aus dem „common-controls“-Label-Set (components/widgets/label-sets/common-controls.ts).

Platzhalter für Website-Texte

Text, der in die Konfiguration eines Widgets geschrieben wird – sei es durch eine Voreinstellung oder durch den Ersteller –, kann einige Fakten über die Website benennen, anstatt sie vollständig auszuschreiben (helpers/text-placeholders.ts):
  • Die Namen lauten {site.name}, {site.wordmark}, {year} und {site.host}. Diese Liste umfasst die gesamte Sprache; ein Platzhalter ist kein Pfad in die Laufzeitumgebung, und ein Name, auf den keine Antwort vorliegt, bleibt bestehen, sodass {jahr} als {jahr} dargestellt wird und als der Tippfehler erkennbar ist, der er ist.
  • {site.wordmark} ist die Bezeichnung, unter der sich die Website schriftlich präsentiert, und {site.name} ist der Name, unter dem sie registriert ist. Ist keine Wortmarke festgelegt, wird die Wortmarke durch den Namen ersetzt, sodass es sich niemals um die leere Abfrage „ask“ handelt.
  • Die Reihenfolge lautet: maskieren, übersetzen, ausfüllen – niemals erst übersetzen und dann ausfüllen. {year} ist ein Wort, und ein maschineller Übersetzer übersetzt Wörter: Als Ergebnis erhält man {Jahr}, worauf nichts passt. maskPhiTextPlaceholders wandelt zunächst jeden Namen in ein %n-Token um – dasselbe Token, das dieser Vertrag bereits für Werte verwendet – und resolvePhiTextPlaceholders füllt diese anschließend an den Stellen aus, an denen der Übersetzer sie hinterlassen hat.
  • Ein Text kann eigene Werte enthalten – ein Listeneintrag { text: "Site key: %1", values: [key] }. Diese nehmen Werte von %1 bis %k an, und die maskierten Namen beginnen bei %k+1 (maskPhiTextPlaceholders(text, k)), sodass durch eine einzige Ersetzung beide wiederhergestellt werden. Ein Wert wird niemals übersetzt, und ein Satz, der einen Wert enthält, bildet eine Katalogzeile anstelle einer Zeile pro Site.
  • Das anschließende Ausfüllen ist zudem der Grund dafür, dass eine Übersetzung wiederverwendbar ist. Die gespeicherte Übersetzung ist an den Quelltext gekoppelt, sodass © %1 %2. All rights reserved. für jede Website, die die Voreinstellung übernimmt, eine Zeile pro Sprachversion darstellt – und dieselbe Zeile gilt auch nach Neujahr.
  • Eine Voreinstellung löst beim Aufbau ihres Baums niemals einen Platzhalter auf. Dadurch werden der Name einer Website und das Jahr der Übernahme in die Kopie jedes Nutzers geschrieben, wo sie verbleiben.
  • Widgets, die kurze Konfigurationstexte enthalten, lösen diese auf; lange Markdown- und HTML-Inhalte tun dies bewusst nicht, da es sich bei einer geschweiften Klammer dort eher um ein Code-Beispiel als um einen Platzhalter handelt.

Ant Design und Datumsformatierung

Die Ant Design-eigenen Textelemente (Paginierung, Leerstände, Auswähltext, Validierungsvorlagen, Schaltflächen in Modalfenstern) sowie die Datums- und Zeitformatierung stammen aus der Ant Design-Lokalisierung und der gemeinsamen Day.js-Lokalisierungsbrücke (components/root/phi-dayjs-locale.tsx), niemals aus Label-Sets. Die Ant-Design-Locale wird einmalig im Root-ConfigProvider (components/root/phi-root-layout.tsx) angewendet. helpers/antd-locale.ts ordnet die aufgelöste Site-Locale einem Ant-Design-Locale-Schlüssel zu und lädt sie über eine explizite Whitelist von import("antd/locale/<key>")-Loadern, niemals über einen berechneten Importpfad.

Ländereinstellung anfordern

  • Die aufgelöste Locale-Anfrage stammt von @phis/server (GET /api/v1/site/locale) und enthält die Parameter locale, language, die optionalen Parameter script und region, direction, intlLocale, den optionalen Parameter deeplTargetLang, labelFallbacks sowie source (helpers/site-locale-config.ts). Die gemeinsame Benutzeroberfläche überprüft nicht, ob die Plattform die jeweilige Locale unterstützt, und implementiert weder DeepL-Zielsprachen noch die Textrichtung oder Fallback-Ketten neu.
  • Root, CMS, Metadaten, Übersetzung und Weiterleitungscode verwenden alle dasselbe, auf die Anfrage bezogene Ergebnis (server-helpers/request-locale.ts); keines davon wendet eine eigene Locale-Priorität an. Diese Anfrage ist no-store, da die Antwort von der Sitzung, den Cookies, der explizit festgelegten Locale und dem Accept-Language-Header abhängt. Die Locale-Konfiguration der Website (fetchSiteLocaleConfig) kann pro Website zwischengespeichert werden.
  • x-locale enthält ausschließlich die explizit angegebene Locale einer öffentlichen Route mit Locale-Präfix. Der Site-Proxy (next/site-proxy.ts) entfernt alle eingehenden x-locale-Angaben und setzt diesen Wert ausschließlich anhand des Pfadpräfixes; ein Cookie, eine Browsereinstellung, ein Profilwert oder eine bereits aufgelöste Locale werden niemals in diesen Wert übernommen.
  • Übersetzungsaufrufe auf Site-Ebene enthalten keine Quell-Locale der Site: @phis/server leitet diese von der Site ab. Die defaultLocale der Site ist die letzte Ausweichoption für die Anfrage-Locale und wird niemals als Ersatz für die englische (en ) Quelle globaler Texte herangezogen.

Transport der Quell-Lokalisierung

  • Bei gewöhnlichen Site-Übersetzungsaufrufen wird sourceLocale weggelassen; @phis/server ermittelt die unveränderliche Site-Quell- Locale.
  • Modultext, der einen Übersetzungsaufruf der Website erreicht, enthält die sourceLocale des Moduls: eine Navigationsbezeichnung, die ein Modul bereitstellt (PhiCmsNavigationLabel.sourceLocale, festgelegt beim Auflösen des Eintrags), sowie den Titel einer Modulroute. Ohne diese Angabe liest eine Website, deren Quellsprache nicht die des Moduls ist, die englische Version des Moduls als ihre eigene und übersetzt sie niemals. Eine Bezeichnung, die der Betreiber umbenennt oder hinzufügt, verliert dieses Feld oder verfügt gar nicht erst darüber und wird in der Quellsprache der Website gelesen.
  • Eigenständige globale Bezeichnungen können sourceLocale angeben; wird dies nicht angegeben, gilt Englisch. Modul-eigene Voreinstellungen von Drittanbietern übernehmen die Spracheinstellung des zugehörigen Moduls, anstatt eine andere Ausgangssprache anzugeben.
  • Jedes Laufzeitmodul deklariert eine kanonische sourceLocale; wird diese nicht angegeben, gilt Englisch. Alle vom Paket erstellten Komponenteninhalte erben diese über den „Module Label-Set“-Helper. Komponentenspezifische Überschreibungen der Quellsprache sowie mehrsprachige Modul-Metadaten sind ungültig.
  • Von Phi verwaltete Module erstellen die kanonische Version in englischer Sprache. Metadaten und Komponentenbezeichnungen von Modulen von Drittanbietern können eine andere deklarierte Modul-Quellsprache verwenden.
  • Externe Markdown- und HTML-Widgets speichern in der Widget-Konfiguration eine einzige „plainsourceLocale“-Einstellung. Diese kann von den auf der Website verfügbaren Ziellokalisierungen abweichen.
  • sourceLocale wird als eigenständiges Anfragefeld weitergeleitet. Es darf keinesfalls in ctx kodiert werden.
  • Kann der aktive Anbieter die konfigurierte externe Quelle nicht übersetzen, zeigt das Widget das Originaldokument an und führt bei jeder Darstellung keine erneute Erkennung durch.

Kontext und Format

Aufrufer stellen lediglich optionale Kontextinformationen in natürlicher Sprache bereit. Sie erstellen keine internen Kontext-Flags. Das Gateway leitet das format: "html" sowie explizite Metadaten externer Quellen weiter; @phis/server ist für die kanonischen Speicherhüllen [html], [extern] und [html:extern] verantwortlich.

Strukturierte Dokumente

  • Markdown und HTML werden vor dem Aufruf des Gateways in semantische Übersetzungseinheiten zerlegt.
  • Eine Überschrift, ein Absatz, ein Listenpunkt-Absatz, ein Zitatblock-Absatz oder eine Tabellenzelle gilt als eine Einheit.
  • Inline-Formatierungen und sichtbarer Linktext bleiben durch übersetzungssicheres HTML-Markup erhalten.
  • Code, Inline-Code und Linkziele werden niemals übersetzt. Der Alternativtext von Bildern ist übersetzbar.
  • Alle Einheiten aus einem Dokument nutzen das Bulk-Gateway. Der Server wertet Cache-Treffer und die Aufteilung der Anforderung durch den Anbieter aus, wobei die Reihenfolge der Einheiten beibehalten wird.
Die HTML-Sanitisierung orientiert sich an Vertrauensgrenzen und nicht an der Häufigkeit der Darstellung. Kanonisches Inline-HTML wird vor der Speicherung durch @phis/server sanitisiert. Externe Dokumente und von Anbietern erstelltes HTML werden im Server-Rendering-Pfad bereinigt, da es sich dabei nicht um vertrauenswürdiges, dauerhaft gespeichertes Widget-Markup handelt. Öffentliche und App-HTML-Widget-Clients erhalten sicheres, serialisiertes Markup und dürfen den HTML-Sanitizer nicht importieren.
In intern gespeicherten Markdown-/HTML-Dateien eingebettete Ziele für „Typed Page“ und „Asset“ sowie die zwingende Ablehnung dieser Ziele in externen Dokumenten richten sich nach der Datei REFERENCES.md. Referenz- Identitäten und -ziele sind strukturelle Metadaten und niemals Übersetzungseinheiten.
Bei externen Quellen ermittelt der Builder die Quellsprache einmalig, sobald ein neuer Anhang konfiguriert wird, und speichert diese Angabe im Rahmen der normalen, generischen Widget-Konfigurationsaktualisierung. Bei nachfolgenden Darstellungen wird dieser Wert verwendet. Der Builder kann diesen Wert explizit überschreiben oder nach einer Änderung des Anhangs eine erneute Ermittlung anfordern.
Das Entfernen eines Widgets oder das Löschen seiner URL trennt lediglich die Quelle. Es darf keine impliziten Anweisungen zum Löschen von Übersetzungseinheiten auslösen, da Einheiten möglicherweise gemeinsam genutzt werden und Builder-Vorgänge weiterhin rückgängig gemacht werden können müssen.

Metadaten des Laufzeitmoduls

Titel, Beschreibung und andere vom Paket erstellte Bezeichnungen des Laufzeitmoduls verwenden globale Übersetzungen, niemals Website-Übersetzungseinheiten. Server-eigene Autorierungskataloge gruppieren Metadaten nach der Quellsprache des Moduls, übersetzen diese in großen Mengen und senden lokalisierte Kopien an Client-Anbieter. Die unveränderliche Definition des Laufzeitmoduls behält ihre kanonischen Quellzeichenfolgen und die Quellsprache bei; die Lokalisierung darf den aktiven Modulkatalog nicht überschreiben.
Ein Modul, dessen Quell-Locale nicht die kanonische ist, wird von jeder Installation, auf der es ausgeführt wird, auf dem eigenen Provider dieser Installation übersetzt und niemals über das CDN. Das kanonische Englisch, nach dem seine Einheit indiziert ist, wird generiert und nicht deklariert, sodass zwei Installationen dieselbe Zeichenfolge unter zwei unterschiedlichen Hashes indizieren und kein Mirror auf eine der beiden reagieren kann. Was diese Zeichenfolgen gemeinsam nutzbar machen würde, ist ein Paket, das seinen kanonischen Text neben der eigenen Sprache deklariert; eine lokale Vorübersetzung ist nicht dasselbe, auch wenn es so aussieht, als wäre es so (phis-server TRANSLATIONS.md, „Übersetzungsmodi“).
Modulkategorie, ID, Anbieterschlüssel, Funktionen und andere Systemidentitäten bleiben unveränderliche Schlüssel. Ein separates globales Kategorie-Label-Set kann den Benutzern einen Kategorieschlüssel anzeigen. Optionale, von der Website verwaltete Darstellungsüberschreibungen sind Website-Inhalte und ersetzen nicht die globale Paketübersetzung.