Wie zeige ich Skriptnamen wie Lateinisch, Kyrillisch, Arabisch an?

Verwenden Sie Intl.DisplayNames, um Skriptcodes in menschenlesbare Namen für Schriftsysteme in jeder Sprache umzuwandeln.

Einführung

Ein Skript ist ein Schriftsystem. Latein ist das Skript, das für Englisch, Französisch und Spanisch verwendet wird. Kyrillisch ist das Skript, das für Russisch, Bulgarisch und Ukrainisch verwendet wird. Arabisch ist das Skript, das für Arabisch, Persisch und Urdu verwendet wird. Skripte unterscheiden sich von Sprachen, da dieselbe Sprache in mehreren Skripten geschrieben werden kann. Serbisch verwendet sowohl kyrillische als auch lateinische Skripte. Benutzer in Serbien wählen, welches Skript sie bevorzugen.

Wenn Sie Sprachauswahlen, Schriftartauswahlen oder Texteingabesteuerungen erstellen, müssen Sie Skriptnamen anzeigen, damit Benutzer Schriftsysteme identifizieren können. Die Intl.DisplayNames-API konvertiert Skriptcodes in lokalisierte, menschenlesbare Namen, ohne dass Sie Übersetzungstabellen pflegen müssen.

Verständnis von Skripten und Sprachen

Skripte und Sprachen sind nicht dasselbe. Eine Sprache ist das, was Menschen sprechen. Ein Skript ist, wie Menschen sie schreiben.

Englisch ist eine Sprache. Latein ist ein Skript. Englisch verwendet das lateinische Skript, aber auch Dutzende anderer Sprachen, darunter Spanisch, Französisch, Deutsch, Vietnamesisch und Türkisch.

Serbisch ist eine Sprache, die in zwei Skripten geschrieben werden kann. Serbisch in kyrillischer Schrift sieht aus wie "Српски". Serbisch in lateinischer Schrift sieht aus wie "Srpski". Beide repräsentieren dieselbe Sprache mit denselben Wörtern und derselben Grammatik. Der Unterschied liegt nur im Schriftsystem.

Chinesisch hat zwei gängige Skriptvarianten. Vereinfachtes Chinesisch verwendet vereinfachte Han-Zeichen. Traditionelles Chinesisch verwendet traditionelle Han-Zeichen. Derselbe Satz erscheint je nach verwendetem Skript unterschiedlich.

Diese Unterscheidung ist wichtig beim Erstellen von Benutzeroberflächen. Ein serbischer Benutzer könnte kyrillischen Text gegenüber lateinischem Text bevorzugen. Ein chinesischer Benutzer muss zwischen vereinfachten und traditionellen Zeichen wählen. Ihre Benutzeroberfläche muss Skriptnamen anzeigen, damit Benutzer diese Auswahl treffen können.

Das Problem mit hartcodierten Skriptnamen

Sie können eine Lookup-Tabelle erstellen, die Skriptcodes zu Skriptnamen zuordnet.

const scriptNames = {
  Latn: "Latin",
  Cyrl: "Cyrillic",
  Arab: "Arabic",
  Hans: "Simplified Chinese",
  Hant: "Traditional Chinese"
};

console.log(scriptNames.Latn);
// "Latin"

Dieser Ansatz funktioniert nur für englischsprachige Benutzer. Benutzer, die andere Sprachen sprechen, sehen englische Skriptnamen, die sie möglicherweise nicht verstehen. Sie benötigen Übersetzungen für jede Sprache, die Sie unterstützen.

const scriptNames = {
  en: {
    Latn: "Latin",
    Cyrl: "Cyrillic",
    Arab: "Arabic"
  },
  es: {
    Latn: "latino",
    Cyrl: "cirílico",
    Arab: "árabe"
  },
  fr: {
    Latn: "latin",
    Cyrl: "cyrillique",
    Arab: "arabe"
  }
};

Dies wird schnell unwartbar. Jede neue Sprache erfordert einen vollständigen Satz von Übersetzungen. Jedes neue Skript erfordert Einträge in jeder Sprache. Sie benötigen eine bessere Lösung.

Verwendung von Intl.DisplayNames zur Ermittlung von Skriptnamen

Der Konstruktor Intl.DisplayNames erstellt einen Formatierer, der Skriptcodes in menschenlesbare Namen umwandelt. Sie geben eine Locale an und setzen den Typ auf "script".

const names = new Intl.DisplayNames(["en"], { type: "script" });
console.log(names.of("Latn"));
// "Latin"

Das erste Argument ist ein Array von Locale-Identifikatoren. Das zweite Argument ist ein Options-Objekt, wobei type: "script" dem Formatierer mitteilt, dass Sie Skriptnamen wünschen. Die Methode of() nimmt einen Skriptcode entgegen und gibt dessen Namen zurück.

Skriptcodes folgen dem ISO 15924-Standard. Jedes Skript hat einen vierstelligen Code, wobei der erste Buchstabe großgeschrieben und die restlichen drei Buchstaben kleingeschrieben sind. Lateinisch ist Latn. Kyrillisch ist Cyrl. Arabisch ist Arab.

const names = new Intl.DisplayNames(["en"], { type: "script" });

console.log(names.of("Latn"));
// "Latin"

console.log(names.of("Cyrl"));
// "Cyrillic"

console.log(names.of("Arab"));
// "Arabic"

console.log(names.of("Hani"));
// "Han"

console.log(names.of("Hira"));
// "Hiragana"

console.log(names.of("Kana"));
// "Katakana"

Der Formatierer übernimmt die gesamte Komplexität der Verwaltung von Skriptnamen-Übersetzungen. Sie müssen nur den Skriptcode angeben.

Häufige Skriptcodes

Der ISO 15924-Standard definiert Codes für über 160 Schriftsysteme. Dies sind die am häufigsten verwendeten Codes.

const names = new Intl.DisplayNames(["en"], { type: "script" });

console.log(names.of("Latn"));
// "Latin"

console.log(names.of("Cyrl"));
// "Cyrillic"

console.log(names.of("Arab"));
// "Arabic"

console.log(names.of("Hebr"));
// "Hebrew"

console.log(names.of("Deva"));
// "Devanagari"

console.log(names.of("Thai"));
// "Thai"

console.log(names.of("Hani"));
// "Han"

console.log(names.of("Hans"));
// "Simplified Han"

console.log(names.of("Hant"));
// "Traditional Han"

console.log(names.of("Hang"));
// "Hangul"

console.log(names.of("Hira"));
// "Hiragana"

console.log(names.of("Kana"));
// "Katakana"

console.log(names.of("Beng"));
// "Bengali"

console.log(names.of("Grek"));
// "Greek"

Lateinisch (Latn) deckt die meisten westeuropäischen Sprachen ab. Kyrillisch (Cyrl) deckt Russisch, Bulgarisch, Ukrainisch und andere slawische Sprachen ab. Arabisch (Arab) deckt Arabisch, Persisch und Urdu ab. Han (Hani) deckt Chinesisch ab, mit Hans für vereinfachtes Chinesisch und Hant für traditionelles Chinesisch. Hangul (Hang) deckt Koreanisch ab. Hiragana und Katakana sind japanische Schriftsysteme.

Anzeigen von Skriptnamen in verschiedenen Locales

Skriptnamen werden basierend auf der Anzeigesprache lokalisiert. Erstellen Sie Formatierer mit verschiedenen Locales, um Namen in verschiedenen Sprachen zu sehen.

const enNames = new Intl.DisplayNames(["en"], { type: "script" });
const esNames = new Intl.DisplayNames(["es"], { type: "script" });
const frNames = new Intl.DisplayNames(["fr"], { type: "script" });
const jaNames = new Intl.DisplayNames(["ja"], { type: "script" });

console.log(enNames.of("Latn"));
// "Latin"

console.log(esNames.of("Latn"));
// "latino"

console.log(frNames.of("Latn"));
// "latin"

console.log(jaNames.of("Latn"));
// "ラテン文字"

Jeder Formatierer gibt den Skriptnamen in seiner Anzeigesprache zurück. Dies bewältigt die gesamte Komplexität der Verwaltung von Skriptnamen-Übersetzungen.

Das gleiche Muster funktioniert für jeden Skriptcode.

const enNames = new Intl.DisplayNames(["en"], { type: "script" });
const deNames = new Intl.DisplayNames(["de"], { type: "script" });
const zhNames = new Intl.DisplayNames(["zh"], { type: "script" });

console.log(enNames.of("Cyrl"));
// "Cyrillic"

console.log(deNames.of("Cyrl"));
// "Kyrillisch"

console.log(zhNames.of("Cyrl"));
// "西里尔文"

console.log(enNames.of("Arab"));
// "Arabic"

console.log(deNames.of("Arab"));
// "Arabisch"

console.log(zhNames.of("Arab"));
// "阿拉伯文"

Der Formatierer wendet automatisch die korrekten linguistischen Konventionen für jede Sprache an.

Aufbau eines Skript-Selektors für Sprachvarianten

Einige Sprachen bieten Benutzern die Wahl zwischen verschiedenen Schriften. Serbisch kann in kyrillischer oder lateinischer Schrift geschrieben werden. Chinesisch kann in vereinfachten oder traditionellen Zeichen geschrieben werden. Diese Optionen müssen angezeigt werden, damit Benutzer wählen können.

function getScriptOptions(language, userLocale) {
  const names = new Intl.DisplayNames([userLocale], { type: "script" });

  if (language === "sr") {
    return [
      { code: "Cyrl", name: names.of("Cyrl") },
      { code: "Latn", name: names.of("Latn") }
    ];
  }

  if (language === "zh") {
    return [
      { code: "Hans", name: names.of("Hans") },
      { code: "Hant", name: names.of("Hant") }
    ];
  }

  return [];
}

console.log(getScriptOptions("sr", "en"));
// [
//   { code: "Cyrl", name: "Cyrillic" },
//   { code: "Latn", name: "Latin" }
// ]

console.log(getScriptOptions("zh", "en"));
// [
//   { code: "Hans", name: "Simplified Han" },
//   { code: "Hant", name: "Traditional Han" }
// ]

console.log(getScriptOptions("zh", "es"));
// [
//   { code: "Hans", name: "han simplificado" },
//   { code: "Hant", name: "han tradicional" }
// ]

Diese Funktion gibt Schriftoptionen in der Benutzeroberflächen-Sprache des Benutzers zurück. Serbische Benutzer sehen Optionen für kyrillische und lateinische Schriften. Chinesische Benutzer sehen Optionen für vereinfachte und traditionelle Schriften. Die Namen erscheinen in der Sprache, die der Benutzer versteht.

Anzeige vollständiger Gebietsschema-Kennungen mit Schriftinformationen

Gebietsschema-Kennungen können Schriftcodes enthalten, um zwischen Schriftsystemen zu unterscheiden. Das Format ist Sprache-Schrift-Region, wie sr-Cyrl-RS für Serbisch in kyrillischer Schrift in Serbien oder zh-Hans-CN für vereinfachtes Chinesisch in China.

Bei der Anzeige dieser Gebietsschema-Kennungen sollte der Schriftcode extrahiert und in einen lesbaren Namen umgewandelt werden.

function parseLocaleWithScript(locale) {
  const parts = locale.split("-");

  if (parts.length < 2) {
    return null;
  }

  const [language, script] = parts;

  if (script.length === 4) {
    return {
      language,
      script: script.charAt(0).toUpperCase() + script.slice(1).toLowerCase()
    };
  }

  return null;
}

function formatLocaleWithScriptName(locale, displayLocale) {
  const parsed = parseLocaleWithScript(locale);

  if (!parsed) {
    return locale;
  }

  const languageNames = new Intl.DisplayNames([displayLocale], {
    type: "language"
  });
  const scriptNames = new Intl.DisplayNames([displayLocale], { type: "script" });

  const languageName = languageNames.of(parsed.language);
  const scriptName = scriptNames.of(parsed.script);

  return `${languageName} (${scriptName})`;
}

console.log(formatLocaleWithScriptName("sr-Cyrl", "en"));
// "Serbian (Cyrillic)"

console.log(formatLocaleWithScriptName("sr-Latn", "en"));
// "Serbian (Latin)"

console.log(formatLocaleWithScriptName("zh-Hans", "en"));
// "Chinese (Simplified Han)"

console.log(formatLocaleWithScriptName("zh-Hant", "en"));
// "Chinese (Traditional Han)"

console.log(formatLocaleWithScriptName("sr-Cyrl", "es"));
// "serbio (cirílico)"

Dieses Muster macht Gebietsschema-Kennungen menschenlesbar, indem Sprachnamen mit Schriftnamen kombiniert werden. Benutzer sehen "Serbian (Cyrillic)" anstelle von "sr-Cyrl".

Erstellen eines Schriftartauswählers mit Skriptnamen

Schriftartauswahlschnittstellen gruppieren Schriftarten oft nach den Skripten, die sie unterstützen. Sie müssen Skriptnamen anzeigen, damit Benutzer verstehen, welche Skripte jede Schriftart abdeckt.

function createFontOptions() {
  const fonts = [
    {
      name: "Arial",
      scripts: ["Latn", "Cyrl", "Grek", "Hebr", "Arab"]
    },
    {
      name: "Noto Sans CJK",
      scripts: ["Hans", "Hant", "Hira", "Kana", "Hang"]
    },
    {
      name: "Noto Sans Devanagari",
      scripts: ["Deva"]
    }
  ];

  const names = new Intl.DisplayNames(["en"], { type: "script" });

  return fonts.map((font) => ({
    name: font.name,
    scripts: font.scripts.map((code) => names.of(code))
  }));
}

console.log(createFontOptions());
// [
//   {
//     name: "Arial",
//     scripts: ["Latin", "Cyrillic", "Greek", "Hebrew", "Arabic"]
//   },
//   {
//     name: "Noto Sans CJK",
//     scripts: ["Simplified Han", "Traditional Han", "Hiragana", "Katakana", "Hangul"]
//   },
//   {
//     name: "Noto Sans Devanagari",
//     scripts: ["Devanagari"]
//   }
// ]

Dies erstellt eine Liste von Schriftarten mit ihren unterstützten Skripten in menschenlesbarer Form. Benutzer können Schriftarten basierend auf den benötigten Schriftsystemen auswählen.

Anzeigen verfügbarer Eingabemethoden nach Skript

Betriebssysteme und Browser bieten Eingabemethoden für verschiedene Skripte an. Eine japanische Eingabemethode konvertiert lateinische Zeichen in Hiragana, Katakana oder Kanji. Eine chinesische Eingabemethode konvertiert Pinyin in vereinfachte oder traditionelle chinesische Zeichen. Sie können verfügbare Eingabemethoden mit ihren Skriptnamen anzeigen.

function getInputMethods(userLocale) {
  const inputMethods = [
    { id: "latin-ime", script: "Latn" },
    { id: "japanese-ime", script: "Hira" },
    { id: "chinese-pinyin-simplified", script: "Hans" },
    { id: "chinese-pinyin-traditional", script: "Hant" },
    { id: "korean-ime", script: "Hang" },
    { id: "arabic-ime", script: "Arab" },
    { id: "hebrew-ime", script: "Hebr" }
  ];

  const names = new Intl.DisplayNames([userLocale], { type: "script" });

  return inputMethods.map((method) => ({
    id: method.id,
    name: names.of(method.script)
  }));
}

console.log(getInputMethods("en"));
// [
//   { id: "latin-ime", name: "Latin" },
//   { id: "japanese-ime", name: "Hiragana" },
//   { id: "chinese-pinyin-simplified", name: "Simplified Han" },
//   { id: "chinese-pinyin-traditional", name: "Traditional Han" },
//   { id: "korean-ime", name: "Hangul" },
//   { id: "arabic-ime", name: "Arabic" },
//   { id: "hebrew-ime", name: "Hebrew" }
// ]

console.log(getInputMethods("ja"));
// [
//   { id: "latin-ime", name: "ラテン文字" },
//   { id: "japanese-ime", name: "ひらがな" },
//   { id: "chinese-pinyin-simplified", name: "簡体字" },
//   { id: "chinese-pinyin-traditional", name: "繁体字" },
//   { id: "korean-ime", name: "ハングル" },
//   { id: "arabic-ime", name: "アラビア文字" },
//   { id: "hebrew-ime", name: "ヘブライ文字" }
// ]

Dies zeigt Eingabemethodennamen in der Sprache des Benutzers an. Benutzer sehen "Hiragana", wenn die Benutzeroberfläche auf Englisch eingestellt ist, und "ひらがな", wenn die Benutzeroberfläche auf Japanisch eingestellt ist.

Verständnis der Großschreibung von Skriptcodes

Skriptcodes folgen einem bestimmten Großschreibungsmuster. Der erste Buchstabe ist großgeschrieben. Die restlichen drei Buchstaben sind kleingeschrieben. Latn ist korrekt. LATN, latn und LaTn entsprechen nicht dem Standard.

Die Methode of() akzeptiert Skriptcodes unabhängig von der Groß- und Kleinschreibung.

const names = new Intl.DisplayNames(["en"], { type: "script" });

console.log(names.of("Latn"));
// "Latin"

console.log(names.of("LATN"));
// "Latin"

console.log(names.of("latn"));
// "Latin"

console.log(names.of("LaTn"));
// "Latin"

Der Formatierer verarbeitet alle Varianten korrekt. Die Verwendung des standardmäßigen Großschreibungsmusters macht Ihren Code jedoch lesbarer und konsistenter mit dem ISO 15924-Standard.

Umgang mit Fallback-Locales

Der Konstruktor Intl.DisplayNames akzeptiert ein Array von Locales. Wenn die erste Locale nicht verfügbar ist, fällt der Formatierer auf die nächste Locale im Array zurück.

const names = new Intl.DisplayNames(["xx-XX", "en"], { type: "script" });
console.log(names.of("Latn"));
// "Latin"

Der Formatierer versucht zuerst "xx-XX", das nicht existiert, und fällt dann auf "en" zurück. Dies stellt sicher, dass Ihr Code auch dann funktioniert, wenn die angeforderte Locale nicht verfügbar ist.

Sie können mit der Methode resolvedOptions() überprüfen, welche Locale der Formatierer tatsächlich verwendet.

const names = new Intl.DisplayNames(["xx-XX", "en"], { type: "script" });
console.log(names.resolvedOptions().locale);
// "en"

Dies zeigt, dass der Formatierer nach dem Fallback auf Englisch zurückgegriffen hat.

Aufbau eines mehrsprachigen Content-Management-Systems

Content-Management-Systeme, die mehrere Skripte unterstützen, müssen anzeigen, welche Skripte für jeden Inhalt verfügbar sind. Sie können Skriptnamen anzeigen, um Content-Editoren bei der Auswahl der richtigen Version zu unterstützen.

function getContentVersions(contentId, userLocale) {
  const versions = [
    { script: "Latn", url: `/content/${contentId}/latn` },
    { script: "Cyrl", url: `/content/${contentId}/cyrl` },
    { script: "Arab", url: `/content/${contentId}/arab` }
  ];

  const names = new Intl.DisplayNames([userLocale], { type: "script" });

  return versions.map((version) => ({
    script: version.script,
    name: names.of(version.script),
    url: version.url
  }));
}

console.log(getContentVersions("article-123", "en"));
// [
//   { script: "Latn", name: "Latin", url: "/content/article-123/latn" },
//   { script: "Cyrl", name: "Cyrillic", url: "/content/article-123/cyrl" },
//   { script: "Arab", name: "Arabic", url: "/content/article-123/arab" }
// ]

Dieses Muster hilft Content-Editoren zu sehen, welche Skriptversionen existieren und zwischen ihnen zu navigieren.

Browser-Unterstützung

Die Intl.DisplayNames-API mit Unterstützung für Skripttypen ist in allen modernen Browsern verfügbar. Sie wird seit März 2021 von allen wichtigen Browsern unterstützt, darunter Chrome, Firefox, Safari und Edge.

Sie können überprüfen, ob die API verfügbar ist, bevor Sie sie verwenden.

if (typeof Intl.DisplayNames !== "undefined") {
  const names = new Intl.DisplayNames(["en"], { type: "script" });
  console.log(names.of("Latn"));
} else {
  console.log("Intl.DisplayNames is not supported");
}

Für ältere Browser müssen Sie einen Fallback bereitstellen oder ein Polyfill verwenden. Ein einfacher Fallback verwendet eine fest codierte Zuordnung von Skriptcodes zu Namen.

function getScriptName(code, locale) {
  if (typeof Intl.DisplayNames !== "undefined") {
    const names = new Intl.DisplayNames([locale], { type: "script" });
    return names.of(code);
  }

  const fallbackNames = {
    Latn: "Latin",
    Cyrl: "Cyrillic",
    Arab: "Arabic",
    Hans: "Simplified Han",
    Hant: "Traditional Han"
  };

  return fallbackNames[code] || code;
}

console.log(getScriptName("Latn", "en"));
// "Latin"

Dies stellt sicher, dass Ihr Code auch in Browsern ohne Unterstützung für Intl.DisplayNames funktioniert, obwohl Sie die automatischen Lokalisierungsfunktionen verlieren.