Languages
Give your module's text a default, translations and an editor on the Lang page.
A lang class lists the text your module sends, such as API messages and email text. Admins can reword any of it on the Lang page, per language, and your code reads the result.
Supported Languages
en, fr, es-ES, de, pt-BR, it, nl, pl, ru, uk, tr, sv-SE, ja, ko, zh-CN, zh-TW
English is the base. Prism looks up text in the server's Language, then its Secondary Language, then English, and uses the first one that has the key.
Defining Text
Put the English class in resources/lang/en/:
import { Langs } from "#prism/modules";
export class ExampleMessages extends Langs {
constructor(prism) {
super(prism, { name: "messages", label: "Messages", description: "Text sent by the example API" });
}
schema() {
return {
replies: {
type: "section",
label: "Replies",
fields: {
synced: { type: "phrase", default: "Synced %count% items.", label: "Synced" },
failed: { type: "phrase", default: "Sync failed: %reason%", label: "Failed" }
}
},
footer: { type: "text", default: "Thanks for buying from us.", label: "Footer" }
};
}
}| Type | Editor |
|---|---|
phrase | One line. The default when type is left out. |
text | Several lines. |
section entries group fields under a heading, the same as in config classes. A field can also be a bare string, such as synced: "Synced %count% items.".
Translations
Every other language is a JSON file named after the group, holding only the keys you translate:
resources/lang/
├── en/
│ ├── common.json
│ └── messages.js
├── de/
│ ├── common.json
│ └── messages.json
└── fr/
├── common.json
└── messages.json{
"synced": "%count% Elemente synchronisiert.",
"failed": "Synchronisierung fehlgeschlagen: %reason%"
}Missing keys fall back through the chain above. Folders for languages Prism does not support are skipped.
You can also put every language in one resources/lang/translations.json, keyed by language and then group:
{
"de": { "messages": { "synced": "%count% Elemente synchronisiert." } },
"fr": { "messages": { "synced": "%count% éléments synchronisés." } }
}Reading Text
this.prism.modules.lang.phrase("example", "messages", "synced", { count: 12 });
this.prism.modules.lang.value("example", "messages", "footer");
this.prism.modules.lang.values("example", "messages");phrase replaces each %token% with the value you pass. If the key does not exist it returns the key itself, so a typo shows up instead of an empty message.
All three use the server's language and include anything an admin changed on the Lang page.
Admin Edits
The Lang page lists every module with a lang class. Its Translator tab translates text between any two languages, and each field has a translate button. An admin picks a language and changes any field. Edits are saved per language under lang:<module> in Prism's settings and win over your defaults and JSON files. When editing another language, the English text is shown under each field.
Dashboard Text
common.json holds the text the web app shows for your module, in each language:
{
"name": "Beispiel",
"description": "Synchronisiert Elemente mit einem anderen Dienst",
"schema.example.config.settings.label": "Beispiel",
"schema.example.config.settings.token.label": "API-Token"
}| Key | Translates |
|---|---|
name | The module name in the sidebar and module list, as module.<id>.name. The manifest name stays the lowercase ID. |
description | The module description. |
schema.<module>.config.<group>.label | A config group's heading. |
schema.<module>.config.<group>.<field>.label | A config field's label. |
schema.<module>.lang.<group>.<field>.label | A field's label on the Lang page. |
Any other key is added to the web dictionary as is, so your pages can use it. Prism's own text lives in src/web/lang/<code>/common.json and is not part of a module.
Ship a common.json for all 16 languages, never English only. Leave field descriptions out so rows stay aligned.