Zum Hauptinhalt springen

Intl MessageFormat

Inoffizielle Beta-Übersetzung

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.

npm Version intl-messageformat minzipped size

Ü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.

Zukünftige Änderungen

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.:

Live Editor
new IntlMessageFormat(
  `{numPhotos, plural,
      =0 {You have no photos.}
      =1 {You have one photo.}
      other {You have # photos.}
    }`,
  'en-US'
).format({numPhotos: 1000})
Result
Live Editor
new IntlMessageFormat(
  `{numPhotos, plural,
      =0 {Usted no tiene fotos.}
      =1 {Usted tiene una foto.}
      other {Usted tiene # fotos.}
    }`,
  'es-ES'
).format({numPhotos: 1000})
Result

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.NumberFormat bzw. Intl.DateTimeFormat.

  • Optimiert für wiederholte Aufrufe der format()-Methode einer IntlMessageFormat-Instanz.

  • Ermöglicht benutzerdefinierte Formatstile/-optionen.

  • Unterstützt Escape-Sequenzen für Syntaxzeichen, z. B.: "'{foo}'" gibt "{foo}" aus statt es als foo-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:

  1. Intl.NumberFormat für Zahlenformatierung (kann via @formatjs/intl-numberformat gepolyfilled werden)

  2. Intl.DateTimeFormat für die Formatierung von Datum und Uhrzeit (kann mittels @formatjs/intl-datetimeformat polygefillt werden)

  3. Intl.PluralRules fü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). Bei false sind 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:

Live Editor
new IntlMessageFormat('', 'en-us').resolvedOptions().locale
Result

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:

Live Editor
new IntlMessageFormat('My name is {name}.', 'en-US').format({name: 'Eric'})
Result
Platzhalter

Es muss für jedes Argument im Nachrichtenmuster ein Wert bereitgestellt werden.

Rich-Text-Unterstützung

Live Editor
new IntlMessageFormat('hello <b>world</b>', 'en').format({
  b: chunks => <strong>{chunks}</strong>,
})
Result

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:

  1. Attribute in HTML-Tags werden ignoriert.

  2. Selbstschließende Tags werden als literale Zeichenketten behandelt und sind nicht unterstützt; verwenden Sie stattdessen normale ICU-Platzhalter wie {placeholder}.

  3. Alle spezifizierten Tags benötigen entsprechende Werte - Fehlende Werte führen zu Fehlern, z.B:

Live Editor
function () {
  try {
    return new IntlMessageFormat('a <foo>strong</foo>').format()
  } catch (e) {
    return String(e)
  }
}
Result
  1. XML/HTML-Tags werden mittels Apostroph maskiert wie andere ICU-Konstrukte. Beispiele zur Maskierung:
Live Editor
new IntlMessageFormat("I '<'3 cats").format()
Result
Live Editor
new IntlMessageFormat("raw '<b>HTML</b>'").format()
Result
Live Editor
new IntlMessageFormat("raw '<b>HTML</b>' with '<a>'{placeholder}'</a>'").format(
  {placeholder: 'some word'}
)
Result
  1. 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:

Live Editor
new IntlMessageFormat(
  'The price is: {price, number, ::currency/EUR}',
  'en-GB'
).format({price: 100})
Result

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:

SymbolMeaningNotes
GEra designator
yyear
Mmonth in year
Lstand-alone month in year
dday in month
Eday of week
elocal day of weeke..eee is not supported
cstand-alone local day of weekc..ccc is not supported
aAM/PM marker
hHour [1-12]
HHour [0-23]
KHour [0-11]
kHour [1-24]
mMinute
sSecond
zTime Zone

Beispiel:

Live Editor
new IntlMessageFormat('Today is: {now, date, ::yyyyMMdd}', 'en-GB').format({
  now: new Date(),
})
Result

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)