Internationalisierung
Die WebExtensions API verfügt über ein nützliches Modul zur Internationalisierung von Erweiterungen — i18n. In diesem Artikel werden wir die Funktionen erkunden und ein praktisches Beispiel zeigen, wie es funktioniert. Das i18n-System für Erweiterungen, die mit WebExtension APIs erstellt wurden, ist ähnlich wie gängige JavaScript-Bibliotheken für i18n, wie z.B. i18n.js.
Hinweis: Die in diesem Artikel vorgestellte Beispielerweiterung — notify-link-clicks-i18n — ist auf GitHub verfügbar. Folgen Sie dem Quellcode, während Sie die untenstehenden Abschnitte durchgehen.
Anatomie einer internationalisierten Erweiterung
Eine internationalisierte Erweiterung kann dieselben Funktionen enthalten wie jede andere Erweiterung — Hintergrundskripte, Inhalts-Skripte, usw. — aber sie hat auch einige zusätzliche Teile, um zwischen verschiedenen Lokalitäten wechseln zu können. Diese werden im folgenden Verzeichnisbaum zusammengefasst:
-
extension-root-directory/
-
_locales
-
en
-
messages.json
- Englische Nachrichten (Strings)
-
-
de
-
messages.json
- Deutsche Nachrichten (Strings)
-
-
etc.
-
-
manifest.json
- lokalabhängige Metadaten
-
myJavascript.js
- JavaScript zum Abrufen der Browser-Lokale, lokalspezifischer Nachrichten, etc.
-
myStyles.css
- lokalabhängige CSS
-
Lassen Sie uns jede der neuen Funktionen der Reihe nach erkunden — jeder der folgenden Abschnitte stellt einen Schritt dar, den Sie beim Internationalisieren Ihrer Erweiterung befolgen sollten.
Bereitstellen lokalisierter Strings in _locales
Hinweis: Sie können Sprachuntercodes mit dem Find Tool auf der Language subtag lookup page nachschlagen. Beachten Sie, dass Sie nach dem englischen Namen der Sprache suchen müssen.
Jedes i18n-System erfordert die Bereitstellung von Strings, die in alle verschiedenen Lokalitäten, die Sie unterstützen möchten, übersetzt sind. In Erweiterungen sind diese in einem Verzeichnis namens _locales
enthalten, das sich im Stammverzeichnis der Erweiterung befindet. Jede einzelne Locale hat ihre Strings (als Nachrichten bezeichnet), die in einer Datei namens messages.json
enthalten sind, die sich in einem Unterverzeichnis von _locales
befindet, das mit dem Sprachuntercode für die Sprache dieser Locale benannt ist.
Bitte beachten Sie, dass, wenn der Untercode aus einer grundlegenden Sprache plus einer regionalen Variante besteht, Sprache und Variante konventionell durch einen Bindestrich getrennt werden: zum Beispiel "en-US". Unter den Verzeichnissen in _locales
muss der Trenner jedoch ein Unterstrich sein: "en_US".
So haben wir zum Beispiel in unserer Beispiel-App Verzeichnisse für "en" (Englisch), "de" (Deutsch), "nl" (Niederländisch) und "ja" (Japanisch). Jedes dieser Verzeichnisse hat eine messages.json
Datei darin.
Werfen wir nun einen Blick auf die Struktur einer dieser Dateien (_locales/en/messages.json):
{
"extensionName": {
"message": "Notify link clicks i18n",
"description": "Name of the extension."
},
"extensionDescription": {
"message": "Shows a notification when the user clicks on links.",
"description": "Description of the extension."
},
"notificationTitle": {
"message": "Click notification",
"description": "Title of the click notification."
},
"notificationContent": {
"message": "You clicked $URL$.",
"description": "Tells the user which link they clicked.",
"placeholders": {
"url": {
"content": "$1",
"example": "https://developer.mozilla.org"
}
}
}
}
Diese Datei ist standardmäßiges JSON — jedes ihrer Mitglieder ist ein Objekt mit einem Namen, das eine message
und eine description
enthält. Alle diese Elemente sind Strings; $URL$
ist ein Platzhalter, der durch einen Teilstring ersetzt wird, wenn das notificationContent
-Mitglied von der Erweiterung aufgerufen wird. Sie erfahren, wie das im Abschnitt Abrufen von Nachrichtenstrings aus JavaScript funktioniert.
Hinweis:
Sie können viel mehr Informationen über den Inhalt von messages.json
Dateien in unserem verzeichnis-spezifische Nachrichtenreferenz finden.
Internationalisieren von manifest.json
Es gibt ein paar verschiedene Aufgaben, die Sie durchführen sollten, um Ihre manifest.json zu internationalisieren.
Abrufen lokalisierter Strings in Manifests
Ihre manifest.json enthält Strings, die dem Benutzer angezeigt werden, wie z.B. den Namen und die Beschreibung der Erweiterung. Wenn Sie diese Strings internationalisieren und die entsprechenden Übersetzungen davon in messages.json setzen, wird dem Benutzer die richtige Übersetzung des Strings basierend auf der aktuellen Locale angezeigt, wie folgt.
Um Strings zu internationalisieren, spezifizieren Sie sie so:
"name": "__MSG_extensionName__",
"description": "__MSG_extensionDescription__",
Hierbei rufen wir nachrichtenabhängige Strings ab, abhängig von der Locale des Browsers anstatt nur statische Strings einzufügen.
Um einen Nachrichtenstring so aufzurufen, müssen Sie ihn so angeben:
- Zwei Unterstriche, gefolgt von
- Dem String "MSG", gefolgt von
- Einem Unterstrich, gefolgt von
- Dem Namen der Nachricht, die Sie aufrufen möchten, wie in
messages.json
definiert, gefolgt von - Zwei Unterstriche
__MSG_ + messageName + __
Spezifikation einer Standardlocale
Ein weiteres Feld, das Sie in Ihrer manifest.json spezifizieren sollten, ist default_locale:
"default_locale": "en"
Dies spezifiziert eine Standardlocale, die verwendet wird, wenn die Erweiterung keinen lokalisierten String für die aktuelle Locale des Browsers enthält. Alle Nachrichtenstrings, die nicht in der Browser-Locale verfügbar sind, werden stattdessen aus der Standardlocale bezogen. Es gibt einige weitere Details, die in Bezug darauf, wie der Browser Strings auswählt, zu beachten sind — siehe Lokalisierte String-Auswahl.
Lokalspezifische CSS
Beachten Sie, dass Sie auch lokalisierte Strings aus CSS-Dateien in der Erweiterung abrufen können. Zum Beispiel möchten Sie möglicherweise eine lokalspezifische CSS-Regel wie diese erstellen:
header {
background-image: url(../images/__MSG_extensionName__/header.png);
}
Dies ist nützlich, obwohl Sie in einer solchen Situation besser mit vordefinierten Nachrichten umgehen.
Abrufen von Nachrichtenstrings aus JavaScript
Also, Sie haben Ihre Nachrichtenstrings eingerichtet und Ihr Manifest. Jetzt müssen Sie nur noch beginnen, Ihre Nachrichtenstrings aus JavaScript aufzurufen, sodass Ihre Erweiterung möglichst die richtige Sprache verwendet. Die tatsächliche i18n API ist ziemlich einfach und enthält nur vier Hauptmethoden:
- Sie werden vermutlich
i18n.getMessage()
am häufigsten verwenden — dies ist die Methode, die Sie zur Abrufung eines spezifischen Sprachstrings verwenden, wie oben erwähnt. Beispiele für die spezifische Nutzung werden unten gezeigt. - Die Methoden
i18n.getAcceptLanguages()
undi18n.getUILanguage()
können verwendet werden, wenn Sie die Benutzeroberfläche je nach Locale anpassen möchten — möglicherweise möchten Sie Präferenzen, die spezifisch für die bevorzugten Sprachen der Benutzer sind, weiter oben in einer Präferenzliste anzeigen oder kulturelle Informationen anzeigen, die nur für eine bestimmte Sprache relevant sind, oder angezeigte Daten gemäß der Browser-Local formatieren. - Die Methode
i18n.detectLanguage()
könnte verwendet werden, um die Sprache von benutzerübermitteltem Inhalt zu erkennen und sie entsprechend zu formatieren.
In unserem Beispiel notify-link-clicks-i18n enthält das Hintergrundskript die folgenden Zeilen:
let title = browser.i18n.getMessage("notificationTitle");
let content = browser.i18n.getMessage("notificationContent", message.url);
Die erste Zeile ruft einfach das notificationTitle message
Feld aus der verfügbaren messages.json
Datei ab, die am besten zur aktuellen Locale des Browsers passt. Die zweite ist ähnlich, aber es wird eine URL als zweiter Parameter übergeben. Was steckt dahinter? So geben Sie den Inhalt an, um den $URL$
Platzhalter zu ersetzen, den wir im notificationContent message
Feld sehen:
"notificationContent": {
"message": "You clicked $URL$.",
"description": "Tells the user which link they clicked.",
"placeholders": {
"url" : {
"content" : "$1",
"example" : "https://developer.mozilla.org"
}
}
}
Das "placeholders"
-Mitglied definiert alle Platzhalter, und woher sie abgerufen werden. Der "url"
Platzhalter spezifiziert, dass sein Inhalt von $1
abgerufen wird, das der erste Wert innerhalb des zweiten Parameters von getMessage()
ist. Da der Platzhalter "url"
genannt wird, verwenden wir $URL$
, um ihn innerhalb des eigentlichen Nachrichtenstrings aufzurufen (für "name"
würden Sie $NAME$
verwenden, usw.). Wenn Sie mehrere Platzhalter haben, können Sie sie in einem Array angeben, das als zweiter Parameter an i18n.getMessage()
übergeben wird — [a, b, c]
werden als $1
, $2
und $3
verfügbar sein, und so weiter, innerhalb von messages.json
.
Lassen Sie uns ein Beispiel durchgehen: der ursprüngliche notificationContent
Nachrichtenstring in der en/messages.json
Datei ist
You clicked $URL$.
Angenommen, der angeklickte Link zeigt auf https://developer.mozilla.org
. Nach dem Aufruf von i18n.getMessage()
, werden die Inhalte des zweiten Parameters in messages.json als $1
verfügbar gemacht, das den $URL$
-Platzhalter ersetzt, wie im "url"
Platzhalter definiert. Der endgültige Nachrichtenstring ist dann
You clicked https://developer.mozilla.org.
Direkte Platzhalterverwendung
Es ist möglich, Ihre Variablen ($1
, $2
, $3
, usw.) direkt in den Nachrichtenstrings einzufügen, zum Beispiel könnten wir das oben aufgeführte "notificationContent"
-Mitglied so umschreiben:
"notificationContent": {
"message": "You clicked $1.",
"description": "Tells the user which link they clicked."
}
Dies mag schneller und weniger komplex erscheinen, aber die andere Methode (die Verwendung von "placeholders"
) wird als Best Practice angesehen. Der Grund dafür ist, dass der Platzhaltername (z.B. "url"
) und das Beispiel Ihnen helfen, sich zu merken, wofür der Platzhalter gedacht ist — eine Woche nachdem Sie Ihren Code geschrieben haben, werden Sie wahrscheinlich vergessen haben, worum es sich bei $1
– `$8$ handelt, aber Sie werden eher wissen, auf was sich Ihre Platzhalternamen beziehen.
Harte Kodierung von Ersetzungen
Es ist auch möglich, in Platzhaltern fest kodierte Strings zu verwenden, so dass jedes Mal derselbe Wert verwendet wird, anstatt den Wert von einer Variable in Ihrem Code zu erhalten. Zum Beispiel:
"mdn_banner": {
"message": "For more information on web technologies, go to $MDN$.",
"description": "Tell the user about MDN",
"placeholders": {
"mdn": {
"content": "https://developer.mozilla.org/"
}
}
}
In diesem Fall kodieren wir den Platzhalterinhalt einfach fest, anstatt ihn von einem Variablenwert wie $1
abzurufen. Dies kann manchmal nützlich sein, wenn Ihre Nachrichten-Datei sehr komplex ist, und Sie möchten, dass verschiedene Werte aufgeteilt werden, um die Strings in der Datei lesbarer zu machen, außerdem könnten diese Werte dann programmatisch abgerufen werden.
Darüber hinaus können Sie solche Ersetzungen verwenden, um Teile des Strings zu spezifizieren, die nicht übersetzt werden sollen, wie Personen- oder Firmennamen.
Lokalisierte String-Auswahl
Locales können unter Verwendung eines Sprachcodes wie fr
oder en
oder mit einem Skript- und Region-Code wie en-US
oder zh-Hans-CN
angegeben werden. Wenn Ihre Erweiterung das i18n-System nach einem String fragt, wählt es einen String mithilfe dieses Algorithmus aus:
- Gibt den String zurück, wenn es eine
messages.json
Datei für die Locale des Browsers des Benutzers gibt, die den String enthält. Zum Beispiel, wenn der Benutzer seinen Browser aufen-US
eingestellt hat und die Erweiterung die_locales/en_US/messages.json
Datei bereitstellt. - Andernfalls, wenn die Browser-Local mit einem Script oder einer Region qualifiziert ist (z.B.
en-US
oderzh-Hans-CN
) und es einemessages.json
-Datei für die regionenlose Version und ohne das Skript dieser Locale gibt und diese Datei den String enthält, dann geben Sie ihn zurück. Zum Beispiel, wenn der Benutzer seinen Browser aufzh-Hans-CN
eingestellt hat (und es keine_locales/zh_Hans_CN/messages.json
Datei gibt), sucht das i18n-System nach einem String inzh-Hans
, und wenn das nicht verfügbar ist, inzh.
- Falls dies nicht der Fall ist, ob es eine
messages.json
Datei für diedefault_locale
gibt, die inmanifest.json
definiert ist, und sie den String enthält, dann geben Sie ihn zurück. - Andernfalls geben Sie einen leeren String zurück.
Nehmen Sie dieses Beispiel:
-
extension-root-directory/
-
_locales
-
en_GB
-
messages.json
{ "colorLocalized": { "message": "colour", "description": "Color." }, /* … */ }
en
-
messages.json
{ "colorLocalized": { "message": "color", "description": "Color." }, /* … */ }
-
-
fr
-
messages.json
{ "colorLocalized": { "message": "couleur", "description": "Color." }, /* … */}
-
-
-
Angenommen, die default_locale
ist auf fr
gesetzt.
- Wenn die Browser-Local
en-GB
ist, wenn die ErweiterunggetMessage("colorLocalized")
aufruft, wird "colour" zurückgegeben, weil_locales/en_GB/messages.json
diecolorLocalized
-Nachricht enthält. - Wenn die Browser-Local
en-US
ist, wenn die ErweiterunggetMessage("colorLocalized")
aufruft, wird "color" zurückgegeben, weil sie auf die Nachricht in_locales/en/messages.json
zurückgreift. - Wenn die Browser-Local
zh-Hans-CN
ist, wenn die ErweiterunggetMessage("colorLocalized")
aufruft, wird "couleur" zurückgegeben, da es keine Sprache, kein Skript oder keine regionale Übereinstimmung mit derzh-Hans-CN
-Locale gibt.
Vordefinierte Nachrichten
Das i18n-Modul bietet uns einige vordefinierte Nachrichten, die wir auf die gleiche Weise aufrufen können wie wir es zuvor in Abrufen lokalisierter Strings in Manifesten und Durch Locale beeinflusste CSS gesehen haben. Zum Beispiel:
__MSG_extensionName__
Vordefinierte Nachrichten verwenden genau die gleiche Syntax, außer mit @@
vor dem Nachrichtennamen, zum Beispiel
__MSG_@@ui_locale__
Die folgende Tabelle zeigt die verschiedenen verfügbaren vordefinierten Nachrichten:
Nachrichtenname | Beschreibung |
---|---|
@@extension_id |
Die intern generierte UUID der Erweiterung. Sie könnten diesen String verwenden, um URLs für Ressourcen innerhalb der Erweiterung zu konstruieren. Auch nicht lokalisierte Erweiterungen können diese Nachricht verwenden. Sie können diese Nachricht nicht in einer Manifestdatei verwenden.
Beachten Sie auch, dass diese ID nicht die Add-on-ID ist, die durch
|
@@ui_locale |
Die aktuelle Lokalisierung; Sie könnten diesen String verwenden, um lokalspezifische URLs zu konstruieren. |
@@bidi_dir |
Die Textrichtung für die aktuelle Lokalisierung, entweder "ltr" für von links nach rechts gerichtete Sprachen wie Englisch oder "rtl" für von rechts nach links gerichtete Sprachen wie Arabisch. |
@@bidi_reversed_dir |
Wenn das @@bidi_dir "ltr" ist, dann ist es "rtl"; ansonsten
ist es "ltr".
|
@@bidi_start_edge |
Wenn das @@bidi_dir "ltr" ist, dann ist es "left"; ansonsten
ist es "right".
|
@@bidi_end_edge |
Wenn das @@bidi_dir "ltr" ist, dann ist es "right";
ansonsten ist es "left".
|
Zurück zu unserem früheren Beispiel wäre es sinnvoller, es so zu schreiben:
header {
background-image: url(../images/__MSG_@@ui_locale__/header.png);
}
Nun können wir unsere lokalspezifischen Bilder einfach in Verzeichnissen speichern, die den verschiedenen unterstützten Lokalitäten entsprechen — en, de, etc. — was viel mehr Sinn macht.
Schauen wir uns ein Beispiel für die Verwendung von @@bidi_*
Nachrichten in einer CSS-Datei an:
body {
direction: __MSG_@@bidi_dir__;
}
div#header {
margin-bottom: 1.05em;
overflow: hidden;
padding-bottom: 1.5em;
padding-__MSG_@@bidi_start_edge__: 0;
padding-__MSG_@@bidi_end_edge__: 1.5em;
position: relative;
}
Für von links nach rechts gerichtete Sprachen wie Englisch, würden die CSS-Erklärungen, die die oben genannten vordefinierten Nachrichten verwenden, zu den folgenden endgültigen Codezeilen übersetzt:
direction: ltr;
padding-left: 0;
padding-right: 1.5em;
Für eine von rechts nach links gerichtete Sprache wie Arabisch, würden Sie erhalten:
direction: rtl;
padding-right: 0;
padding-left: 1.5em;
Testen Ihrer Erweiterung
Um die Lokalisierung Ihrer Erweiterung zu testen, verwenden Sie Firefox oder Firefox Beta, die Firefox-Builds, in denen Sie Sprachpakete installieren können.
Dann, für jede in der Erweiterung unterstützte Locale, die Sie testen möchten, folgen Sie den Anweisungen zur Verwendung von Firefox in einer anderen Sprache, um die Firefox-UI-Sprache zu wechseln. (Wenn Sie sich in den Einstellungen auskennen, verwenden Sie unter Sprache die Option Alternativen festlegen.)
Wenn Firefox in Ihrer Testsprache ausgeführt wird, installieren Sie von about:debugging
aus die Erweiterung vorübergehend oder laden Sie sie neu, wenn sie bereits installiert ist. Nach der Installation oder dem Neuladen Ihrer Erweiterung, wenn Sie Ihre Erweiterung korrekt eingerichtet haben, sehen Sie die Erweiterung mit ihrem Symbol, ihrem Namen und ihrer Beschreibung in der gewählten Sprache aufgelistet. Sie können auch die lokalisierten Erweiterungsdetails unter about:addons
sehen. Üben Sie die Funktionen der Erweiterung aus, um sicherzustellen, dass die Übersetzungen vorhanden sind.
Wenn Sie diesen Prozess ausprobieren möchten, können Sie die notify-link-clicks-i18n Erweiterung verwenden. Richten Sie Firefox so ein, dass eine der in diesem Beispiel unterstützten Sprachen (Deutsch, Niederländisch oder Japanisch) angezeigt wird. Laden Sie die Erweiterung und gehen Sie auf eine Website. Klicken Sie auf einen Link, um die übersetzte Version der Benachrichtigung zu sehen, die die URL des Links angibt.