Zurück

Pluralisierung 101 in React

Archie McKenzie avatarArchie McKenzie
guidepluralsinternationalizationreactnextjs

Was ist Pluralisierung?

Ich stoße oft auf Apps, die unnatürliche Meldungen anzeigen wie:

Sie haben 1 neue Nachricht

Das ist ein untrügliches Zeichen für eine:n Entwickler:in, der:die sich nicht sorgfältig mit der User Experience auseinandergesetzt hat.

React-Apps brauchen häufig Pluralisierung – für Benachrichtigungszähler, Listenlängen oder Suchergebnisse. Und es ist gar nicht so schwer, Pluralisierung korrekt umzusetzen, besonders wenn deine App nur Englisch unterstützen muss. Aber es gibt viele schlechte Praktiken, in die neue Entwickler:innen verfallen, insbesondere bei mehrsprachigen Interfaces.

Hartcodierte Plurale

Viele Projekte – darunter überraschend große und wichtige – haben die Plurallogik hartcodiert.

export default function Example({ n }) {
  return (
    <p>
      {n} Element{n === 1 ? '' : 'e'} angezeigt
    </p>
  )
}

Aber Pluralbildung ist oft komplexer, als nur ein „s“ an das Ende eines Wortes zu hängen. Einige Substantive haben unregelmäßige Pluralformen wie „child“ und „children“. Manchmal müssen auch andere Teile des Satzes geändert werden, um das geänderte Wort widerzuspiegeln, zum Beispiel „is“ und „are“, die sich je nach Anzahl ändern.

Die Tabelle unten veranschaulicht einige häufige Szenarien:

ScenarioExamplesNotes
Viewer count„1 person is watching“
„2 people are watching“
Unregelmäßiges Substantiv („person“ → „people“) und notwendige Verbänderungen.
Item deletion„Delete this message?“
„Delete these 2 messages?“
Änderung des Demonstrativpronomens („this“ vs. „these“) plus Pluralbildung des Substantivs.
Search results„No results“
„1 result found“
„2 results found“
Unterschiedliche Formulierungen für null, ein und mehrere Ergebnisse.

Die Verwendung von bedingten Ausdrücken wird dabei schnell unhandlich.

Und es wird zum Albtraum, wenn du deine App in anderen Sprachen ausliefern musst. Was für Englisch funktioniert, bricht in Sprachen wie Polnisch oder Arabisch oft komplett, weil sie völlig andere Regeln für die Behandlung von Mengen haben. Unternehmen, mit denen wir zusammenarbeiten, schieben Internationalisierung oft vor sich her, weil das Refactoring von hart codiertem UI wie diesem so schmerzhaft ist.


Englische Pluralbildung

Im Englischen ist es in der Regel unkompliziert, in deiner App die richtigen Pluralformen zu verwenden.

Für die einfache Pluralbildung von Nomen schreibst du eine Utility‑Funktion:

export function pluralize(
  count: number,
  singular: string,
  plural: string = singular + 's'
) {
  return `${count === 1 ? singular : plural}`;
}

Jetzt gibt es eine einzige Funktion, die unsere gesamte Plurallogik übernimmt, und sie funktioniert auch für unregelmäßige Pluralformen:

pluralize(2, 'user') // "users"
pluralize(2, 'person', 'people') // "people"
pluralize(2, 'child', 'children') // "children"

Aber was ist, wenn du komplexere Logik benötigst, zum Beispiel:

"Niemand schaut zu"
"1 Person schaut zu"
"2 Personen schauen zu"

An diesem Punkt sollten Sie ernsthaft über eine wartungsarme Internationalisierungsbibliothek („i18n“) nachdenken.

Obwohl Entwickler häufig denken, dass i18n‑Bibliotheken nur für mehrsprachige Oberflächen gedacht sind, können sie selbst in einsprachigen Anwendungen für Plural- und Variablenformatierung sehr nützlich sein.

Es gibt zahlreiche React‑i18n‑Bibliotheken, darunter unsere, gt-react (oder gt-next, wenn Sie Next.js verwenden). Die Ausgabe eines englischen Plurals mit gt-react ist kinderleicht:

import { Plural } from 'gt-react'

function Example({ count }) {
  return (
    <Plural n={count} zero={'Niemand schaut zu'} one={`${count} Person schaut zu`}>
      {count} Personen schauen zu
    </Plural>
  )
}

Die UI wird abhängig vom Wert von n bedingt gerendert.

Die meisten Bibliotheken verwenden das JavaScript-Intl-Objekt, um zu entscheiden, welche Pluralform angezeigt werden soll. Das bedeutet, dass du im Englischen den Bezeichner "one" für den Singular und "other" für den Plural verwendest. Unsere <Plural>-Komponente greift auf ihre Kinder zurück, wenn die an n übergebene Zahl mit keinem der übergebenen Props übereinstimmt.

Die Verwendung einer Bibliothek ist hier Best Practice, selbst für rein englischsprachige Anwendungen, und macht zukünftige Internationalisierung deutlich einfacher.


Internationalisierung (i18n) und Pluralformen

Eine mehrsprachige Benutzeroberfläche auszuliefern, macht den Umgang mit Pluralformen deutlich komplizierter.

  • Im Arabischen haben Substantive unterschiedliche Formen, je nachdem, ob es null, eins, zwei oder viele davon gibt
  • Im Spanischen, Deutschen und Italienischen werden bei großen Zahlen Punkte statt Kommata verwendet, sodass aus 1,000,000 → 1.000.000 wird
  • Im Hindi werden Ziffern paarweise gruppiert, daher wird aus 1,000,000 → 10,00,000

Für eine internationalisierte App solltest du eine spezialisierte Bibliothek verwenden, die eine eigene Dokumentation dazu hat, wie Pluralformen und Zahlenformate gehandhabt werden.

Zahlen für verschiedene Sprachen formatieren

Du kannst das Intl-Objekt auch verwenden, um Zahlen zu formatieren. Am einfachsten geht das mit der integrierten Methode toLocaleString().

Standardmäßig wird dabei die aktuelle Locale der Laufzeitumgebung verwendet:

const n = 1000000
n.toLocaleString() // zeigt 1,000,000 an, wenn die Laufzeit-Locale „en-US" (amerikanisches Englisch) ist
n.toLocaleString('de') // 1.000.000, weil die Locale als „de" (Deutsch) angegeben wurde

gt-react bietet außerdem eine <Num>-Komponente, die intern auf Intl.NumberFormat setzt.

import { Num } from 'gt-react'

// zeigt 1,000,000 an, wenn die Sprache „en-US" ist
// zeigt 1.000.000 an, wenn die Sprache „de" ist
// zeigt 10,00,000 an, wenn die Sprache „hi" ist
export default function Example() {
  return <Num>1000000</Num>
}

Anzeigen alternativer Pluralformen

Die sechs Pluralformen, die vom Intl‑Objekt in JavaScript unterstützt werden, sind: zero, one, two, few, many, other. Während Englisch nur one („Singular“) und other („Plural“) verwendet, kennen Sprachen wie Arabisch und Polnisch mehr als nur diese zwei Formen.

Eine englischsprachiger Nutzer*in würde zum Beispiel Folgendes erwarten:

"Niemand schaut zu"
"1 Person schaut zu"
"2 Personen schauen zu"

Während eine arabischsprachige Nutzerin oder ein arabischsprachiger Nutzer möglicherweise unterschiedliche Ausdrücke für Singular, Dual (wenn die Anzahl genau zwei beträgt) sowie für kleine und große Pluralformen erwartet:

"Niemand schaut zu"
"1 Person schaut zu"
"2 Personen schauen zu"
"3 Personen schauen zu"
"11 Personen schauen zu"

Hier wird eine Internationalisierungsbibliothek unverzichtbar. Jede Sprache hat ihre eigene Logik dafür, wann und wie Pluralformen dargestellt werden, daher ist es besser, sich auf eine spezialisierte Bibliothek zu verlassen, um das korrekt zu handhaben.

Eine gute Internationalisierungsbibliothek erledigt zwei Dinge:

  1. Sie entscheidet anhand des Locale, welche Pluralform (one, many, other usw.) verwendet werden soll
  2. Sie findet die Übersetzung in der richtigen Sprache, die dieser Form entspricht

Wenn du bereits eine Internationalisierungsbibliothek verwendest, schau in deren Doku nach Informationen zur Pluralformatierung. Fast alle Bibliotheken haben eine eigene Dokumentation zum Rendern von Pluralformen.

Alle Bausteine zusammenführen

Wenn du noch keine Internationalisierungsbibliothek hast, probiere gt-react aus!

Die <Plural>-Komponente von gt-react:

  • Ist eine einfache, pragmatische Möglichkeit, Pluralformen korrekt zu rendern
  • Funktioniert nahtlos mit der <Num>-Formatierungskomponente
  • Funktioniert nahtlos mit der <T>-Übersetzungskomponente, die mit unserem kostenlosen Übersetzungsdienst integriert ist, um Pluralformen automatisch zu generieren

Wenn wir alle Bausteine zusammenführen, erhalten wir eine vollständige mehrsprachige Oberfläche:

import { T, Plural, Num } from 'gt-react'

// Funktioniert sofort in über 100 Sprachen
function Example({ count }) {
  return (
    <T>
      <Plural
        n={count}
        zero={'Niemand schaut zu'}
        one={
          <>
            <Num>{count}</Num> Person schaut zu
          </>
        }
      >
        <Num>{count}</Num> Personen schauen zu
      </Plural>
    </T>
  )
}

Möchtest du mehr erfahren? Sieh dir unsere Dokumentation zur Einrichtung von gt-react oder gt-next an.