th_biedermann
Occasional Collector

Mehrsprachigkeit externe DB Fallback Sprache

Hallo zusammen

Ich stehe vor dem Problem, dass ich eine nicht FS Datenbank habe, mit verschiedenen Sprachen DE; EN; FR.
Es sind nicht immer alle Felder in allen Sprachen gefüllt. CZ wird z.B. in EN abgefüllt.

Wie kann ich nun eine Fallbacksprache definieren z.B. EN und zuweisen, so dass wenn z.B. FS cz/cs/ ausgewählt ist, die EN Version gezogen wird.

snap099.png

Danke für einen Tipp und Grüsse

Thomas

0 Kudos
15 Replies
hoebbel
Crownpeak employee

Hallo Thomas,

das müsste über das Mapping gehen. Einfach alle Sprachen auf die entsprechende Datenbankspalte mappen, die benutzt werden soll. (dann bekommst Du zwar den Hinweis, dass doppelt gemappt wurde, aber speichern und Ausgabe sollte dennoch funktionieren).

Die gelben Markierungen im Mapping musst Du dann einfach ignorieren. Hilfreich ist in solchen Fällen, den Kommentar unter Eigenschaften zu benutzen, um dort zu erklären, warum man das gemacht hat - das hilft enorm, wenn sich das jemand in der Zukunft nochmal ansieht 😉

Oder habe ich die Anforderung falsch verstanden?

Viele Grüße
Holger

0 Kudos

Hoi Holger

Du liegst mit deiner Einschätzung wieder mal goldrichtig.

Ich bin ein wenig weiter gekommen. Jetzt habe ich noch das Problem mit den Detailseiten. Bei DE sind alle kompett. Bei EN und CZ sind nicht alle mit Inhalten gefüllt Ich habe alle Mappings bei EN; FR und CZ auf DE gemacht.

Wie muss ich das Feld bei der Ausgabe ansprechen. Mit in $CMS_VALUE(item.getValue("Stellentitel_" + lang))$

$CMS_SET(lang, #global.language.abbreviation)$
$CMS_SET(set_langArr, ss_jobLanguage.split(";"))$
$CMS_IF(set_langArr.indexOf(#global.language.toString()) != 1)$
	$CMS_SET(lang, ss_jobFallbackLang)$
$CMS_END_IF$

 

snap109.png

Was könnte hier noch das Problem sein?

0 Kudos

Hallo Thomas,

ich nehme an, dass die Detailseite wird ja mit der entsprechenden Tabellenvorlage realisiert.

In der Tabellenvorlage ist die Eingabekomponente auf die entsprechende Tabellenzelle gemappt.

Das brauchst du manuell nicht nachzubauen. Gibt einfach $CMS_VALUE(<Name der Eingabekomponente>)$ aus, also beispielsweise $CMS_VALUE(cs_stellentitel)$. 

Misstrauisch macht mich die Schreibweise ".getValue("Stellentitel_" + lang)" in deinem Beispiel. Das könnte darauf hinweisen, dass du ein Entity hast und von diesem die Informationen auslesen willst. In dem Fall würde ich das Entity in einen Dataset umwandeln und die Eingabekomponente dann mittels <dataset>.formData.<Name der Eingabekomponente> holen/ausgeben.
Den Dataset bekommst Du ab der FirstSpirit Version 2021.09 mittels <entity>.getDataset("<Uid der Tabellenvorlage>"). Mit älteren FirstSpirit Versionen ist es etwas komplizierter:

$CMS_SET(myContent2, #global.userService.getStore(class("de.espirit.firstspirit.access.store.Store$Type").CONTENTSTORE,false).getContent2ByName("<uid content2>"))$
$CMS_SET(dataset,myContent2.getDataset(<entity>))$

Bei dem manuellen Weg, den Du momentan einschlägst, musst du (wenn Du von der Entity ausgehst) den Spaltennamen aus dem Schema nehmen, also nicht das aktuellen Sprachkürzel anhängen, sondern hartkodiert das der vorhandenen Spalte. Hier kannst Du ausnutzen, dass man bei der Ausgabe mittels "default" einen Rückgriffswert definieren kann.

Das würde in dem Beispiel dann so aussehen:

$CMS_VALUE(item.getValue("Stellentitel_" + lang),default:item.getValue("Stellentitel_DE"))$

Nachteil: Die Zielsprache steht hartkodiert im Template. Ändert sich in Zukunft die Zuordnung, muss das Template angepasst werden. Kompliziert wird es, wenn es sprachabhängig verschiedene Fallbacks geben soll. Dann müssen diese vorher in eine Variable geschrieben werden und die Variable aus Fallback ausgegeben werden. Von dem Weg rate ich ab (sowohl was Wartbarkeit und Lesbarkeit des Codes als auch Performance angeht)

Viele Grüße
Holger

0 Kudos

Guten Morgen Holger

In der Zwischenzeit habe ich es irgend wie hinbekommen, dass die Inhalte der Detailseiten angezeigt werden.

Jetzt habe ich eigentlich nur noch ein kleines Problem. Die ausgeschriebenen Detailseiten haben seit dem ich auf Mehrsprachig umgestellt habe, keine Sprechendenden URL's mehr.

Beispiel:

/ch/de/karriere/offene-stellen/product-manager-–-dach-fassade-(m-w).html

/ch/de/offene-stellen/job_detail_801739.html

An was könnte das noch liegen?

Grüsse. Thomas

 

0 Kudos

Hallo Thomas,

das könnte ein größeres Problem sein. Normalerweise wird die sprechende URL ja gebildet, indem man im SiteArchitect auf der Karteikarte Daten eine Variable für die Darstellung in der Sitemap auswählt (bei Verwendung des Advanced URL Creators). Wenn die entsprechende Spalte in der Datenbank sprachabhängig ist, vervollständigt FirstSpirit die automatisch mit dem entsprechenden Sprachkürzel.

Das klappt aber bei dir nicht, da nicht für alle Sprachen entsprechende Sprachkürzel zur Verfügung stehen. Da kommt es dann zur Nutzung des Fallbacks (ich glaube das ist die UID der Seitenreferenz gefolgt von der ersten und letzten fs_id der Datensätze, die auf der Seite dargestellt werden). 

Eine saubere Lösung wäre es, einen eigenen URL Creator zu schrieben, der die gewünschten URLs erzeugt.

Oder einen View in der Datenbank zu erzeugen, der die sprachabhängigen Spalten "simuliert" und diesen als Tabelle im Schema zu referenzieren.

Wenn die URL sprachunabhängig sein darf, könnte als Workaround auch funktionieren, dass dort nicht "<Spaltennamen>* " gespeichert wird, sondern statt dessen beispielsweise "<Spaltenname>_DE". Den Workaround kann man per Skript umsetzen, z.B. in einer Beanshell Konsole, die auf dem Knoten (der steht dann in "e") aufgerufen wird:

e.setLock(true);
cp = e.getContent2Params();
cp.setSitemapVariableName("Name_DE");
e.save();
e.setLock(false);

Anstelle von "Name_DE" musst Du dann den passenden Spaltennamen verwenden, der in allen Sprachen für die URL verwendet werden soll.

ACHTUNG: ich habe das nicht getestet. Es kann gut sein, dass ich etwas nicht korrekt bedacht habe und dass der Workaround so doch nicht funktioniert.

Vielleicht habe ich auch falsch getippt, was die Ursache des Problems angeht 😉

Ich hoffe trotzdem, dass die Antwort weiterhilft

Viele Grüße
Holger

0 Kudos

Hallo Holger

Vielen lieben DANK für deine immer sehr ausführliche Hilfe.

Wir hätten einen URL-Creator order sowas ähnliches 😉

Ich frage mich wie ich das in den Deployment Prozess einbinden kann.

 

//! Beanshell
import de.espirit.firstspirit.agency.OperationAgent;
import de.espirit.firstspirit.ui.operations.RequestOperation;

operationAgent = context.requireSpecialist(OperationAgent.TYPE);
requestOperation = operationAgent.getOperation(RequestOperation.TYPE);
 
yes = requestOperation.addYes();
no = requestOperation.addNo();

requestOperation.setKind(RequestOperation.Kind.QUESTION);
requestOperation.setTitle("Urlkey Generation");
result = requestOperation.perform("Do you want to generate the URL key? Using the headline as content. Please be sure its the preferred headline. It's irreversable!");

if(result == yes) {
	urlKey = content.get().toText(false);
	
	if(urlKey.length() > 50) {
		urlKey = urlKey.substring(0, 50);
	}
	
	target.set(urlKey);
}

 

grüsse. Thomas

0 Kudos

Hallo Thomas,

ich fürchte, dass ist ein Missverständnis, da ich mich unklar ausgedrückt habe.

Mit URLCreator meinte ich ein entsprechendes Modul, welches in einer Generierungsaktion innerhalb eines Auftrag bei "Pfaderzeugung" ausgewählt werden kann. (Standardmäßig gibt es dort Advanced URL Creator, Default URLs, Infix URLs, ...)

Da können auch eigene URL Creator Implementierungen hinzugefügt werden, die die URLs anders erzeugen als bei den Standardfällen.

Aber Du hast natürlich Recht - es kann auch die URL manuell (per Skript) gesetzt werden. 

Die API Methode ist URLProperties.setStoredUrl . Die URL Properties findest Du im SiteArchitect unter Globale Einstellungen/URL Einstellungen. Um die URL für einen Datensatz zu setzen, kann man aber nicht die GUI benutzen, sondern muss das per Skript machen.

Viele Grüße
Holger

0 Kudos

Hallo Holger

Genau das habe ich eingerichtet.

snap114.png

snap116.png

snap115.png

Grüsse. Thomas

0 Kudos

Hallo Thomas,

OK - du benutzt also die AdvancedURLs. Das bedeutet, dass entweder die URL aus der Registry gelesen wird oder, wenn dort noch keine steht, eine neue erzeugt und in der Registry gespeichert wird. 

Zuerst einmal bedeutet dies, dass die URLs sich nach der ersten Generierung nicht mehr verändern werden, solange Du die nicht zurücksetzt (Im SiteStore das Kontextmenü auf der Seiten/dem Ordner aufrufen und dort Extras/Gespeicherte URLs zurücksetzen aufrufen).

Beim Erzeugen der URL wird aber festgestellt, dass es für die "Variable für Text in der Sitemap" (Karteikarte Daten) keinen Wert in den Sprachen gibt, für die es keine Spalte gibt (da wird, wenn ich mich nicht irre, die Datenbankspalte genommen und um das Sprachkürzel erweitert). 

Nach dem Zurücksetzen der URLs musst Du also per Skript neue URLs definieren und in die Registry schreiben (siehe Api-Hinweis in meiner Antwort von heute morgen). Einfach über die Entities iterieren und für jede die gewünschte URL (erzeugt aus der Überschrift der passenden Sprache) für die jeweilige Projekt-Sprache in dem gewünschten Templatesatz (bekommt man über das Project) für die Seitenreferenz, die die Detailseiten erzeugt, setzen. ACHTUNG: Du musst darauf achten, dass die URLs sich pro Sprache und pro Templatesatz unterscheiden. Doppelte URLs sind nicht erlaubt und auch nicht gewünscht 😉

Dieses Skript sollte dann auch in den Generierungsauftrag übernommen werden und die URLs jeweils vor der Generierung erneut setzen, damit neue Datensätze auch die korrekten URLs haben.

Viele Grüße
Holger

0 Kudos