Oracle APEX bietet out-of-the-box die Möglichkeit, eine Anwendung in mehreren Sprachen zu veröffentlichen. Wie das funktioniert, möchte ich Ihnen in diesem Beitrag näher erläutern.
TIPP!
Bitte beachten Sie auch meinen Post zum Thema
Gefahren und Fallen beim Umgang mit APEX Translations
In diesem Beitrag sind noch weitere nützliche Tipps enthalten, die Ihnen viel Zeit sparen werden.
Szenario
Wir möchten eine Anwendung schreiben, die in 2 Sprachen, Englisch und Deutsch, verfügbar ist. Die Sprache soll sich automatisch ändern, wenn die Browsersprache geändert wird.
Als Standardsprache für die Entwicklung legen wir die englische Sprache fest, da wir uns international positionieren möchten.
Als kleine Zusatzanforderung möchten wir, dass beim Wechsel der Sprache das Datumsformat sich automatisch auf das jeweilige lokale Format anpasst (für deutsch: DD.MM.YYYY, für englisch: DD/MM/YY).
Vorgehensweise
- Festlegen der Standardsprache (in welcher Sprache wird entwickelt?)
- Festlegen, auf welche Weise die Sprache gewechselt werden kann
- Applikationseinstellungen für das Sprachhandling vornehmen
- Applikation in eine andere Sprache übersetzen
- Weitere notwendige Aktionen
- Formatmaske für Datumsfelder angeben
- Tipps und Tricks beim Umgang mit Translation Files
Zu 1: Festlegen der Standardsprache (in welcher Sprache wird entwickelt?)
Am Anfang sollte man sich überlegen, in welcher Sprache die Anwendung realisiert wird (Primary Language). APEX nutzt diese als Basis für alle weiteren Übersetzungen.
Wie wir bereits festgelegt haben, soll die Standardsprache für die Entwicklung englisch sein.
TIPP!
Entwickeln Sie in der Sprache, die für Sie am wichtigsten ist und die als erstes veröffentlicht werden soll. Alle weiteren Übersetzungen können später jederzeit noch hinzugefügt werden.
Die Standardsprache wird automatisch immer dann verwendet, wenn eine Sprache aktiv ist, für die es keine Übersetzung gibt!!!
Bitte beachten Sie auch, dass jede Änderung an den Labels oder Texten in der Standardsprache Änderungen in allen Übersetzungen nach sich zieht!
Zu 2: Festlegen, auf welche Weise die Sprache gewechselt werden kann
Legen sie fest, wie die Sprache innerhalb der Anwendung geändert werden kann. Hierbei sollte man sich überlegen, ob die Sprachanpassung automatisch oder durch benutzereingriff erfolgen soll.
APEX bietet ihnen hierzu folgende Möglichkeiten zur Sprachauswahl:
– Übernahme der Browsersprache
– Einstellen der Sprache über eine Umgebungsvariable namens FSP_LANGUAGE_PREFERENCE
– Einstellen der Sprache über eine selbst definitere Umgebungsvariable
In diesem Beispiel soll sich die Sprache analog zu der im Browser eingestellten Sprache verhalten. D.h. sie soll automatisch wechseln, wenn die Browsersprache geändert wird.
Zu 3: Applikationseinstellungen für das Sprachhandling vornehmen
Zuerst machen wir die globalen Einstellungen für das Sprachhandling in der Applikations-Definition.
- Über „Shared Components“ -> „Definition“ -> „Globalization“ müssen wir 2 Einstellungen machen.
- „Application Primary Language“ auswählen
Wählen Sie hier die Standardsprache, die wir zuvor als Primary Language festgelegt haben, aus (in unserem Beispiel „English (en)“.
-
- “Application Language Derived From” auswählen.
Wählen Sie hier „Browser (use browser language preference)“ aus.
-
- Optional geben wir hier schon mal das Standard-Datumsformat für die englische Sprache an (DD/MM/RRRR)
Zu 4: Applikation in eine andere Sprache übersetzen
Nun wollen wir die eigentliche Übersetzungsarbeit durchführen. Dazu gehen Sie bitte, wie folgt, vor.
- Über „Shared Components“ -> „Translate Application“ (in der Region „Globalization“) gelangen Sie in das Translation Menü. Dieses Menü muss nun, mehr oder weniger, von oben nach unten durchgearbeitet werden.
- Klicken Sie auf “1. Map your primary language application to a translated application” und dann auf “Create”.
Hier wird nun zuerst einmal die Sprache erzeugt, die veröffentlicht werden soll. Wir machen nun die notwendigen Eingaben und setzen folgende Werte:
TIPP!
In dem Feld “Translation Application” wird eine eindeutige ID erwartet, die man jedoch selbst vergeben muss. Wenn man viele Applications auf einer Instanz erzeugt hat, wird das etwas schwierig mit der Eindeutigkeit. Deshalb meine Empfehlung: Überlegen Sie sich eine Regel, wie Sie IDs für Übersetzungen verwenden. Sie können z.B., wie in unserem Beispiel, die ID der Primary Language (in unserem Falle 150) nehmen und eine Stelle anhängen und diese dann einfach für jede Übersetzung um 1 erhöhen (1501 deutsch, 1502 italienisch, 1503 spanisch, usw.)
- Über die Breadcrumb Region gehen wir zurück zum Translation Menü und erzeugen das Translation-File.
- Klicken auf „Seed and export the translation text of your application into a translation file.”
- Sprache auswählen und Texte erzeugen
Hier werden nur die von uns angelegten Sprachen angezeigt. In unserem Beispiel existiert nur die „1501 de“. Diese wählen wir aus und klicken auf „Seed Translatable Text“.
Wir gelangen nun in den XLIFF Export. Hier können wir entscheiden, ob wir die Übersetzungen für die gesamte Anwendung oder nur für bestimmte Seiten erzeugen wollen. Zudem kann ausgewählt werden, ob alle Übersetzungstexte oder nur die, die eine Übersetzung benötigen, exportiert werden sollen.
Wir wollen nun die gesamte Anwendung übersetzen und auch nur die Texte, die eine Übersetzung benötigen.
Wir wählen hier nun die Application aus, markieren die Option „Only those elements requiring translation“ und klicken auf „Export XLF File for Application“, um das Übersetzungsfile zu erzeugen.
Es wurde nun eine Datei mit allen notwendigen Übersetzungen erzeugt (f150_1501_en_de.xlf). Dies ist nun die Basis, auf der wir die Texte übersetzen müssen. In unserem kleinen Beispiel können wir die Texte nun direkt in dem erzeugten File ändern (Bitte nur jeweils die „Target“-Texte ändern!!!). Bei einer richtigen Anwendung kann das allerdings ziemlich viel Aufwand werden.
Hinweis!
Unter Punkt 7 finden Sie noch einige Tipps und Tricks für das Übersetzen der Texte und den Umgang mit den Translation-Files.
- Haben wir die Texte im Translation-File übersetzt, müssen wir die Übersetzung noch veröffentlichen.
- In der Breadcrumb Region klicken wir auf „Translate Application“ und dann auf „4. Apply your translation file and publish“.
- Auf der Seite „XLIFF Translation Files“ klicken wir nun auf „Upload XLIFF“ um das Translation File hochzuladen. Wir machen folgende Eingaben:
Title: 1501_de
Description: <irgendeine Beschreibung für das Import File>
XLIFF File: <auswählen der Datei mit unseren Übersetzungen, in unserem Fall f150_1501_en_de.xlf>
-
- Nachdem wir auf „Upload…“ geklickt haben, wird uns die importierte Datei angezeigt. Klicken Sie nun auf den Title der Datei und wählen im folgenden Dialog die Sprache aus, für die die Übersetzung bestimmt ist („apply to“ – in unserem Fall „1501 de“).
- Klicken Sie nun auf „Apply XLIFF Translation File“, prüfen Sie im folgenden Dialog, dass bei „Create Application“ die richtige Applikation angezeigt wird (ggf. korrigieren) und dann oben rechts auf „Publish Application“, um die Sprache schließlich zu veröffentlichen.
Hinweis!
APEX erzeugt für jede veröffentlichte Sprache eine eigene Applikation. Im Hinblick auf die Performance ist das sicherlich eine sehr gute Lösung. Jedoch werden Sie früher oder später sehen, dass dies auch einige Nachteile hat. Wenn wir nämlich nun PLSQL-Code verändern, der nichts mit irgendwelchen Übersetzungs-relevanten Texten zu tun hat, müssen wir trotzdem alle Übersetzungen erneut veröffentlichen, da APEX teilweise auch funktionalen Code dupliziert und für jede Übersetzungs-Applikation explizit vorhält. Mehr dazu finden Sie unter „Gefahren und Fallstricke beim Umgang mit APEX Translations“.
Zu 5: Weitere notwendige Aktionen
Übersetzen von internen APEX Messages
Wenn Sie die Anwendung nun aufrufen und Ihren Browser auf z.B. „German (de)“ umstellen, werden Sie feststellen, dass einige Labels noch in englischer Sprache dargestellt werden. Z.B. werden in einer Reportmaske mit Seitennavigation die „Next“/“Previous“ Labels noch in Englisch dargestellt.
Grund hierfür sind die APEX internen Messages, die nicht out-of-the-box in das Translation-File exportiert werden. Eine Aufstellung aller internen Messages finden Sie unter folgendem Link in Kapitel „Table 16-3 Internal Messages Requiring Translation“.
http://download.oracle.com/docs/cd/E10513_01/doc/appdev.310/e10499/global.htm#BABFHCJA
Um diese internen Messages zu übersetzen, gehen Sie bitte wie folgt vor.
- „Shared Components“ -> unter „Globalization“ auf „Text Messages“ und dann auf „Create“ klicken.
- Geben Sie bei Name den gewünschten Substitution String aus der Tabelle „Internal Messages Requiring Translation“ (zuvor erklärt) ein.
- Wählen Sie die Sprache aus, die als Hauptsprache bei der Application angegeben wurde (bei uns „Englisch“).
- Geben Sie den Übersetzungstext ein (in englisch).
Hier können auch Platzhalter eingegeben werden. Um z.B. den Info-Text in der Navigations-Popupliste (X_Y_of_Z: row(s) 1 – 10 of 12) zu ändern, geben Sie bei Name „WWV_RENDER_REPORT3.X_Y_OF_Z“ und bei Text z.B. „Zeile(n) %0 – %1 von insgesamt %2“ ein.
Beachte!
Diesen Vorgang müssen Sie für alle benötigten internen Messages durchführen.
- Nun, wie unter Punkt 4 beschrieben, die übersetzten Applikationen neu erzeugen (der Punkt „Map your Primary Language Application to…“ kann weggelassen werden, da die Anwendung bereits gemapt ist). Wenn die gerade angelegten Texte in der Hauptsprache erzeugt wurde, werden diese Texte ebenfalls mit in die jeweiligen XLF-Files eingetragen. Nach dem Übersetzen und „publishen“ müssten auch hier nun die Übersetzungen angezeigt werden.
TIPP!
Sollten diese internen Messages nun nicht im Translation-File auftauchen, lesen Sie bitte den Beitrag Interne Messages und dynamische Übersetzungen werden nicht in das XLF-File exportiert.
HINWEIS!
Alle Übersetzungstexte für interne Messages können auch hier komplett erstellt werden. Jedoch ist der Weg über die Translation-Files der bessere, wenn die Übersetzungsarbeit von einem Übersetzer durchgeführt wird.
Übersetzen von statischen Wertelisten
Wenn Sie statische Wertelisten verwenden die nicht über eine LOV implementiert, sondern mit „STATIC:…“ einfach bei dem entsprechenden Item eingegeben wurden, so werden diese Inhalte nicht übersetzt.
Hierfür sollten Sie auf jeden Fall eine statische LOV erzeugen und ausschließlich diese verwenden (auch im Sinne von Wiederverwendbarkeit sinnvoll!). Statische LOV-Werte werden beim erzeugen der Translation-Files (siehe oben) mit exportiert und können dann zusammen mit den anderen Texten übersetzt werden.
Übersetzen von dynamischen Wertelisten
Ein weiteres Problem besteht darin, LOV-Werte, die dynamisch aus der Datenbank ermittelt werden, zur Laufzeit zu übersetzen. APEX stellt dafür eine PLSQL-API zur Verfügung (APEX_LANG).
Wie das funktioniert, möchte ich Ihnen hier kurz zeigen.
Gegeben sei eine Wertelist, die verfügbare Sprachen darstellt und auswählbar macht. Diese Sprachen sind in einer Datenbanktabelle mit dem Namen „LANGUAGE“ eingetragen (In unserem Beispiel sind nur 2 Einträge in der Tabelle für „German“ und „English“).
Gehen Sie bitte wie folgt vor.
- Übersetzungstexte für alle Werte der Tabelle LANGUAGE erzeugen.
- Über „Shared Components“ -> „Translate Application“ (Globalization) -> “Optionally identify any data that needs to be dynamically translated …” -> “Create” einen neuen Text in der gewünschten Übersetzungssprache erzeugen.
Language: “German (Germany) (de)” auswählen
Translate From Text: “German” (das ist der Key bzw. der Text, der in der Tabelle vorhanden ist und übersetzt werden muss).
Translate To Text: „German“ (das ist der Text, der angezeigt werden soll).
-
- “Create” klicken, um den Text anzulegen.
- Das Gleiche machen wir nun mit allen Sprachen, die in der Tabelle vorhanden sind und übersetzt werden müssen.
Hinweis!
Ich habe hier als Übersetzungstexte die englischen Texte eingegeben, um das Szenario aufzuzeigen. Wenn Sie hier direkt die richtigen Übersetzungstexte eingeben, sparen Sie sich die spätere Übersetzung.
Beachte!
Wenn Sie diese dynamischen Texte in der Hauptsprache (in unserem Fall „Englisch“) eingeben, werden diese Texte, im Gegensatz zu den anderen Text-Messages, nicht in das XLIFF-File exportiert! Deshalb sollten Sie darauf achten, direkt die richtige Sprache auszuwählen.
- Erzeugen einer LOV zur Selektion dieser Sprachen.
Beim Erzeugen der LOV müssen wir die Apex Language API (APEX_LANG) benutzen, um auf die Übersetzungstexte zuzugreifen. Das Statement für die LOV sieht dementsprechend wie folgt aus.
- Nun müssen wir die LOV dem Item zuweisen, welches diese Werteliste beinhalten soll.
- Nun, wie unter Punkt 4 beschrieben, die übersetzten Applikationen neu erzeugen. Wenn die gerade angelegten dynamischen Werte in der Hauptsprache erzeugt wurden, werden diese ebenfalls mit in die jeweiligen XLF-Files eingetragen. Nach dem Übersetzen und „publishen“ müssten auch hier nun die Übersetzungen richtig angezeigt werden.
HINWEIS!
Alle Übersetzungstexte für interne Messages können auch hier komplett erstellt werden. Jedoch ist der Weg über die Translation-Files der bessere, wenn die Übersetzungsarbeit von einem Übersetzer durchgeführt wird.
- Weitere Informationen zum Umgang mit der APEX_LANG-API hierzu finden Sie unter
https://docs.oracle.com/cd/E23903_01/doc.41/e21676/apex_lang.htm#AEAPI354
Übersetzen sonstiger dynamischer Inhalte
Nun kann sich auch noch die Notwendigkeit ergeben, Werte aus anderen Tabellen, die in Reports oder Formularen benötigt werden, zu übersetzen. Hierfür stellt APEX noch eine andere Funktion der APEX_LANG-API zur Verfügung.
APEX_LANG.MESSAGE
Das Handling hierfür ist fast identisch zu dem vorherigen Punkt („Übersetzen von dynamischen Wertelisten“). Der Unterschied besteht hauptsächlich darin, dass der Übersetzungstext in APEX an einer anderen Stelle eingetragen wird.
Zum Erstellen des Übersetzungstextes klicken Sie bitte unter „Shared Components“ -> „Text Messages“ (Globalization) -> und klicken auf „Create“. Bei Namen bitte den Text bzw. Key eintragen (der Text aus der Tabelle, der übersetzt werden soll), wählen die Sprache aus und tragen den Übersetzungstext ein. Fertig!
Nun können Sie innerhalb Ihres Codings (im Prinzip überall, wo Sie PLSQL-Code verwenden), mit der APEX_LANG-API auf diesen Text zugreifen.
Beispiel: (Dieses Statement würde die Städtenamen aus der Tabelle PERSONEN übersetzen, wenn zuvor die Städte als Übersetzungstexte angegeben worden sind)
SELECT APEX_LANG.MESSAGE(city) FROM PERSONEN;
Weitere Informationen zur APEX_LANG-API finden Sie unter
http://download.oracle.com/docs/cd/E10513_01/doc/appdev.310/e10499/global.htm#insertedID0
ACHTUNG BUG in Version 3.2.1!!!
Wenn man zuvor eine Translation zu einer Sprache mit einer anderen ID erstellt und dann gelöscht hatte (z.B. zuvor die „151 de“), dann bleiben Fragmente in der Tabelle WWV_FLOW_TRANSLATABLE_TEXT$ die verhindern, dass eine deutsche Übersetzung mit einer anderen ID (jetzt 1501) erstellt werden kann. Als workaround geht folgendes:
- Die Translation, die Probleme macht, löschen.
- Gesamte Applikation exportieren
- Gesamte Applikation löschen
- Applikation importieren.
Nun kann die Translation wieder normal angelegt und damit gearbeitet werden.
Zu 6: Formatmaske für Datumsfelder definieren
Wie Sie Formatmasken in APEX definieren können, finden Sie hier.
Datumsformate applikationsweit defnieren
Einen Beitrag zum Thema „Localization“ für Datums- und Zeitformate kommt bald. Sollten Sie Informationen dazu benötigen, können Sie mich gerne kontaktieren.
Zu 7: Tipps und Tricks zum Umgang mit Translation Files
In diesem Beitrag wurde nun erklärt, wie man mit APEX eine Anwendung mehrsprachig auslegen kann. Nun stellen sich allerdings noch folgende Fragen.
- Wer übersetzt denn nun eigentlich die ganzen Texte?
- In welcher Form stelle ich dem Übersetzer die Texte zur Verfügung?
Naja, die Antwort auf die 1. Frage ist recht einfach – die Übersetzer!
Im Unternehmen haben wir vielleicht Leute die gut genug englisch sprechen, um die englische Übersetzung zu machen. Aber was ist mit den anderen Sprachen? Hierfür benötige ich natürlich einen oder vielleicht sogar mehrere Übersetzer.
Und schon sind wir bei der 2. Frage. In welcher Form kann ich den Übersetzern meine Texte zur Verfügung stellen?
Das Problem
Die Translation Files (XLF-Files) sind so unübersichtlich, dass ein Übersetzer mir dieses wahrscheinlich nach spätestens 5 Minuten um die Ohren schlagen würde.
Also was tun?
- Nicht benötigte Labels und Texte von den Translations ausschließen
APEX bietet eine Möglichkeit, ein paar unnötige Übersetzungen zu unterdrücken. Das macht auch durchaus Sinn, da eh schon genügend Texte als Übersetzungen erkannt und vorgeschlagen werden, die gar keine Übersetzung benötigen.
-
- Unnötige Region Labels unterdrücken
Bei den Region-Attributes gibt es die Möglichkeit, die Option „exclude title from translation“ anzuklicken. In diesem Fall wird der Region-Title nicht als Übersetzung eingetragen. Diese Option macht Sinn für Hilfs-Regions, die nicht angezeigt werden.
-
- Templates von den Translations ausschließen
Bei den Templates gibt es die Möglichkeit, ein Template komplett auszuschließen. Sie sollten also prüfen, ob statische Texte in Ihren Templates enthalten sind. Wenn nicht, markieren Sie die entsprechenden Templates als „non-translatable“ (wie folgende Abbildung zeigt).
- Nur die Texte in das Translation File exportieren, die eine Übersetzung benötigen
Sie können beim erzeugen des XLF-Files die Option „Only those elements requiring translation“ auswählen. Dadurch werden schon mal eine nicht benötigte Texte ausgeschlossen.
- Übersetzungstexte über APEX Dialog bearbeiten
APEX bietet einen Dialog, um Übersetzungstexte direkt im APEX Builder zu bearbeiten. Hinweis!
Beim späteren Erzeugen des Translation Files (XLF) werden die Änderungen erkannt und dort eingetragen.
- XLF-File in eigene Tabelle laden und Maske bauen
In meinem letzten Projekt haben wir ein JAVA-Programm geschrieben, um das komplette XLF-File in eine eigene Datenbanktabelle zu schreiben. Für diese Tabelle haben wir einen einfachen änderbaren Report entwickelt, mit dem wir die Übersetzungstexte ganz einfach bearbeiten konnten. Ein zweites kleines JAVA-Programm hat die übersetzten Texte aus der Tabelle gelesen und ein neues APEX-konformes XLF-File erzeugt. Dieses konnten wir dann importieren, um damit die benötigen übersetzten Applications zu erzeugen.
Bei Interesse stellen wir Ihnen diese JAVA Programme gerne zur Verfügung (natürlich kostenlos – auch gerne mit Source-Code, damit Sie diese Programme für sich anpassen können).
- Übersetzungstexte aus Repository auslesen
Zu diesem Punkt habe ich einen eigenen Post geschrieben.
Hallo,
ich weiß es ist einige Zeit her, seit Sie diesen Bericht geschrieben haben.. Ich studiere derzeit an der DHBW Karlsruhe und habe die Aufgabe bekommen in Apex die Möglichkeiten Applikationen zu übersetzen, zu verbessern. Ich wunderte mich, ob die JAVA Programme noch existieren und ich diese evtl. benutzen kann? Vielleicht wäre das eine passende Lösung.
Vielen Dank
Sara
Hallo Sara,
das Java Programm existiert noch und klar, kannst du dieses benutzen.
Ich habe 2 Zip-Files bereitgestellt. Eines mit den ausführbaren Utilities und eines mit dem Sourcecode. In Apex_Translation_Util.zip ist ein ReadMe File. Dort stehen einige Anweisungen zum Umgang.
Apex_Translation_Util.zip
Apex_Translation_Util_src.zip
Schau mal, ob du damit klar kommst. Wenn nicht, melde dich gerne noch mal.
Viel Erfolg für dein Studium.
VG
Volker
Hallo,
super toller Beitrag.
Ich wunderte mich, da der Beitrag schon einige Zeit her geschrieben wurde, ob die JAVA-Programme noch existieren und ob ich diese dann evtl. verwenden kann?
Vielen Dank
Sara
Hallo,
endlich habe ich mal eine verständliche Anleitung gefunden, aber was ich immer noch nicht verstanden habe:
Wie kann ich denn bei einem Textfield das Label dynamisch anzeigen lassen? Also wie lautet die Syntax das Apex den Labelnamen von einer Textmessage selektiert?
Gruß,
Christian
Hallo Christian,
zuerst einmal muss ich dir leider die Illusion nehmen, dass die Labels dynamisch angezeigt werden. Es gibt zwar Möglichkeiten, bestimmte Labels dynamisch zu ändern, aber das APEX-Konzept für die Translations ist etwas anders. Ich hatte eigentlich gehofft, dass dies aus meinem Beitrag hervorgeht. Aber egal.
APEX Konzept zur Mehrsprachigkeit
Man entwickelt zuerst eine Basis-Application in einer Sprache (z.B. Deutsch), wobei die Sprache bei den Application-Properties festgelegt wird, wie ich es oben beschrieben ist (Punkt 1). APEX stellt nun die Möglichkeit zur Verfügung, für jede weiter benötigte Sprache eine EIGENE Application zu erzeugen (oben beschrieben unter Punkt 4). D.h. du legst mit APEX-Mitteln eine neue Application an, exportierst diese und übersetzt dann alle exportierten Texte. Dann importierst du dieses übersetzte XLIFF-File wieder über die Translation-Mechanismen. APEX verwaltet diese App dann zwar als eigene Application, weiß aber, dass dies die Übersetzung deiner „Basis“-Application ist. Wenn du nun, nachdem du die Übersetzungs-App importiert hast, dich anmeldest erkennt APEX die Sprache (hierbei unbedingt Punkt 2 oben berücksichtigen) und switcht automatisch um auf die ein oder andere Sprache (bzw. App), vorausgesetzt, für die Sprache, die erkannt wurde, wird eine Application gefunden. Das bedeutet, dass APEX hier nichts dynamisch macht, sonder eine Art Schatten-App einstellt, die statische Texte beinhaltet. Ich denke mal, dass dies aus Laufzeitgründen so gemacht wurde, weil Dynamik kostet Performance!!!
Am besten probierst du das mal mit einer Demo-App aus, die nur ein oder zwei Pages besitzt. Dann wirst du es verstehen. Und wenn nicht, meld dich gerne wieder.
Viel Erfolg, Volker