abendstund: Sprachenkonzept

Liebe Leute,

wie realisiert ihr in eurem Projekt eine unübersichtliche Anzahl von Sprachen?

Ich habe ein europäisches Tourismus-Projekt, bei dem neben den vielen europäischen Sprachen auch reisefreudige andere Nationen informiert werden sollen: русский (russisch), 日本語 (japanisch), ...

Und heute, nachdem ich die Browser-Sprachen speichere und auswerte, stelle ich überrascht fest, dass nach "english" die meisten Zugriffe "中文" (chinesisch) sind, deutlich vor "de" (deutsch).

Whow, zwei Milliarden Chinesen gegen 80 Millionen Deutsche. Die Chinesen sind herzlich willkommen. In Heidelberg, in Rothenburg ob der Tauber und sonstwo ...

Doch wie managt man das jetzt als Programmierer?

Ich könnte theoretisch für jede, vom Browser gemeldete Sprache einen Baustein hinterlegen. Doch ab 3 Textbausteinen pro Programm wird die Pflege unübersichtlich, unmöglich, fehlerhaft.

Die Alternative ist ein englischer Textbaustein, in dem Weichen für die zahlreichen Sprachen gestellt werden, etwa so:

@_de|Ihr Zentrum: F-54840 Gondreville
@_en|Your center: F-54840 Gondreville
@_fr|Votre centre: F-54840 Gondreville
...

  1. Der Standard ist meistens eine wie auch immer geartete Schnittstelle, bei der man als Basis Englisch nimmt (da man diese Basis meistens günstiger an Übersetzerbüros schicken kann); in den meisten Fällen XML oder CSV ("Identifier";"jeweilige Übersetzung").

    Im Optimalfall hat man für jede Sprache eine eigene Datei im gleichen Format und als Fallback eben Englisch. Wenn neue Sätze hinzukommen, muss man nur die englischen Ergänzugen an das Übersetzungsbüro schicken.

    Gruß, LX

    --
    RFC 1925, Satz 2: Egal, wie fest man schiebt, ganz gleich, wie hoch die Priorität ist, man kann die Lichtgeschwindigkeit nicht erhöhen.
  2. Hi!

    wie realisiert ihr in eurem Projekt eine unübersichtliche Anzahl von Sprachen?

    I18n oder ausgesprochen Internationalization ist kein neues Thema. Dazu sollte es für jede (wichtige) Programmiersprache mindestens ein einsetzbares System geben.

    .NET arbeitet mit Ressourcen. Man gibt nur den Ressourcen-Namen anstelle eines Textes an und zur Laufzeit holt sich das System den passenden Text aus den Ressourcen-Dateien.

    Für PHP gibt es beispielsweise eine Einbindung des Gettext-Systems. Anstelle eines String schreibt man _("den Text") und die Funktion _() (alias für gettext()) sucht sich den passenden Text aus den Sprachdateien.

    Mit dem oben genannten Stichwort solltest du zu deinem System fündig werden.

    Außerdem ist noch L10n (Localization) von Bedeutung, denn nicht nur Texte sind in den verschiedenen Sprachen unterschiedlich sondern auch die Formatierung von Zahlen oder die Verwendung von Maßeinheiten und damit verbundenen auch Maßsysteme (z.B. imperiales vs. metrisches).

    Lo!

    1. Hallo,

      Für PHP gibt es beispielsweise eine Einbindung des Gettext-Systems. Anstelle eines String schreibt man _("den Text") und die Funktion _() (alias für gettext()) sucht sich den passenden Text aus den Sprachdateien.

      Ich klinke mich hier mal mit meiner Frage ein.

      Wie geht man bei mehrsprachigen Seiten am besten mit großen Textpassagen vor?
      Bei (Fehler)Meldungen etc. erscheint mir gettext sehr praktisch, aber ich bin mir nicht sicher, ob das auch für etwas längere Texte gilt. (z.B.: eine Beschreibung des Webprojekts über 1,5 Bildschirmseiten)

      Bei solchen langen Texten gehe zumindest ich so vor, dass ich PHP ausmache ?> und in purem HTML weitermache, da es so viel übersichtliche ist, als z.B. in einem echo()  (Macht ihr das auch so?)

      Für die gettext Variante müsste man diese Texte ja auch in die Funktion packen.

      Ich vermute, dass da je nach Textmenge z.B. so vorgegangen werden kann:
      Es wird eine extra Datei für die Beschreibung angelegt (beschreibung_de_DE.inc) und jenachdem, welche Sprache festgelegt ist, wird dann die richtige Datei includet.

      Wenn es um Produktbeschreibungen in einem Shop geht oder sonst sehr viele Texte da sind würde ich das ganze der Übersichltichkeit halber in eine DB packen.

      Aber da fällt mir folgendes noch ein:
      Könnte ich es mit gettext so machen, dass ich z.B. _("Beschreibung") schreibe und ich dann für jede Sprache in der PO Datei die richtige lange Beschreibung einfüge?

      Gruß
      Alex

      1. Hi!

        Wie geht man bei mehrsprachigen Seiten am besten mit großen Textpassagen vor?

        Wenn es übersetzt werden soll, dann sollte das über den gewählten Weg gehen, sonst hat man x unterschiedliche Verfahren zu pflegen.

        Bei solchen langen Texten gehe zumindest ich so vor, dass ich PHP ausmache ?> und in purem HTML weitermache, da es so viel übersichtliche ist, als z.B. in einem echo()  (Macht ihr das auch so?)

        Es gibt die Heredoc- und Nowdoc-Syntax, die ähnliches leisten kann. Zudem kann man vielleicht auch über unterschiedliche Templates nachdenken. Unterschiedliche Templates bedeutet aber üblicherweise auch, dass man den HTML-Code zwischen den sprachspezifischen Texten mehrfach vorliegen hat, was wartungstechnisch sehr ungünstig ist. Also wäre eine solche Lösung schon deshalb nicht unbedingt zu bevorzugen. Große Textstücke sind vermutlich weniger reine Textwüsten sondern mit Markup durchzogen. Ich denke, der beste Kompromiss ist dann, eine eigene Syntax zu verwenden, die beim Abruf durch das Markup ausgetauscht wird. (Ein Cache kann helfen, dass das nicht jedes Mal passieren muss.)

        Für die gettext Variante müsste man diese Texte ja auch in die Funktion packen.

        Ja, die Funktion nimmt aber auch Variablen entgegen.

        Könnte ich es mit gettext so machen, dass ich z.B. _("Beschreibung") schreibe und ich dann für jede Sprache in der PO Datei die richtige lange Beschreibung einfüge?

        Der Sinn des Klartextes anstelle eines Textnamens ist, dass zum einen der Text zumindest in einer Sprache in voller Schönheit im Quelltext steht, man also nicht rätseln muss, welcher Text konkret sich hinter einem Platzhalter verbirgt. Zum anderen ist der dann auch die Fallback-Lösung für nicht übersetzte Texte.

        Lo!

        1. Hallo,

          Wenn es übersetzt werden soll, dann sollte das über den gewählten Weg gehen, sonst hat man x unterschiedliche Verfahren zu pflegen.

          Also du würdest entweder alle Texte in gettext mach oder eben keinen, richtig?

          Es gibt die Heredoc- und Nowdoc-Syntax, die ähnliches leisten kann. Zudem kann man vielleicht auch über unterschiedliche Templates nachdenken. Unterschiedliche Templates bedeutet aber üblicherweise auch, dass man den HTML-Code zwischen den sprachspezifischen Texten mehrfach vorliegen hat, was wartungstechnisch sehr ungünstig ist. Also wäre eine solche Lösung schon deshalb nicht unbedingt zu bevorzugen. Große Textstücke sind vermutlich weniger reine Textwüsten sondern mit Markup durchzogen. Ich denke, der beste Kompromiss ist dann, eine eigene Syntax zu verwenden, die beim Abruf durch das Markup ausgetauscht wird. (Ein Cache kann helfen, dass das nicht jedes Mal passieren muss.)

          *DOC habe ich geredae mal ausprobiert. Ist eine interessante Sache, nur leider kann man dabei anscheinend nicht mit Codeeinrückungen arbeiten, da PHP sich dann an den Leerzeichen stört...

          Ja so ein langer Text würde etwas HTML zur schöneren Aufbereitung enthalten.
          Wie meinst du das mit der eigenen Syntax und dem austausch durch das Markup, das verstehe ich leider nicht.

          Der Sinn des Klartextes anstelle eines Textnamens ist, dass zum einen der Text zumindest in einer Sprache in voller Schönheit im Quelltext steht, man also nicht rätseln muss, welcher Text konkret sich hinter einem Platzhalter verbirgt. Zum anderen ist der dann auch die Fallback-Lösung für nicht übersetzte Texte.

          Stimmt, das ist ein großer Vorteil. Ich habe mal aus Spaß eine mehrsprachige kleine Seite gebaut. Da wusste ich von gettext noch nichts und habe es daher mit Arrays gemacht. Hatte da nur Platzhalter im Quelltext und nicht die ganzen Sätze...das war schon sehr unübersichtlich.

          Gruß
          Alex

          1. Hi!

            Wenn es übersetzt werden soll, dann sollte das über den gewählten Weg gehen, sonst hat man x unterschiedliche Verfahren zu pflegen.
            Also du würdest entweder alle Texte in gettext mach oder eben keinen, richtig?

            Ich würde versuchen, alles mit einer Lösung abzuhandeln, also entweder gettext oder eine andere Lösung. "Keiner" ist ja nicht zielführend. Allerdings bin ich nicht starr festgelegt, was sowas angeht. Wenn sich für ein bestimmtes Teilproblem eine bessere Lösung findet, wäge ich Vor- und Nachteile gegeneinander ab und fahre zur Not zweigleisig.

            Es gibt die Heredoc- und Nowdoc-Syntax, die ähnliches leisten kann.
            *DOC habe ich geredae mal ausprobiert. Ist eine interessante Sache, nur leider kann man dabei anscheinend nicht mit Codeeinrückungen arbeiten, da PHP sich dann an den Leerzeichen stört...

            Kommt darauf an, was du meinst. Du kannst nicht den gesamten *doc-Block einrücken, denn diese Einrückung wäre Teil des Inhalts. So ein Block sieht nicht selten wie ein Fremdkörper im umgebenden Code aus.

            Ja so ein langer Text würde etwas HTML zur schöneren Aufbereitung enthalten.
            Wie meinst du das mit der eigenen Syntax und dem austausch durch das Markup, das verstehe ich leider nicht.

            Einfache Regeln, wie "zwei Zeilenumbrüche ergeben einen Absatz", statt <p>...</p>. Die Übersetzer sind ja meist keine HTML-Profis. Du kannst ihnen natürlich auch erklären, wie sie mit der HTML-Syntax umgehen sollen. Ungünstig ist es, wenn sie dir Klassennamen oder IDs übersetzen :-) Deswegen sollte die Syntax zur Textauszeichnung so einfach wie möglich sein, BBCode oder Syntax wie in Wiki-Systemen.

            Wenn an der resultierenden HTML-Syntax was zu ändern ist, ändert man die Übersetzungsregel und fertig ist, statt durch alle Sprachvarianten durchzulaufen.

            Einfache Syntax kann man nicht in jedem Fall anwenden. Komplexe Aufgabenstellungen/Formatierungswünsche kann man nicht immer gleichwertig mit einfacher Syntax darstellen.

            Lo!