Thread localization - Anfängerfrage
(20 answers)
Opened by naspdep at 2012-06-11 10:34
Also zu Anfang. Es gibt mehr als eine Implementation von Gettext für Perl. Das wird dir noch häufiger begegnen, dass es mehrere Module gibt die alle ungefähr das selbe machen.
Neben Gettext gibt es noch Locale::gettext, Locale::Messages, Locale::Simple und noch einige mehr. Neben dem eigentlichen Programmieren ist es auch wichtig zu wissen welche Module man am besten nutzt. Aber zurück zu gettext. Programme die gettext nutzen greifen auf die Umgebungsvariablen zurück um festzustellen was die Aktuelle Ausgabesprache ist. So ist in LANGUAGE definiert welche Sprachen generell verstanden werden. LC_MESSAGE definiert ein welcher Sprache Texte ausgeben werden sollen. Daneben gibt es noch LC_CTYPE und LANG. Will man alle diese Werte auf einmal beeinflussen gibt es noch LC_ALL Anzumerken ist das LC_ALL=C sämtliche Übersetzungen unterdrückt und alle Texte so ausgeben werden wie sie im Code stehen. Das gilt für alle Programme. (zumindest wenn das System POSIX Konform ist) Schreibe LC_ALL=C programm und du bekommst die Ausgaben wie sie die Programmierer verfasst haben. Will man unter Debian (und auch Ubuntu) die aktiven Sprachen einstellen so kann man als root dpkg-reconfigure locales eingeben und die Sprachen einstellen, die man verwenden möchte. Danach ist ein Neustart angebracht, damit die Einstellungen in allen Ecken des Systems ankommen. Um zu schauen welche locales zur Verfügung stehen kann man locale -a ausführen damit werden alle verfügbaren gelistet. Nun ein kleines Script: test.pl: Code (perl): (dl
)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 #!/usr/bin/perl use strict; use warnings; # gettext laden. # Das ist Bei Debian gleich dabei und nutzt die C-Lib gettext use Locale::gettext; # POSIX laden um "setlocale" nutzen zu lönnen use POSIX; # das Verzeichnis finden in dem das Script liegt use FindBin '$Bin'; # keine Übersetzung vorläufig setlocale(LC_MESSAGES,'C') or die( "Can't set LC_MESSAGES" ); # die Domein an ein Verzeichnis # im Ordner des Scriptes binden bindtextdomain("my_test","$Bin/translate"); # in diesem Scrit diese Domain verwenden textdomain("my_test"); print gettext("Yo man")."\n"; for(0..9) { printf gettext('ln: %02u')."\n",$_; } Das soll ein kleines Beispiel sein. Wie zu sehen sollte im Verzeichnis des Scripts ein Ordner "translate" existieren. Nun generieren wir aus dem Script ein Template für die Übersetzungen: xgettext ./test.pl -d my_test -p translate Das Erzeugt im Ordner 'translate' eine Datei "my_test.po" Grob gesagt sucht xgettext nach gettext(...) und nimmt den String daraus um damit das Template zu erzeugen. Darum funktionieren so Konstrukte wie gettext( "WERT=$wert\n" ) nicht und sollten besser so geschrieben werden: sprintf( gettext( "WERT=%s\n" ), $wert ) Die Sollte ungefähr so aussehen: Code: (dl
)
1 # SOME DESCRIPTIVE TITLE. Das ist das Template mit dem die einzelnen Übersetzungen erzeugt werden. Im Verzeichnis 'translate' führt man aus: msginit -l de -i my_test.po Damit wird eine Datei 'de.po' erzeugt. Darin macht man die Übersetzungen. Ungefähr so: Code: (dl
)
1 # German translations for PACKAGE package. Wenn man Umlaute benutzt muss man das charset=ASCII Ändern. Speichert man die Datei Als UTF-8 (was zu empfehlen ist) dann setzt man charset=UTF-8 Speichert man in einer anderen Kodierung muss man das dort vermerken. Macht man da einen Fehler nörgelt gettext herum das bestimmte Zeichen nicht zur Kodierung passen, oder die Ausgabe hat seltsame Zeichen. Das macht man nun für jede Sprache die man haben will (z.B englisch). Der nächste Schritt ist es die Dateien zu kompilieren und an die richtige Stelle zu packen. Dazu erzeugt man zu jeder Sprache einen Ordner diesen Namens der einen Ordner 'LC_MESSAGES' enthält. Also für Deutsch: translate/de/LC_MESSAGES/ Nun wird das ganze kompiliert: msgfmt -o de/LC_MESSAGES/my_test.mo ./de.po Nun kann das Script auf die Übersetzung zugreifen. Dieses Prozedere wiederholst du für jede der Übersetzungen. Mit ./test.pl bekommt man : Was zu erwarten ist da eine Übersetzung unterdrückt ist. Kommentiert man #setlocale(LC_MESSAGES,'C') aus bekommt man die Ausgabe: Code: (dl
)
1 Hallo Wenn du Vorher für alle gewünschten Übersetzungen die locales ausgewählt hast, kannst du die Sprache ändern indem du die Zeile setlocale(LC_MESSAGES,'...') änderst. Die Ordnerstruktur ist bei mir nun: Code: (dl
)
1 test.pl Das "gettext"-Packet bietet noch weitere Programme um z.B Änderungen im Script zu erkennen und in den Übersetzungen zu ergänzen. Das solltest du dir aber selber durch lesen. Ich hoffe das hilft dir weiter. |