2009-11-20 3 views
11

In PHP (oder gettext im Allgemeinen), was macht Gettext, wenn es eine Variable zu dynamischen Inhalten sieht?Wie geht Gettext mit dynamischen Inhalten um?

Ich habe 2 Fälle im Hinterkopf.

1) Nehmen wir an, ich habe <?=$user1?> poked John <?=$user2?>. Vielleicht ist die Reihenfolge der Wörter in einer Sprache anders. Wie geht Gettext damit um? (Nein, ich baue nicht Facebook, das war nur ein Beispiel)

2) Sagen wir, ich speichere einige Kategorien in einer Datenbank. Sie selten, aber sie sind in einer Datenbank gespeichert. Was würde passieren, wenn ich mache? Ich möchte, dass die Übersetzer diese Kategorienamen auch übersetzen, aber muss das in der Datenbank selbst gemacht werden?

Dank

+1

Leser dieser Frage könnten auch interessiert sein an "Wie geordnete Variablen in Gettext .po Dateien angeben?": Http://StackOverflow.com/questions/13979962/how-to -specify-ordered-variables-in-gettext-po-files – Ryan

Antwort

19

Ihre beste Möglichkeit ist spritf() Funktion zu verwenden. Dann würden Sie die printf-Notation verwenden, um dynamischen Inhalt in Ihren Strings zu behandeln. Hier ist eine Funktion, die ich hier gefunden vor einer Weile das für Sie leicht zu handhaben:

function translate() 
{ 
    $args = func_get_args(); 
    $num = func_num_args(); 
    $args[0] = gettext($args[0]); 

    if($num <= 1) 
     return $args[0]; 

    return call_user_func_array('sprintf', $args); 

} 

Jetzt zum Beispiel 1, würden Sie wollen, um die Zeichenfolge zu ändern:

%s poked %s 

Welche würden Sie Eingabe in die translate() Funktion wie folgt aus:

<?php echo translate('%s poked %s', $user1, $user2); ?> 

würden Sie analysieren, alle() Funktionen mit poEdit übersetzen. Dann übersetzen Sie die Zeichenfolge "% s poked% s" in die gewünschte Sprache, ohne die Zeichenfolgenplatzhalter % s zu ändern. Diese würden bei der Ausgabe durch die Funktion translate() mit user1 bzw. user2 ersetzt werden. Sie können mehr über sprintf() im PHP-Handbuch lesen, um weiterführende Informationen zu erhalten.

Für Problem # 2. Sie müssten eine statische Datei erstellen, die poEdit mit den Kategorienamen analysieren kann. Zum Beispiel "misctranslations.php":

<?php 

_('Cars'); 
_('Trains'); 
_('Airplanes'); 

Dann poEdit Parse misctranslations.php haben. Sie könnten dann die Übersetzung des Kategorienamens mit

+4

Fall 1 kann einfacher gehandhabt werden: ' '. Sie benötigen keine zusätzliche Funktion und poedit wird die Zeichenfolge immer noch genau analysieren. – DanMan

+1

Wenn Sie "% s poked% s" übersetzen, wie können Sie die Namen der beiden Benutzer austauschen, wenn sie beide mit demselben Platzhalter gekennzeichnet sind? In manchen Sprachen geht das Thema vor dem Objekt. – bdsl

4

ausgeben Um ein wenig auf das zu bauen, was Mark sagte ... das einzige Problem mit der obigen Lösung ist, dass die statische Liste immer von Hand gepflegt werden muss und wenn Sie hinzufügen eine neue Zeichenfolge vor allen anderen oder Sie ändern eine vorhandene vollständig, die weiche, die Sie für die Übersetzung verwenden, könnte die neuen Zeichenfolgen verwirren, und Sie könnten einige Übersetzungen verlieren.

ich eigentlich einen Artikel über diese zu schreiben (zu wenig Zeit, um es zu beenden jederzeit schnell!), Aber meine vorgeschlagene Antwort lautet in etwa so:

Gettext können Sie die Zeilennummer speichern, dass die Zeichenfolge erscheint in der Code in der .po-Datei. Wenn Sie die Zeichenfolge vollständig ändern, weiß der .po-Editor, dass die Zeichenfolge nicht neu ist, sondern eine alte (dank der Zeilennummer).

Meine Lösung ist, ein Skript zu schreiben, das die Datenbank liest und eine statische Datei mit allen gettext-Strings erstellt. Der große Unterschied zu Marks Lösung besteht darin, dass der Primärschlüssel (nennen wir es ID) in der Datenbank mit der Zeilennummer in der neuen Datei übereinstimmt. Wenn Sie in diesem Fall eine Originalübersetzung vollständig ändern, sind die Zeilen immer noch gleich und Ihr Übersetzer soft wird die Zeichenfolgen erkennen.

Natürlich gibt es vielleicht neuere und intelligentere .po-Editoren da draußen, aber zumindest, wenn Sie Probleme mit neueren Strings haben, dann wird dies sie lösen.

Meine 2 Cent.

1

@Julian

Ich denke, Ihr Ansatz nicht gut in der Praxis funktionieren würde. Stellen Sie sich vor, Sie verschieben eine Funktion über den Code. Die Zeilennummer wird unterschiedlich sein, auch der Dateiname kann abweichen.

Ich denke, die einzige intelligente Möglichkeit, die Änderung von Übersetzungs-IDs zu verwalten, wäre zu versuchen, ähnliche IDs in Ihrer .po-Datei zu finden. Der Editor könnte einen Vorschlag zum Zusammenführen des neuen Übersetzungstextes mit dem vorhandenen vorschlagen, wenn sie sehr ähnlich sind und in der gespeicherten Zeilennummer in Ihrem Code kein Übersetzungsstring vorhanden ist.

1

Wenn Sie irgendwo in Ihrem Code haben: <?=sprintf(_('%s poked %s'), $user1, $user2)?> und eine Ihrer Sprachen muss die Argumente austauschen, es ist sehr einfach. Übersetzen Sie einfach Ihren Code wie folgt: msgid "%s poked %s" msgstr "%2$s translation_of_poked %1$s"