News Mozilla: Fluent unterstützt bei lokaler Anpassung von Software

mischaef

Kassettenkind
Teammitglied
Registriert
Aug. 2012
Beiträge
5.930
Entwickler kennen die Tücken und den Aufwand bei Anpassungen ihrer Software in verschiedene Sprachen. Immer wieder stößt das Konzept über Sprachdateien gelöste Übersetzungen an seine Grenzen. Hier will Mozilla mit Fluent die Arbeit deutlich erleichtern.

Zur News: Mozilla: Fluent unterstützt bei lokaler Anpassung von Software
 
  • Gefällt mir
Reaktionen: flo.murr, yummycandy und psYcho-edgE
Ich bin zwiegespalten. Einerseits freue ich mich durchaus, dass es noch Ambitionen gibt hier mal einen neuen Ansatz zu probieren, anstelle von 9001 Insellösungen. Auf der anderen Seite frage ich mich welches Problem das Projekt löst, welches noch nicht von den simpelsten Templating-Libraries erschlagen werden könnte.

Code:
{$userName} {$photoCount ->
        [one] added a new photo
       *[other] added {$photoCount} new photos
    } to {$userGender ->
        [male] his stream
        [female] her stream
       *[other] their stream
    }.

Erzeugt also einen JSON basierten AST mit 389 Zeilen und 4371 Zeichen (ohne Whitespace). Der wirderrum wird geparsed, durchlaufen etc... für mich eher ein Fall von "Overengineering". Und mehr als 2 Geschlechter gehen auch mit normalem templating... SCNR

Resultat: Nun gibt es 9002 Insellösungen und alle haben ihre eigene Syntax... :-)
 
edit: nvm
 
0xffffffff schrieb:
Auf der anderen Seite frage ich mich welches Problem das Projekt löst, welches noch nicht von den simpelsten Templating-Libraries erschlagen werden könnte.
http://userguide.icu-project.org/formatparse/messages
Code:
{gender_of_host, select, 
  female {
    {num_guests, plural, offset:1 
      =0 {{host} does not give a party.}
      =1 {{host} invites {guest} to her party.}
      =2 {{host} invites {guest} and one other person to her party.}
      other {{host} invites {guest} and # other people to her party.}}}
  male {
    {num_guests, plural, offset:1 
      =0 {{host} does not give a party.}
      =1 {{host} invites {guest} to his party.}
      =2 {{host} invites {guest} and one other person to his party.}
      other {{host} invites {guest} and # other people to his party.}}}
  other {
    {num_guests, plural, offset:1 
      =0 {{host} does not give a party.}
      =1 {{host} invites {guest} to their party.}
      =2 {{host} invites {guest} and one other person to their party.}
      other {{host} invites {guest} and # other people to their party.}}}}
Zeig mir doch mal wie du das mit Templates löst... Und die Grammatik sollte auf deinem Template-Weg auch stimmen, nicht nur in Deutsch + Englisch, sondern auch Polnisch, Tschechisch, irgendwann mal CJK... Spätestens wenn du jetzt überlegst, wie du das am besten in Einzelteile auftrennst, damit es mit deiner (Bastel-)Lösung funktioniert, ist doch schon alles gesagt.

Alle bisherigen Lösung sind extrem bastelanfällig. Mit ICU kann man "endlich" komplette Strings ordentlich übersetzen ohne irgendwelche dummen Workarounds nutzen zu müssen.

Im Prinzip ist das alles nur ne "Erweiterung" von ICU, welches ich in einem Projekt seit ca. drei Jahren verwende (PHP + Intl). Sehr wunderbare Lösung, weil man einfach einen String hineingibt und sich ICU und der Übersetzer um alles kümmern. Ich muss keine Ahnung mehr von der Sprache und dessen Grammatik haben, dafür gebe ich es ja dem Übersetzer und mach es nicht selbst mit Google Translate...

Fragwürdig ist eher, warum sich alle mit den beschissenen Bastellösungen zufriedengeben?! ICU ist echt keine Wissenschaft, extrem einfach zu benutzen, sehr dynamisch, man kann ganze Romane übergeben und nicht nur einzelne Schnipsel...
 
Yuuri schrieb:
Zeig mir doch mal wie du das mit Templates löst...

Was ist daran besonders? Ich sehe da simple "if/else"- bzw. "switch/case/default"-Konstrukte die in jeder Template-Library mit Kontrollstrukturen umsetzbar sind. Unterschiedlich ist nur die Syntax, und die ist dann geschmackssache.

In der Velocity-Syntax z.B. sähe das (stupide übertragen) ungefähr so aus:

Code:
#if (gender == "female")
  #if (num_guests == 0)
      $host does not give a party.
  #elseif (num_guests == 1)
      $host invites $guest to her party.
  #elseif (num_guests == 2)
      $host invites $guest and one other person to her party.
  #else
      $host invites $guest and $other people to her party.
  #end
#elseif (gender == "male")
  [...]
#else
  [...]
#end

Oder etwas vereinfachter...

Code:
#if (is_female && num_guests == 0)
      $host does not give a party.
#elseif (is_female && num_guests == 1)
      $host invites $guest to her party.
#elseif (is_female && num_guests == 2)
      $host invites $guest and one other person to her party.
#elseif (is_female && num_guests > 2)
      $host invites $guest and $other people to her party.
#elseif (is_male && num_guests == 0)
  [...]
#end

Am Ende ist es doch reine Geschmackssache. Letztendlich steht und fällt die Übersetzungsqualität mit den Variabeln/Informationen die ein Übersetzer nutzen kann, hier liegt m.E. häufig das größte Problem. Welche Lib dann Platzhalter ersetzt und wie dessen Syntax aussieht ändert daran doch wenig. 🤷‍♂️
 
0xffffffff schrieb:
Was ist daran besonders?
Das hab ich dir oben bereits geschrieben. Während du deinen Quirks im Template umsetzt und für jede Sprache mit jeglicher Besonderheit einen weiteren Fall rein bringst, der vielleicht bei 90 % aller restlichen Sprachen irrelevant ist und du doppelt, dreifach und vierfach Code warten musst, geht das mit ICU Patterns problemlos.
0xffffffff schrieb:
Oder etwas vereinfachter...
Oder ganz einfach:
Code:
<div>
  {{ translate text_xy locale=de_DE gender_of_host=user.gender num_guests=event.guestCount host=event.host guest=event.guest|first }}
</div>
o.ä.
0xffffffff schrieb:
Am Ende ist es doch reine Geschmackssache.
Nein. Du musst deinen Code mit jeder weiteren Sprache ggf. noch weiter anpassen. Ich geb in ICU Variablen mit und die Übersetzung/der Übersetzer kümmert sich drum. Typisches separation of concerns eben. Dein Template hat nicht in der Übersetzung zu pfuschen und schon gar nicht sollte es irgend ein stupides, ggf. gar nicht funktionierendes Markup für die (damit nicht sauber mögliche?) Übersetzung vorgeben.

Beispiel für eine Pluralform aus dem Polnischen mit gettext: https://www.gnu.org/software/gettext/manual/html_node/Plural-forms.html (plik = file)
Code:
1 plik
2,3,4 pliki
5-21 pliko'w
22-24 pliki
25-31 pliko'w
Pluralformen in gettext:

Deutsch, Englisch, ...nplurals=2; plural=n != 1
Polnischnplurals=3; plural=n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2
Arabischnplurals=6; plural=n==0 ? 0 : n==1 ? 1 : n==2 ? 2 : n%100>=3 && n%100<=10 ? 3 : n%100>=11 ? 4 : 5

Machst du jetzt insgesamt sechs Fälle in deinem Template auf, damit du auch problemlos arabisch bedienen kannst? Oder substituierst du und setzt sie als Solches in eine umfassendere (nochmal mit ebenso vielen Plathaltern versehene) Übersetzung ein? Aber bei den sechs Fallunterscheidungen bleibts ja nicht, du musst ja jede Sprache bedienen können:

Mal Copy'n'Paste von der Seite:

CJKOnly one form
DeutschTwo forms, singular used for one only
Brasilianisch, FranzösischTwo forms, singular used for zero and one
LettischThree forms, special case for zero
GälischThree forms, special cases for one and two
RumänischThree forms, special case for numbers ending in 00 or [2-9][0-9]
LitauischThree forms, special case for numbers ending in 1[2-9]
Russisch, Kroatisch, Serbisch, UkrainischThree forms, special cases for numbers ending in 1 and 2, 3, 4, except those ending in 1[1-4]
Tschechisch, SlovakischThree forms, special cases for 1 and 2, 3, 4
SlovenischFour forms, special case for one and all numbers ending in 02, 03, or 04
ArabischSix forms, special cases for one, two, all numbers ending in 02, 03, … 10, all numbers ending in 11 … 99, and others

Oh es graust mir jetzt schon und die Übersetzer freuen sich ebenso... Sie haben erfolgreich 1 Dokumente hochgeladen. Es ist 2019, Lösungen existieren und es ist wahrlich nicht zu viel verlangt ne ordentliche Übersetzung zu liefern, wenn man es bereits mehrsprachig anbieten will.
0xffffffff schrieb:
Letztendlich steht und fällt die Übersetzungsqualität mit den Variabeln/Informationen die ein Übersetzer nutzen kann, hier liegt m.E. häufig das größte Problem.
Genau und mit deiner Übersetzung sind ihm (dem Übersetzer) nur die Möglichkeiten gegeben, die du ihm mittels Marker zusammensetzt. Gibts dann nen weiteren "Sonderfall", der in einer Sprache berücksichtigt werden muss, musst du deine gesamte Codebase anpassen und ebenso die anderen Sprachen erneut überarbeiten, nur weil polnisch einen Sonderfall hat, den keine andere Sprache besitzt. So ist es Sache der Übersetzung.
0xffffffff schrieb:
Welche Lib dann Platzhalter ersetzt und wie dessen Syntax aussieht ändert daran doch wenig.
Platzhalter... Siehe oben.
 
  • Gefällt mir
Reaktionen: 0xffffffff
@Yuuri Danke für die ausführliche Erläuterung, ich werde das morgen mal in Ruhe lesen!
 
Zurück
Oben