final URL eines Datasets
Author: MichaelN
Publication Date: 3/12/2014 8:19
Hallo zusammen,
ich benutze quasi die UrlFactory aus den Beispielen. Das funktioniert auch wunderbar, allerdings bleibt ein Problem.
Hat man nun im Java-Client eine Produkt-Detailseite, so habe ich in meinem Modul als selected Element kein SectionImpl-Objekt, sondern ein DatasetImpl-Objekt.
Dieses ist kein ContentProducer und somit kann ich auch nicht die getUrl-Methode der UrlFactory benutzen.
Wie komme ich an die finale URL einer ausgewählten Produkt-Detail-Seite?
-
Author: kohlbrecher - 3/13/2014 10:12
Hallo Michael,
ein SectionImpl ist doch auch kein ContentProducer oder verstehe ich dich falsch?
Kannst du etwas Code posten, dann ist es leichter, dein Problem zu verstehen.
Grüße
Jan
0 -
Author: Peter_Jodeleit - 3/13/2014 10:22
Datensätze werden ja nie eigenständig generiert, sonder immer im Kontext einer Seite. Eventuell reicht es in deinem Anwendungsfall die Vorschauseite des Templates zu nehmen und die URL des Datensates in diesem Kontext anzufragen. Vorraussetzung ist da natürlich, das eine Vorschauseite definiert ist.
0 -
Author: MichaelN - 3/13/2014 11:06
Ja richtig ... die Section selbst ist kein ContentProducer, aber ich hole mir immer die dazugehörige Seite (Page) und die ist einer.
Die Frage müsste auch eigentlich lauten: "wie komme ich über das Dataset an die dazugehörige Page?", die z.B. am Ende so Deployed wird,
http://[Mithras-Deploy-Domain]/Produkte/Kristalline-Module/Christallinemodule-Produkt_960.html
wenn der Redakteur den entsprechenden Datensatz gerade bearbeitet (siehe Screenshot):
Hintergrund ist, dass ich in dem jeweiligen template einen FS_Button habe, der auch wunderbar für Seiten und Absätze funktioniert und mir anhand des aktuell vom Redaktuer ausgewählten Contents die Deployment-URL generiert , aber eben nicht für Datasets.
0 -
Author: MichaelN - 3/13/2014 11:12
Der FS_Button führt im Übrigen diesen Code aus:
IDProvider selectedElement = (IDProvider) paramMap.get("element");
BaseContext context = (BaseContext) paramMap.get("context");
Language language = (Language) paramMap.get("language");
MyPlugin.doWhatIMean(context, selectedElement , language);
0 -
Author: Peter_Jodeleit - 3/13/2014 11:15
Interessanter wäre wohl der Problem-relevante Code innerhalb von "MyPlugin.doWhatIMean(..)" :smileywink:
0 -
Author: Peter_Jodeleit - 3/13/2014 11:19
Eventuell hilft aber schon dieses Stückchen Pseudo-Code:
Dataset dataset = ...;
PageRef pageref = ...;Language language = ..;
TemplateSet templateset = ...;
pageref.getStoredUrl(language, templateset, dataset.getEntity());
0 -
Author: MichaelN - 3/13/2014 11:21
Bei einer Section komme ich so (recursiv) an die Page:
selectedElement.getParent()
und damit noch mittels getIncomingReferences den PageRef um das Template set zu holen
contentProducer.getProject().getTemplateSets()
dann rufe ich die URL factory auf:
urlFactory.getUrl(pageRef, templateSet, language, pageParams); Aber bei einem aufgewählten Dataset geht das halt (so) nicht.
0 -
Author: MichaelN - 3/13/2014 12:45
Aber wie komme ich an die PageRef eines DataSets. So geht es nicht, da referenceEntries imme rleer ist!?:
public static PageRef getPageRefFromStoreElement(StoreElement storeElement) {
ReferenceEntry[] referenceEntries = storeElement.getIncomingReferences();
for (ReferenceEntry referenceEntry : referenceEntries) {
IDProvider idProvider = referenceEntry.getReferencedElement();
if (!(idProvider instanceof PageRef)) {
continue;
}
return (PageRef) idProvider;
}
return null;
}
0 -
Author: MichaelN - 3/24/2014 8:42
Und dann bleibt noch die Frage wo ich dann bei einem dataSet die PageParams herbekomme?
geht doch auch nur über die PageRef? oder? Und wenn ja bleibt wieder die Frage, wo die PageRef herkommt?(siehe oben)
0 -
Author: Peter_Jodeleit - 3/24/2014 14:30
Wieso gehst du nicht den von mir skizzierten Weg?
[EDIT]
An das Dataset kommst du mit "context.getElement()".
0 -
Author: MichaelN - 3/26/2014 7:33
gerne, aber ich weiß halt nicht, wie ich an das pageRef rankomme um pageref.getStoredUrl aufzurufen.
Mir fehlt also quasi der Teil:
PageRef pageref = ...;
0 -
Author: Peter_Jodeleit - 3/26/2014 12:04
Eine Möglichkeit wäre z.B. so: dataset.getTableTemplate().getPreviewPageRef()
0 -
Author: MichaelN - 3/26/2014 13:44
Das war es ... danke schön. Mit der PageRef funktioniert es dann ja auch mit dem gewünschten Weg.
0 -
Author: MichaelN - 4/11/2014 14:44
Das war es doch nicht :smileysad:
Zumindest in der Mithras-Responsiv Version ist das dataset.getTableTemplate().getPreviewPageRef() immer dasselbe für alle Produkte aller Kategorien.
Nachtag: Auch in der normalen Mithras Version bekomme ich als URL immer:
/Produkte/[Kopiervorlage]-Modulwechselrichter-150W-12V-Mini.html
für alle Produkte.
Es sollte aber am Ende eigentlich z.B.:
/Produkte/Solarspeicher/Accum-1-000-L.html
entstehen.
0 -
Author: MichaelN - 9/30/2014 12:24
Gibt es hier schon eine Lösung?
0 -
Author: Peter_Jodeleit - 9/30/2014 12:55
Hm, meiner Meinung nach steht schon alles hier. Die Bestimmung der Seitenreferenz ist abhängig vom Kontext. Außerdem kann es ja durchaus gewünscht sein, das ein Datensatz an mehreren Stellen gerendert wird. Dein Problem, das die URL eines ganz anderen Datensatzes herauskommt, kann ich aber nicht nachvollziehen.
0 -
Author: MichaelN - 9/30/2014 13:48
Hmmm .. hier ist nochmal der fertige Code, der aber im Falle eines Dataset immer die Url des Produktes liefert, welches ((Dataset) storeElement).getTableTemplate().getPreviewPageRef() für alle Elemente einer Datenquelle gleich ist. Vielleicht ist hier noch ein Gedankenfehler!?
Erst mal der Einstieg über einen Button im Template selbst ...
public class MyExecutable implements Executable{
@Override
public Object execute(Map<String, Object> paramMap) throws ExecutionException {
IDProvider selectedElement = (IDProvider) paramMap.get("element");
BaseContext context = (BaseContext) paramMap.get("context");
Language language = (Language) paramMap.get("language");
MyClass.doit(context, selectedElement , language);
return null;
}
@Override
public Object execute(Map<String, Object> paramMap, Writer paramWriter1, Writer paramWriter2) throws ExecutionException {
return null;
}
}
Und dann der Code, der mir die entsprechende URL zum selectedElement liefern soll ...
protected String getUrl() {
StoreElement storeElement = selectedElement;
PageRef pageRef;
if (storeElement instanceof Dataset) {
pageRef = ((Dataset) storeElement).getTableTemplate().getPreviewPageRef();
} else {
// get PageRef from page
}
final TemplateSet templateSet = fetchTemplateSet(pageRef);
PageParams pageParams = pageRef.getMultiPageParams(language, templateSet).getPageParams(0);
final UrlFactory urlFactory = config.createUrlFactory();
return urlFactory.getUrl(pageRef, templateSet, language, pageParams);
}
0 -
Author: Peter_Jodeleit - 9/30/2014 14:23
Du hast einige Hinweise in diesem Thread ignoriert :smileywink:
Kurzfassung ist: Für Datensätze bitte diesen Code benutzen
pageref.getStoredUrl(language, templateset, dataset.getEntity())
0 -
Author: MichaelN - 10/1/2014 7:05
Ich hatte das schon versucht, dann aber aufgegeben, da die Methode getStoredUrl an der Stelle null lieferte.
Jetzt habe ich das noch mal probiert und festgestellt, dass gerade meine getesteten Entities null liefern. Andere gehen aber wie gewünscht.
z.B. bei dem Produkt KM 12 poly im Mithras Responsive Design liefert die Methode null zurück. Es existiert aber die URL: /Produkte/Kristalline-Module/Christallinemodule-Produkt_1044.html nach dem Deployment.
Woran liegt das?
0 -
Author: Peter_Jodeleit - 10/1/2014 7:19
Dann wird bei der Generierung eine URL-Strategie ohne Persistenz benutzt. Stell doch mal den Auftrag um, so dass z.B. "Advanced URLs" als Strategie benutzt wird.
0 -
Author: MichaelN - 10/1/2014 7:28
Soweit ich das sehen kann steht das auf "Advanced URLs"
0 -
Author: Peter_Jodeleit - 10/2/2014 11:50
[EDIT]
Hm, die URL Produkte/Kristalline-Module/Christallinemodule-Produkt_1044.html sieht aber nicht nach "Advanced URLs" aus... 1044 ist die ID des entsprechenden Datensatzes?
Sprache und Template-Satz sind bei deinem Aufruf korrekt?
0 -
Author: MichaelN - 2/3/2015 14:01
Hilft leider alles nichts.
Jetzt habe ich auch schon die neue Mithras-Version installiert und die Seiten auch komplett (und Fehlerfrei) generiert.
Die Seite und die Änderrungen sind auch ordnungsgemäß deployed, allerdings liefert getStoredUrl trotzdem null.
0 -
Author: mbergmann - 2/3/2015 20:12
Hallo Michael,
wie schon anfangs von Peter erwähnt hat ja ein Datensatz für sich alleine NIE eine URL, sondern immer nur die Kombination "Seitenreferenz der ContentProjektion"+Datensatz.
Kann es sein, dass Du mit der falschen Seitenreferenz arbeitest? Es muss die sein, über die die Detailseite des Datensatzes auch erzeugt wird - nur dort wird die entsprechende Information "eingetragen".
Oft ist das die Vorschauseite, das muss aber nicht sein - das kommt aufs Projekt an. Wenn ich es richtig im Kopf habe, ist das im Mithras nicht so, darauf deutet auch der Dateipfad der Detailseite - der enthält nämlich die Produktkategorie als Ordner. Ich meine, die einzelnen Detailseiten werden im Mithras je nach Kategorie des Produktes von verschiedenen Seitenreferenzen mit entsprechenden Filtern erzeugt.
D.h. Du müsstest erst die "passende" Seitenreferenz (letztlich diejenige, die für die Detailseiten der Kategorie des Produktdatensatzes "zuständig" ist) finden und dann genau diese pageRef nach der storedUrl für den Datensatz fragen.
Viele Grüße
Michael
0 -
Author: MichaelN - 2/4/2015 6:52
Hallo und danke für die Antwort.
Das Problem, was ich ja von Anfang an hatte ist, dass ich nicht programmatisch herausbekomme, welche Verwendung - es gibt augenscheinlich
keine!? - hier vorhanden ist.
Bis jetzt habe ich den _empfohlenen_ Ansatz über:
PageRef pageRef = ((Dataset) storeElement).getTableTemplate().getPreviewPageRef();
versucht, aber das liefert ja anscheinend nicht das gewünschte.
D.h. Du müsstest erst die "passende" Seitenreferenz (letztlich diejenige, die für die Detailseiten der Kategorie des Produktdatensatzes "zuständig" ist) finden und dann genau diese pageRef nach der storedUrl für den Datensatz fragen.
"finden" heiß, dass muss projektspezifisch manuell geschehen, oder gibt es einen programmatischen Weg? Gerade mit dem Hintergrund, dass es eigentlich ja nur einen Weg (URL) zum Ziel (Produkt-Detailseite) geben sollte, und in diesem Projekt ja auch gibt?
0 -
Author: MichaelN - 2/4/2015 6:58
Es bleibt im Übrigen die Frage offen, warum es für einige Produkte über
getTableTemplate().getPreviewPageRef()funktioniert und andere null liefern!?0 -
Author: MichaelN - 2/4/2015 8:12
Ich versuche nun den vorgeschlagenen Weg.
Der Code sieht wie folgt aus:
((PersistentList) ((Dataset) contentElement).getEntity().get("categoriesList")).get(0)
Damit komme ich nun an das Entity der Kategorie. Wie kann ich dann nun das passende Dataset der Kategorie-Entity (storeElementFromCategoryEntity) bekommen um mir dann wieder per
((Dataset) storeElementFromCategoryEntity).getTableTemplate().getPreviewPageRef();
die zugehörige PageRef zu holen?
Sprich wie komme ich an das passende Dataset einer Entity?
Ist das wirklich der gewünschte und _einfachste_ Weg zum Ziel?
0 -
Author: MichaelN - 2/4/2015 9:03
Also ... schlussendlich bekomme ich als pageRef wieder mal null.
final ContentStoreRoot contentStore = (ContentStoreRoot) storeElement.getProject().getUserService().getStore(Type.CONTENTSTORE, false);
Content2 content2 = contentStore.getContent2ByName("kategorien");
Entity entity = ((Entity)((PersistentList) ((Dataset) contentElement).getEntity().get("categoriesList")).get(0));
Dataset dataset = content2.getDataset(entity);
pageRef = dataset.getTableTemplate().getPreviewPageRef(); // liefert null
0 -
Author: MichaelN - 2/4/2015 9:27
Und bei diesem Ansatz ist urlPath null:
public static PageRef getFirstPageRefFromStoreElement(StoreElement storeElement) {
ReferenceEntry[] referenceEntries = storeElement.getIncomingReferences();
for (ReferenceEntry referenceEntry : referenceEntries) {
IDProvider idProvider = referenceEntry.getReferencedElement();
if (!(idProvider instanceof PageRef)) {
continue;
}
return (PageRef) idProvider;
}
return null;
}
final ContentStoreRoot contentStore = (ContentStoreRoot) storeElement.getProject().getUserService().getStore(Type.CONTENTSTORE, false);
Content2 content2 = contentStore.getContent2ByName("kategorien");
Entity entity = ((Entity)((PersistentList) ((Dataset) contentElement).getEntity().get("categoriesList")).get(0));
Dataset dataset = content2.getDataset(entity);
pageRef = getFirstPageRefFromStoreElement(dataset);urlPath = pageRef.getStoredUrl(language, templateSet, ((Dataset) storeElement).getEntity());
0 -
Author: mbergmann - 2/4/2015 9:47
Hallo Michael,
die entsprechenden Seitenreferenzen findest Du nicht über die eingehenden Referenzen eines Datensatzes, das Ergebnis von Abfragen schlägt sich (bis auf ganz bestimmte Ausnahmen) nicht im Referenzgraph nieder - hast Du Dir den mal angesehen?
Ich gehe jetzt mal vom "alten" Mithras aus. Dort haben die entsprechenden Seitenreferenzen Verbindungen zur Produkte-Tabellenvorlage (quasi über den Daten-Reiter).
Du könntest also die eingehenden Referenzen auf der Produkte-Tabellenvorlage durchgehen, dort nur die Seitenreferenzen betrachten und jede(!) davon nach der StoredUrl für den Datensatz fragen.
Hintergrund ist hier, dass die einzelnen Detailseiten entsprechende Filter gesetzt haben und immer nur die Deteilseiten einer Kategorie anzeigen. Nur bei der Seitenreferenz die hier "zum Datensatz passt" wird hier während der Generierung die URL eingetragen.
Rein theoretisch(!) könntest Du über die API auch noch weiter in die Seitenreferenzen "reinlaufen" (Stichwort Content2Params) und gezielter prüfen ob in der Abfrage die ID der Kategorie des jeweiligen Datensatzes steht. Das würde es aber nur unnötig kompliziert machen - pragmatischer ist es hier, einfach alle eingehenden PageRef-Referenzen (auf die Produkte-Tabellenvorlage) nach der URL des jeweiligen Datensatzes zu fragen und sobald Du etwas bekommst abzubrechen.
Viele Grüße
Michael
0
Vous devez vous connecter pour laisser un commentaire.
Commentaires
30 commentaires