Hallo,
gerade das generelle Problem gelöst, habe ich im Umfeld Mehrsprachigkeit direkt das nächste.
In einer Anwendung werden Dokumente mit einer Kategorie gegliedert. Über diese Kategorie werden auch Berechtigungen vergeben, d.h. in Abhängigkeit zur gewählten Kategorie wird im Hintergrund ein Leserfeld berechnet.
Diese Dokument-Kategorie wird natürlich auch in Ansichten zur Kategorisierung genutzt.
Jetzt soll die XPage-basierte Webversion mehrsprachig aufgebaut werden. Intern wird mit einem deutschsprachigen Notes-Frontend gearbeitet.
Die Kategorien müssen also jetzt auch mehrsprachig werden. Die anderen Dokument-Inhalte bleiben in Originalsprache und werden nicht übersetzt.
In den XPages für die Dokumentanzeige habe ich das folgendermaßen umgesetzt bekommen :
1) Unter den Ressourcen je unterstützter Sprache eine Textdatei angelegt (categories.properties, categories_en.properties, etc.). Die Textdatei ist wie folgt aufgebaut :
<Kategorie>=<Übersetzung der Kategorie>
z.B. Preise=Prices
2) In der XPage sind die Dateien als Ressourcenbundle eingebunden (siehe Screenshot 1)
3) Im berechneten Feld ist als Wert folgender Code hinterlegt :
var cat = document1.getItemValueString("Category")
var catStr = String(cat);
return categories[catStr];
Okay, die zweite Zeile kann ich mir vermutlich schenken, aber egal ;)
Das funktioniert soweit wunderbar. Je nach Browsersprache werden die jeweiligen Werte aus den Textdateien korrekt angezogen.
Die Kategorien in den Views sollen natürlich auch übersetzt werden. Ich habe mir gedacht, mach ich das mal nach dem selben Schema und habe erstmal in einer nichtkategorisierten View getestet.
Punkte 1 und 2 von oben sind in der XPage für die View identisch eingebaut. In der Spalte im View Control ist dann folgender Code hinterlegt :
var cat = @ReplaceSubstring(rowData.getColumnValue("Category")," ","");
var catStr = String(cat);
return categories[catStr];
Das ReplaceSubstring brauche ich an der Stelle, weil die Originalkategorien teilweise Spaces enthalten und das immer zu Fehlern geführt hat. In den Textdateien sind die Leerzeichen ebenfalls entfernt und damit funktioniert dann auch die Übersetzung wunderbar.
Wunderbar, also habe ich das so auch in kategorisierten Views umsetzen wollen. Und da knallt es dann, ohne daß ich das irgendwie nachvollziehen kann. Der Aufbau ist wie oben beschrieben umgesetzt, der einzige Unterschied ist, daß die Spalte in der Ansicht halt kategorisiert und nicht nur sortiert ist.
Fehlermeldung im Browser :
Error while executing JavaScript computed expression
Script-Interpreterfehler, Zeile=1, Spalte=5: Unbekanntes Element '' in Java-Klasse 'java.util.PropertyResourceBundle'
Das ist diese Code-Zeile :
var cat = @ReplaceSubstring(rowData.getColumnValue("Category")," ","");
Hat da jemand ne Idee ?
Oder gibt es eine bessere Alternative, um an der Stelle die Mehrsprachigkeit zu erreichen ?
Für die View mußte ich noch ein wenig basteln, habs jetzt aber soweit ich das testen konnte lauffähig. Allerdings ist mein Fall vermutlich etwas speziell, da die zu lokalisierende Kategorie immer gefüllt ist. Ich muß hier also keine Leerwerte berücksichtigen.
Daher noch ein paar Tipps, falls noch jemand vor dem Problem steht.
Der grobe Aufbau ist im Ausgangsposting skizziert. Probleme hatte ich vor allem mit der Anzeige von Nicht-Kategoriezeilen und künstlichen Unterkategorien (z.B. Kategorie\\Unterkategorie).
Mein Script zur Berechnung der lokalisierbaren Spalte sieht jetzt so aus :
var cat = @ReplaceSubstring(rowData.getColumnValue("Category")," ","");
var catStr = String(cat);
if (catStr=="") {
return "";
} else {
return categories[catStr];
}
Somit bekomme ich in einer Kategoriezeile den lokalisierten String für die Kategorie und in allen Nicht-Kategoriezeilen einen Leerwert.
Die künstlichen Unterkategorien setzt das View Control automatisch um. Das war für mich die nächste Falle, denn ich hatte in den Sprachdateien immer nur die vollständigen Kategorien übersetzt, also z.B.
Werbemittel\Anzeige=Advertising\Ad
Dann läuft man allerdings auf einen Runtime Error, weil Kategorie und künstliche Unterkategorie getrennt übersetzt werden. Man muß also in den Sprachdateien jeweils alle möglichen Kategorien und Unterkategorien einbauen, also in diesem Beispiel :
Werbemittel=Advertising
Anzeige=Ad
Worauf mich Stephan Wissel noch auf Stackoverflow hingewiesen hat :
Die Sortierung der übersetzten Kategorien entspricht der Sortierung der Ausgangssprache.
Kategorien in der Ausgangssprache
Auto
Baum
Haus
Strasse
Kategorien in Englisch
Car
Tree
House
Street
Dafür habe ich auch noch keine Lösung.
Die Sortierung der übersetzten Kategorien entspricht der Sortierung der Ausgangssprache.
Auch das ist lösbar; habe hier eine ähnliche Konstellation. Da habe ich in der ersten Spalte die ID eines Dokuments in unserer Anwendung. Die muss "übersetzt" werden, weil sonst die Sortierung der Spalte im Frontend nach der ID und nicht nach dem CompanyName erfolgt.
Ich setze dafür ein xe:objectData control aus der ExtensionLib ein. Hat zudem noch den Vorteil, daß es einen intelligenten Cache Mechanismus enthält. Aber das nur am Rande.
<xe:objectData var="companies"
createObject="#{javascript:new com.isatweb.cois.ObjectDataCompany();}"
scope="view" />
</xp:this.data>
In einem POJO baue ich die Daten zusammen. Hier erfolgt auch die Übersetzung der ID in den lesbaren Namen. Als Rückgabe erhalte ich eine Liste, die die jeweiligen Company ObjeKte mit ihren Eigenschaften enthält. ( Name, Größe etc ) Diese Liste kann ich sortieren.
Das objectData ist an eine DataTable gebunden, in der ich dann die Werte darstelle
<xp:dataTable id="data_table_companies" rows="15" var="entry"
value="#{javascript:companies.getCompanyList()}">
<xp:column id="colCompanyName">
<xp:this.facets>
<xp:label id="hdrCompanyName" xp:key="header" value="${langString_CRM['COMPANYNAME']}"
themeId="cois.column.header" />
</xp:this.facets>
<xp:text escape="true" id="txtCompanyName" value="#{entry[0]}" />
</xp:column>
Noch ein Hinweis. Die globalen Variablen für die Sprache stehen beim Aufruf des objectData Objects (noch) nicht zur Verfügung. Daher muss mann den Zugriff auf die resourcen ebenfalls in den Java Code verlegen.