choff
Returning Observer

Rückgabe einer Datenstruktur von einem Executable in ein Template

Jump to solution

Hallo,

ich würde gern ein Executable ein paar Dinge ermitteln lassen und dies dann in einem Template weiterverwenden.

Wann das zu Ermittelnde ein String ist, ist das ja möglich, indem man im Template mit $CMS_RENDER(script: ...)$ ein Skript aufruft und in diesem mittels

#!executable-class

KlassenName-Wie-In-Module-XML

das Executable aufruft. Wenn der Rückgabewert des Executables ein String ist, erscheint dieser dann direkt als Ausgabe des Templates.

Nun würde ich aber gern den Rückgabewert des Executables im Template noch weiter verwenden und nicht einfach direkt ausgeben. Ist das möglich?

Mit Rendertemplates ist so etwas ja möglich, indem man im aufrufenden Template eine Variable z.B. als leere Liste definiert, diese an das Rendertemplate als Parameter übergibt und im Rendertemplate dann Dinge in die Liste einfügt mit $CMS_SET(void, uebergebeneListe.add(...))$. Nach der Rückkehr aus dem Rendertemplate hat sich im aufrufenden Tempalte die Variable verändert und enthält die von Rendertemplate angefügten Elemente. - Ich habe vorhin versucht, diesen Weg auch in der Konstellation Template mit $CMS_RENDER(script: ...)$ -> Skript -> Executable zu gehen, aber dort scheint es nicht zu funktionieren. Habe ich etwas falsch gemacht oder ist es prinzipiell nicht möglich?

Viele Grüße,

Christian

0 Kudos
1 Solution

Accepted Solutions
mbergmann
Crownpeak employee

Hallo,

einen Wert "einfach so von außen" in den Kontext zu schreiben finde ich nicht wirklich "schön", wenn dann sollte der Name der Variablen dem Executable übergeben werden - ist aber immer noch ein bisschen zu viel "Magie" meiner Meinung nach.

Mein "Standard-Weg" ist hier noch etwas anders - so wie ich es schon grob skizziert hatte:

Im Template:

$CMS_SET(set_result,{:})$

$CMS_RENDER(script:"some_script_name", result:set_result)$

$-- und dann z.B. sowas: --$

$CMS_VALUE(set_result.someKey.someMethod())$

$-- oder --$

$CMS_SET(set_someResultObject, set_result.anotherKey)$

Im Skript "some_script_name":

#!executable-class

My_Executable_Name_From_Module_XML

Im Executable:

...

Map<String, Object> result = (Map<String,Object>) params.get("result");

...

result.put("someKey", someResultObject);

result.put("anotherKey", anotherResultObject);

...

Wenn man tatsächlich nur einen Wert braucht, kann man natürlich statt der Map auch eine leere Liste übergeben uns sich da dann das erste Element heraus holen.

Was mir an dem Ansatz gefällt: Es ist "weniger Magie". Insbesondere tauchen nicht irgendwelche Variablen in irgendwelchen Kontexten auf. Alles was man im Template als Variable nutzt hat man auch vorher als Variable dort definiert.

Welche Objekte dann unter den einzelnen Keys zu finden sind, kann man gut im ApiDoc des Executables dokumentieren. Mit der Map-Variante ist man da auch recht flexibel - wenn sich später herausstellt, dass man "mehr" braucht, kann man das recht "schön" ergänzen.

Viele Grüße

Michael

View solution in original post

0 Kudos
7 Replies
mbergmann
Crownpeak employee

Hallo Christian,

doch, das geht - habe ich schon öfter gemacht.

Du brauchst allerdings trotzdem ein Skript-Objekt, das dann auf das Executable "veweist".

Ist das Skript auch vom Typ "Vorlage"?

Viele Grüße

Michael

0 Kudos

Hallo Christian,

benötigst Du noch weitere Hilfe oder hat Dir Michaels Antwort bereits geholfen? In diesem Fall wäre es super, wenn Du die "richtige Antwort" entsprechend markierst, damit auch andere Community-Teilnehmer diese auf den ersten Blick finden. Solltest Du zwischenzeitlich eine eigene Lösung gefunden haben, wäre es nett, wenn Du diese hier bereitstellst.

Viele Grüße

Tim

0 Kudos
ChKo
Elite Observer

Hallo,

soweit ich weiß sollte es da zwei Möglichkeiten geben:

a) Im Executable die Rückgabe in einen der Kontexte schreiben:

Beispiel: context.getGenerationContext().getPageContext().setVariableValue("set_pt_myValue", "MAGIC!");

Dies hat den Vorteil, dass auch mehrere oder komplexere Werte übergeben werden können.

b) Falls die Rückgabe nur ein String sein soll, könnte man folgendermaßen im Template-Code verfahren:

$CMS_SET(set_myResult)$$--

--$$CMS_RENDER(script:"my_script")$$--

--$$CMS_END_SET$

$CMS_SET(set_myValue,set_myResult.toString())$$-- .toString() muss auf die Variable ausgeführt werden, da ansonsten das Template-Document nicht geparsed wird --$

Die Variable "set_myValue" hätte nun das Ergebnis der Executable und könnte weiter manipuliert werden, bevor es in einem $CMS_VALUE()$ ausgegeben wird.

Gruß,

Christopher

0 Kudos
mbergmann
Crownpeak employee

Hallo,

einen Wert "einfach so von außen" in den Kontext zu schreiben finde ich nicht wirklich "schön", wenn dann sollte der Name der Variablen dem Executable übergeben werden - ist aber immer noch ein bisschen zu viel "Magie" meiner Meinung nach.

Mein "Standard-Weg" ist hier noch etwas anders - so wie ich es schon grob skizziert hatte:

Im Template:

$CMS_SET(set_result,{:})$

$CMS_RENDER(script:"some_script_name", result:set_result)$

$-- und dann z.B. sowas: --$

$CMS_VALUE(set_result.someKey.someMethod())$

$-- oder --$

$CMS_SET(set_someResultObject, set_result.anotherKey)$

Im Skript "some_script_name":

#!executable-class

My_Executable_Name_From_Module_XML

Im Executable:

...

Map<String, Object> result = (Map<String,Object>) params.get("result");

...

result.put("someKey", someResultObject);

result.put("anotherKey", anotherResultObject);

...

Wenn man tatsächlich nur einen Wert braucht, kann man natürlich statt der Map auch eine leere Liste übergeben uns sich da dann das erste Element heraus holen.

Was mir an dem Ansatz gefällt: Es ist "weniger Magie". Insbesondere tauchen nicht irgendwelche Variablen in irgendwelchen Kontexten auf. Alles was man im Template als Variable nutzt hat man auch vorher als Variable dort definiert.

Welche Objekte dann unter den einzelnen Keys zu finden sind, kann man gut im ApiDoc des Executables dokumentieren. Mit der Map-Variante ist man da auch recht flexibel - wenn sich später herausstellt, dass man "mehr" braucht, kann man das recht "schön" ergänzen.

Viele Grüße

Michael

0 Kudos
choff
Returning Observer

Hallo Tim (und Christopher und Michael),

vielen Dank für eure Antworten, ich bin noch nicht dazu gekommen, diese Vorschläge auszuprobieren. Bisher lasse ich das Executable einfach einen String zurückgeben und das funktioniert für unseren Anwendungsfall. Prinzipiell interessiert es mich aber sehr, auch andere Datenstrukturen zurückzugeben, deshalb möchte ich, sobald ich Zeit habe, wieder zu diesem Thema zurückkehren und eure Vorschläge ausprobieren.

Viele Grüße,

Christian

0 Kudos
choff
Returning Observer

Danke Michael,

so geht es. Ich hatte wohl etwas falsch gemacht. Vielleicht wollte ich einen neuen Parameter durch params.put("rueckgabewert", ...) einfügen.

Viele Grüße,

Christian

0 Kudos
choff
Returning Observer

Danke Christopher,

für deine Antwort. Ich hatte mehr so etwas gesucht in der Richtung, wie Michael es geschrieben hat. Ist aber auf jeden Fall interessant zu sehen, was man noch so machen kann. Vielleicht ist das in anderem Zusammenhang ja mal ganz nützlich.

Viele Grüße,

Christian

0 Kudos