Intl MessageFormat
Diese Seite wurde von PageTurner AI übersetzt (Beta). Nicht offiziell vom Projekt unterstützt. Fehler gefunden? Problem melden →
Formatiert ICU-Message-Strings mit Platzhaltern für Zahlen, Datum, Plural und Select, um lokalisierte Nachrichten zu erstellen.
Übersicht
Ziele
Dieses Paket bietet eine Möglichkeit, String-Nachrichten Ihrer JavaScript-Anwendung zu verwalten und in lokalisierte Strings für Ihre Nutzer zu formatieren. Sie können dieses Paket sowohl im Browser als auch auf dem Server via Node.js verwenden.
Diese Implementierung basiert auf dem Strawman-Vorschlag, weicht jedoch an einigen Stellen davon ab.
Diese IntlMessageFormat-API kann sich ändern, um mit ECMA-402 synchron zu bleiben, aber das Paket folgt semver.
Funktionsweise
Nachrichten werden dem Konstruktor als String-Nachricht oder als vorab geparstes AST-Objekt übergeben.
const msg = new IntlMessageFormat(message, locales, [formats], [opts])
Der String message wird geparst und intern in einer kompilierten Form gespeichert, die für die format()-Methode optimiert ist, um den formatierten String für die Benutzerausgabe zu erzeugen.
const output = msg.format(values)
Häufiges Anwendungsbeispiel
Ein typisches Beispiel ist die Formatierung von Nachrichten mit Zahlen und Pluralformen. Mit diesem Paket stellen Sie sicher, dass der String korrekt für das Gebietsschema der Person formatiert wird, z. B.:
new IntlMessageFormat( `{numPhotos, plural, =0 {You have no photos.} =1 {You have one photo.} other {You have # photos.} }`, 'en-US' ).format({numPhotos: 1000})
new IntlMessageFormat( `{numPhotos, plural, =0 {Usted no tiene fotos.} =1 {Usted tiene una foto.} other {Usted tiene # fotos.} }`, 'es-ES' ).format({numPhotos: 1000})
Nachrichtensyntax
Die Nachrichtensyntax dieses Pakets ist nicht proprietär – es handelt sich um einen branchenüblichen Standard, der sprachübergreifend funktioniert und professionellen Übersetzern vertraut ist. Dieses Paket verwendet die ICU Message-Syntax und funktioniert für alle CLDR-Sprachen mit definierten Pluralisierungsregeln.
Funktionen
-
Verwendet Branchenstandards: ICU Message-Syntax und CLDR-Lokalisierungsdaten.
-
Unterstützt plural-, select- und selectordinal-Nachrichtenargumente.
-
Formatiert Zahlen und Datums-/Zeitangaben in Nachrichten via
Intl.NumberFormatbzw.Intl.DateTimeFormat. -
Optimiert für wiederholte Aufrufe der
format()-Methode einerIntlMessageFormat-Instanz. -
Ermöglicht benutzerdefinierte Formatstile/-optionen.
-
Unterstützt Escape-Sequenzen für Syntaxzeichen, z. B.:
"'{foo}'"gibt"{foo}"aus statt es alsfoo-Argument zu interpretieren.
Verwendung
Moderne Intl-Abhängigkeit
Dieses Paket setzt voraus, dass das globale Intl-Objekt in der Laufzeitumgebung existiert. Intl ist in allen modernen Browsern (IE11+) und Node.js (mit vollständiger ICU) vorhanden. Genutzte Intl-Methoden:
-
Intl.NumberFormatfür Zahlenformatierung (kann via @formatjs/intl-numberformat gepolyfilled werden) -
Intl.DateTimeFormatfür die Formatierung von Datum und Uhrzeit (kann mittels @formatjs/intl-datetimeformat polygefillt werden) -
Intl.PluralRulesfür Plural-/Ordinalformatierung (kann mittels @formatjs/intl-pluralrules polygefillt werden)
Laden von Intl MessageFormat im Browser
<script src="intl-messageformat/intl-messageformat.min.js"></script>
Laden von Intl MessageFormat in Node.js
Entweder:
import IntlMessageFormat from 'intl-messageformat'
const IntlMessageFormat = require('intl-messageformat').default
HINWEIS: Ihr Node muss full ICU enthalten
Öffentliche API
IntlMessageFormat-Konstruktor
Zur Erstellung einer zu formatierenden Nachricht verwenden Sie den IntlMessageFormat-Konstruktor. Dieser nimmt drei Parameter entgegen:
-
message: string | AST- Zeichenketten-Nachricht (oder vorab geparster AST), die als Formatierungsmuster dient. -
locales: string | string[]- Zeichenkette mit BCP-47-Sprachtag oder Array solcher Zeichenketten. Ohne Angabe wird die Standardlocale verwendet. Bei Arrays werden alle Einträge und deren übergeordnete Locales geprüft; die erste mit registrierten Lokalisierungsdaten wird verwendet. Details siehe: Locale-Auflösung. -
formats?: object- Optionales Objekt mit benutzerdefinierten Formatstilen. -
opts?: { formatters?: Formatters, ignoreTag?: boolean }- Optionale Optionen.formatters: Map mit zwischengespeicherten Formatierern für bessere Performance.ignoreTag: Ob HTML/XML-Tags als literale Zeichenketten behandelt werden sollen (statt als Tag-Token). Beifalsesind nur einfache Tags ohne Attribute erlaubt.
const msg = new IntlMessageFormat('My name is {name}.', 'en-US')
Locale-Auflösung
IntlMessageFormat nutzt Intl.NumberFormat.supportedLocalesOf(), um basierend auf dem locales-Wert die passenden Lokalisierungsdaten zu bestimmen. Das Ergebnis kann über die Methode resolvedOptions() abgefragt werden.
resolvedOptions()-Methode
Diese Methode gibt ein Objekt mit den bei der Instanzerstellung aufgelösten Optionen zurück. Aktuell enthält es nur die Eigenschaft locale; Beispiel:
new IntlMessageFormat('', 'en-us').resolvedOptions().locale
Beachten Sie, wie die angegebene Locale "en-us" (kleingeschrieben) aufgelöst und normalisiert zu "en-US" wurde.
format(values)-Methode
Nach Erstellung der Nachricht erfolgt die Formatierung durch Aufruf der format()-Methode mit einer Sammlung von values:
new IntlMessageFormat('My name is {name}.', 'en-US').format({name: 'Eric'})
Es muss für jedes Argument im Nachrichtenmuster ein Wert bereitgestellt werden.
Rich-Text-Unterstützung
new IntlMessageFormat('hello <b>world</b>', 'en').format({ b: chunks => <strong>{chunks}</strong>, })
Wir unterstützen eingebettete XML-Tags in Nachrichten, z.B. this is a <b>strong</b> tag. Dies dient nicht als vollwertige HTML-Einbettung, sondern zur Kontextmarkierung von Textabschnitten für Übersetzungen. Daher gelten folgende Einschränkungen:
-
Attribute in HTML-Tags werden ignoriert.
-
Selbstschließende Tags werden als literale Zeichenketten behandelt und sind nicht unterstützt; verwenden Sie stattdessen normale ICU-Platzhalter wie
{placeholder}. -
Alle spezifizierten Tags benötigen entsprechende Werte - Fehlende Werte führen zu Fehlern, z.B:
function () { try { return new IntlMessageFormat('a <foo>strong</foo>').format() } catch (e) { return String(e) } }
- XML/HTML-Tags werden mittels Apostroph maskiert wie andere ICU-Konstrukte. Beispiele zur Maskierung:
new IntlMessageFormat("I '<'3 cats").format()
new IntlMessageFormat("raw '<b>HTML</b>'").format()
new IntlMessageFormat("raw '<b>HTML</b>' with '<a>'{placeholder}'</a>'").format( {placeholder: 'some word'} )
- Eingebettete gültige HTML-Tags sind derzeit eine Grauzone, da wir nicht den vollständigen HTML/XHTML/XML-Standard unterstützen.
getAst-Methode
Gibt den zugrundeliegenden AST der kompilierten Nachricht zurück.
Datum/Zeit/Zahlen-Skelett
Wir unterstützen ICU-Zahlenskelette und eine Teilmenge von Datum/Zeit-Skeletten für weitergehende Anpassungen von Formaten.
Zahlen-Skelett
Beispiel:
new IntlMessageFormat( 'The price is: {price, number, ::currency/EUR}', 'en-GB' ).format({price: 100})
Eine vollständige Übersicht der Optionen und Syntax finden Sie hier
Datum/Zeit-Skelett
ICU bietet eine Vielzahl von Mustern zur Anpassung von Datums- und Zeitformaten. Allerdings sind nicht alle über die ECMA402 Intl API verfügbar. Daher unterstützt unser Parser nur folgende Muster:
| Symbol | Meaning | Notes |
|---|---|---|
| G | Era designator | |
| y | year | |
| M | month in year | |
| L | stand-alone month in year | |
| d | day in month | |
| E | day of week | |
| e | local day of week | e..eee is not supported |
| c | stand-alone local day of week | c..ccc is not supported |
| a | AM/PM marker | |
| h | Hour [1-12] | |
| H | Hour [0-23] | |
| K | Hour [0-11] | |
| k | Hour [1-24] | |
| m | Minute | |
| s | Second | |
| z | Time Zone |
Beispiel:
new IntlMessageFormat('Today is: {now, date, ::yyyyMMdd}', 'en-GB').format({ now: new Date(), })
Erweiterte Anwendung
Übergeben von AST
Sie können vorgeparste ASTs wie folgt an IntlMessageFormat übergeben:
new IntlMessageFormat('hello').format() // prints out hello
// is equivalent to
import IntlMessageFormat from 'intl-messageformat'
import {parse} from '@formatjs/icu-messageformat-parser'
new IntlMessageFormat(parse('hello')).format() // prints out hello
Dies verbessert die Performance bei SSR oder Plattformen mit Preload/Precompilation-Unterstützung, da AST zwischengespeichert werden kann.
Falls alle Ihre Nachrichten als ASTs vorliegen, können Sie @formatjs/icu-messageformat-parser als {default: undefined} aliasen, um Bundling-Größe zu sparen.
Formatierer
Bei komplexen Nachrichten kann die Initialisierung von Intl.*-Konstruktoren aufwändig sein. Daher ermöglichen wir das Übergeben von formatters zur Bereitstellung gememoizierter Intl-Instanzen. Dieser Ansatz kombiniert mit AST-Übergabe und fast-memoize kann die Geschwindigkeit laut nachfolgendem Benchmark um das 30-fache steigern.
Beispiel:
import IntlMessageFormat from 'intl-messageformat'
import {memoize} from '@formatjs/fast-memoize'
const formatters = {
getNumberFormat: memoize(
(locale, opts) => new Intl.NumberFormat(locale, opts)
),
getDateTimeFormat: memoize(
(locale, opts) => new Intl.DateTimeFormat(locale, opts)
),
getPluralRules: memoize((locale, opts) => new Intl.PluralRules(locale, opts)),
}
new IntlMessageFormat('hello {number, number}', 'en', undefined, {
formatters,
}).format({number: 3}) // prints out `hello, 3`
Benchmark
format_cached_complex_msg x 153,868 ops/sec ±1.13% (85 runs sampled)
format_cached_string_msg x 21,661,621 ops/sec ±4.06% (84 runs sampled)
new_complex_msg_preparsed x 719,056 ops/sec ±2.83% (78 runs sampled)
new_complex_msg x 12,844 ops/sec ±1.97% (85 runs sampled)
new_string_msg x 409,770 ops/sec ±2.57% (79 runs sampled)
complex msg format x 12,065 ops/sec ±1.66% (81 runs sampled)
complex msg w/ formatters format x 11,649 ops/sec ±2.05% (78 runs sampled)
complex preparsed msg w/ formatters format x 597,153 ops/sec ±1.46% (90 runs sampled)
complex preparsed msg w/ new formatters format x 684,263 ops/sec ±1.37% (89 runs sampled)