Zum Hauptinhalt springen

Clientseitig

Für Code, der im Browser läuft — Gadgets, Userexits und die in serverseitigen Konfigurationen eingebetteten Callbacks — steht das Clientmodul I18n bereit. Die Übersetzungen stammen aus derselben Locale-Datei; clientseitig werden sie über den I18n-Kontext des Clients gelesen statt über die Systemtabelle.

Zugriff​

Das Modul wird wie jedes andere Clientmodul über mustGetClientModule geholt:

import { mustGetClientModule } from "@one-unity/library/client";
import type { Locales } from "./ou.sp.ptpINV.installer.step.globalPropertiesLocales";

const t = mustGetClientModule<typeof I18n>("I18n").createT<Locales>();

Welche Member es gibt und wie ihre Signaturen aussehen, steht in der API-Referenz unter I18n.

Ein language-Parameter existiert clientseitig nicht; es gilt immer die Sprache der aktuellen Sitzung.

Eingebettete Callbacks​

Viele Konfigurationsskripte (settings.*, Hitlist- und Gadget-Konfigurationen) laufen auf dem Server, um die Konfiguration zu bauen. Nur die Funktionskörper von click, render und ähnlichen Callbacks werden serialisiert und im Browser neu ausgeführt.

t muss innerhalb des Callbacks erzeugt werden

Ein serialisierter Callback ist keine Closure. Er kann zur Laufzeit ausschließlich auf clientseitige Globals zugreifen (I18n, document, documentsContext) — niemals auf eine Variable, die im umgebenden serverseitigen Objektliteral deklariert wurde. Der mustGetClientModule-Aufruf gehört deshalb in den Callback selbst.

markPosition: {
click: (_, row, options) => {
const t = mustGetClientModule<typeof I18n>("I18n").createT<Locales>();

if (isParentContainerInvisible) {
documentsContext.openMessageDialog(
t((l) => l.filetype.ptpInvoice.monitorRMB.viewerNotOpen.title),
t((l) => l.filetype.ptpInvoice.monitorRMB.viewerNotOpen.message)
);
return;
}
},
},

Ob ein Codeabschnitt server- oder clientseitig läuft, entscheidet sich am umgebenden Code, nicht am Dateinamen: serverseitiger Code verwendet context.* und docFile.*, clientseitiger documents.sdk.*, einen documentsContext-Parameter oder DOM-Globals. Eine einzelne Gadget_*-Datei kann beides enthalten.

Verhalten​

Identisch zur Serverseite: fehlt ein Eintrag, wird der Key zurückgegeben; {{platzhalter}} ohne passenden Wert bleiben stehen; ohne data findet keine Ersetzung statt.

Inline-Literale ersetzen​

documents.sdk.utils.getLocaleValue("de:…;en:…") sieht wie eine Übersetzung aus, ist aber ein hart kodierter zweisprachiger String — eine neue Sprache erreicht er nie. Beim Migrieren wird er wie jeder andere Klartext behandelt: erst einen Key in der Locale-Datei anlegen, dann den Aufruf ersetzen.

// vorher
documents.sdk.utils.getLocaleValue("de:Warnung;en:Warning");

// nachher
t((l) => l.filetype.ptpInvoice.monitorRMB.viewerNotOpen.title);