This is the german version of the article. It is also available in english
Voraussetzung: "Der Einstieg in lua“
"Internationalisierung bedeutet in der Informatik beziehungsweise in der Softwareentwicklung, ein Programm so zu gestalten, dass es leicht (ohne den Quellcode ändern zu müssen) an andere Sprachen und Kulturen angepasst werden kann."
So startet der aktuelle Wikipedia-Artikel das Thema Internationalisierung.
In diesem Tutorial erfährst du wie man unter Nutzung des ResourceStrings-Ansatzes dein Cartrigde in mehreren Sprachen anbieten und dabei deinen eigentlichen Code vom Sprachproblem abkoppeln kannst. Wir beginnen mit der Definition einer Variablen
Anschließend wird ein Array
Jetzt wird sich so mancher Entwickler fragen, warum speichert das messages-Array seine eingestellte Sprache nicht selbst sondern nutzt eine extra Variable. Der Grund hierzu liegt einzig in der Persistenzproblematik. Wir wollen ja auf keinen Fall das gesamte Array persistieren, denn an diesen Werten ändert sich zur Laufzeit nichts. Der einzig dynamische Teil ist die eingestellte Sprache, die nach dem Start z.B per Multiple-Choice ausgewählt werden kann. Um ein aufwendiges OnSave / OnRestore Prozedere zu verhindern, nutzen wir lieber den Workaround über die zweite Variable.
Für jede Sprache (in unserem Beispiel Deutsch, Englisch und Französich) wird ein Subarray wie in Zeile 5-7 definiert. Danach beginnt die eigentliche Stringdefinition.
Die Idee dabei ist, dass im Cartrigde an der Stelle wo für die Begrüßung des Spieler ein übersetzter String ausgegeben werden soll, der key
Bevor wir jedoch zum Auswerten des passenden String kommen, möchte ich noch auf ein paar Besonderheiten hinweisen. Aufmerksame Codestudenten werden bereits festgestellt haben, dass es für den key
Die Sprache ist aktuell auf Deutsch gestellt. Man kann aber bei Start des Cartrigdes durch eine einfache Multiple-Choice-Abfrage die Sprache wählbar machen und dann
Was aber passiert, wenn die Sprache auf
Im Idealfall definiert man immer alle Sprachen direkt, in der Praxis kann es aber vorkommen, dass man Erweiterungen (im Wherigo kommt eine Station hinzu und damit neue Sprachelemente) für Deutsch und Englisch direkt eintragen kann, für die spanische Version aber noch warten muss bis der passende Übersetzer (Der Austauschcacher aus Barcelona) Zeit hat die Strings zu vervollständigen. Bleibt noch die Sache mit den Parametern, z.B der Name des Cachers. Im definierten key können Platzhalter mit einer Zeichenkombi codiert werden. Es sollte eine Kombi sein, die man sonst nicht verwenden muss. Ich habe mich deswegen für
Um die Anzahl der Parameter im String flexible zu halten, bedienen wir uns des variablen
Beipspielaufrufe:
Mittels
Abb. 4 zeigt uns wie man die Übersetzungen im Wherigo aufrufen und benutzen kann. Jeweils ein Beispiel für keinen, einen oder zwei Platzhalter.
Eine Kleinigkeit fehlt noch, nämlich die strikte Trennung von Code und Übersetzung. Im Konzept der ResourceBundles trennt man diese Aspekte insofern, als dass für jede Sprache eine eigene Datei angelegt wird.
Man könnte also eine Datei
Diese Trennung ist aber optional. Ihr könnt auch alles im lua-Teil des Urwigos direkt eingeben, wenn es nicht zu unübesichtlich wird.
Voraussetzung: "Der Einstieg in lua“
"Internationalisierung bedeutet in der Informatik beziehungsweise in der Softwareentwicklung, ein Programm so zu gestalten, dass es leicht (ohne den Quellcode ändern zu müssen) an andere Sprachen und Kulturen angepasst werden kann."
So startet der aktuelle Wikipedia-Artikel das Thema Internationalisierung.
In diesem Tutorial erfährst du wie man unter Nutzung des ResourceStrings-Ansatzes dein Cartrigde in mehreren Sprachen anbieten und dabei deinen eigentlichen Code vom Sprachproblem abkoppeln kannst. Wir beginnen mit der Definition einer Variablen
language
, die wir auch gleich als persistente
Variable so ans Cartrigde anheften, dass es einen Save/Reload Vorgang übersteht.Anschließend wird ein Array
messages
erzeugt indem die unterschiedlichen Textausgaben, sortiert nach Sprachen festgehalten werden.Jetzt wird sich so mancher Entwickler fragen, warum speichert das messages-Array seine eingestellte Sprache nicht selbst sondern nutzt eine extra Variable. Der Grund hierzu liegt einzig in der Persistenzproblematik. Wir wollen ja auf keinen Fall das gesamte Array persistieren, denn an diesen Werten ändert sich zur Laufzeit nichts. Der einzig dynamische Teil ist die eingestellte Sprache, die nach dem Start z.B per Multiple-Choice ausgewählt werden kann. Um ein aufwendiges OnSave / OnRestore Prozedere zu verhindern, nutzen wir lieber den Workaround über die zweite Variable.
Für jede Sprache (in unserem Beispiel Deutsch, Englisch und Französich) wird ein Subarray wie in Zeile 5-7 definiert. Danach beginnt die eigentliche Stringdefinition.
Die Idee dabei ist, dass im Cartrigde an der Stelle wo für die Begrüßung des Spieler ein übersetzter String ausgegeben werden soll, der key
hello
verwendet wird und je nachdem welche Sprache eingestellt ist
"Herzlich Willkommen", "Welcome" oder "Bienvenue" ausgegeben wird.
Bevor wir jedoch zum Auswerten des passenden String kommen, möchte ich noch auf ein paar Besonderheiten hinweisen. Aufmerksame Codestudenten werden bereits festgestellt haben, dass es für den key
hi
kein
Wert für die englische Version definiert wurde. Wäre die Sprache auf en
gesetzt, würde hier der Wert
der defaultLanguage
(siehe Zeile 4) gezogen. Wie man so etwas auflöst folgt weiter unten.
In Zeile 13-18 stehen Beispiele für Verwendung von Platzhaltern, wenn z.B der Name des Spieler in den übersetzten
String eingebaut werden soll. Die Sprache ist aktuell auf Deutsch gestellt. Man kann aber bei Start des Cartrigdes durch eine einfache Multiple-Choice-Abfrage die Sprache wählbar machen und dann
language
auf en
oder
fr
setzen.
Nach der Definition geht es zur Verwendung der ResourceStrings. Zeile 20 wählt aus dem messages-Array zunächst das für die Sprache passende
Subarray (hier messages.de
und daraus der Eintrag für unseren key. Wird diese Funktion mit dem key
hello
aufgerufen, so besitzt value den Wert von messages.de.hello also Herzlich Willkommen zum
i18n Wherigo
. Was aber passiert, wenn die Sprache auf
en
eingestellt ist und der key hi
ausgewählt wird.
message.en.hi
ist nämlich nicht definiert. Dieser Fall ist in Zeile 22-24 behandelt. Dort wird auf die
defaultLanguage zurückgegriffen. Man sollte also darauf achten, dass für die defaultLanguage immer ein Wert
definiert ist.
Im Idealfall definiert man immer alle Sprachen direkt, in der Praxis kann es aber vorkommen, dass man Erweiterungen (im Wherigo kommt eine Station hinzu und damit neue Sprachelemente) für Deutsch und Englisch direkt eintragen kann, für die spanische Version aber noch warten muss bis der passende Übersetzer (Der Austauschcacher aus Barcelona) Zeit hat die Strings zu vervollständigen. Bleibt noch die Sache mit den Parametern, z.B der Name des Cachers. Im definierten key können Platzhalter mit einer Zeichenkombi codiert werden. Es sollte eine Kombi sein, die man sonst nicht verwenden muss. Ich habe mich deswegen für
#1#
entschieden. Bei der Auflösung des ResourceStrings wird dieser Platzhalter mittels string.gsub
durch den betreffenenden Wert ersetzt. Abb. 3 zeigt die überarbeitete getMessage
Methode in der wir Platzhalter ersetzen können.getMessage("helloWithName","Krolock")
liefert für die deutsche
Version "Hallo Krolock, wie geht es dir?"Um die Anzahl der Parameter im String flexible zu halten, bedienen wir uns des variablen
vararg
Argumentes "..."
. Man kann die
Funktion getMessage
neben dem key mit keinen, einem oder mehreren weiteren Parametern aufrufen.
Beipspielaufrufe:
getMessage("hello")
getMessage("helloWithName","Krolock")
getMessage("openDoor","XYZ","A15N")
Mittels
#arg
werden die Anzahl der Argumente ermittelt, auf die dann mit arg[1]
, arg[2]
usw zugegriffen wird
Bei mehreren Parametern muss aber auf die Reihenfolge achten, wie man an Zeile 16-18 erkennen kann. Für den key openDoor
gibt es
unterschiedliche Reihenfolgen in der deutschen und englischen Version
Abb. 4 zeigt uns wie man die Übersetzungen im Wherigo aufrufen und benutzen kann. Jeweils ein Beispiel für keinen, einen oder zwei Platzhalter.
Wie sich heute (10.03.14) erst gezeigt hat, zeigt der WhereYouGo-Player bei dem
vararg
Parameter ein etwas anderes Verhalten. Wenn die Methode getMessage
ohne zweiten Parameter aufgerufen wird (also nur mit key) so ist arg
kein leeres Array sondern nil
. Um dem vorzubeugen fügen wir in Zeile 25 if arg ~= nil then
ein, was wir in Zeile 29 mit end
wieder schließen.Eine Kleinigkeit fehlt noch, nämlich die strikte Trennung von Code und Übersetzung. Im Konzept der ResourceBundles trennt man diese Aspekte insofern, als dass für jede Sprache eine eigene Datei angelegt wird.
Man könnte also eine Datei
messages_de.lua
, messages_en.lua
und
messages_fr.lua
erzeugen und diese dann mit require "messages_de"
usw. einbetten.
Software-Entwicklungsumgebungen wie eclipse oder Intellij IDEA bieten hier viel Unterstützung bei der
Pflege der Übersetzungen. Diese Trennung ist aber optional. Ihr könnt auch alles im lua-Teil des Urwigos direkt eingeben, wenn es nicht zu unübesichtlich wird.
Update 20.04.14: Da auch der PiGo-Player Probleme mit vararg zu haben scheint, schaut euch auch den Folgeartikel Sprachausgaben übersetzten ohne vararg an.