LanguageCopy-Funktion in AdminCentral

Vor einigen Monaten bekam ich die Aufgabe eine Funktion im Magnolia-Backend umzusetzen, die es dem Autor erlaubt, eine Seite (wahlweise rekursiv) einer Sprache in alle anderen gewünschten und verfügbaren Sprachen zu kopieren. In diesem Beitrag werde ich erläutern, welche Komponenten für die Umsetzung nötig waren und den dazugehörigen Code liefern. Der Code ist ausschliesslich für Magnolia 4.5.x und kann nicht 1:1 auf Magnolia 5 angewendet werden. Der Dialog sieht am Schluss so aus:

LanguageCopy-Dialog

1. Neuer Kontextmenü-Eintrag

Da die Funktion über das Kontektmenü im Website-Tree aufgerufen werden soll, müssen wir zuerst das Kontextmenü um einen neuen Eintrag erweitern. Dies geschieht in dem wir den Website-Tree unter /modules/adminInterface/trees/website mit einer neuen configurationClass ausstatten.

Unsere Java-Klasse
Wir legen also eine neue Klasse CustomWorkflowWebsiteTreeConfiguration in unserem Magnolia-Projekt an und erweitern die Klasse WorkflowWebsiteTreeConfiguration um die bestehende Funktionalität zu übernehmen. In der neuen Klasse überschreiben wir die Methode prepareContextMenu(Tree tree, boolean browseMode, HttpServletRequest request), um auf das Kontextmenü Einfluss zu nehmen.

CustomWorkflowWebsiteTreeConfiguration.java

Der browseMode gibt Auskunft über die Art wie der Website-Tree aufgerufen wird. Bindet man den Website-Tree z.B. als iFrame mit der URL http://example.com/trees/website.html?browseMode=true wird er in einer reduzierten Form angezeigt, in der alle Info-Spalten wie Titel, Aktivierungs-Status, Template und Modifikations-Datum ausgeblendet sind und das Kontextmenü nur eine „Refresh“-Option anzeigt. Der Website-Tree mit browseMode=true wird z.B. bei der Erstellung eines internen Links im Richtext-Editor verwendet. In unserem Code zeigen wir unser Kontextmenü nur dann an, wenn der browseMode nicht aktiv ist, was der Normalfall ist.

In der Methode addContextMenuItemLanguageCopy() bauen wir unseren neuen Kontextmenü-Eintrag zusammen. Hierbei definieren wir Label, Icon, onClick-Event und Konditionen die erfüllt sein müssen, um den Eintrag anzuzeigen. Zu beachten ist, dass wir als onClick-Event eine Javascript-Methode in einer noch nicht existierenden Javascript-Klasse angegeben haben. Diese gilt es noch zu erstellen. Zudem wird dieser Methode als Parameter der zu öffnende Dialog mitgegeben. Diesen Dialog, in dem dann die LanguageCopy-Funktion konfiguriert und ausgeführt wird, gilt es ebenfalls noch zu definieren.

Das Javascript
CustomDialogOpener.js

Unsere Javascript-Klasse agiert als Mittelmann in dem sie die Methode mgnlOpenDialog von Magnolia aufruft und ihr den Pfad zu unserem LanguagaCopy-Dialog und den Pfad zu der Page auf der der Kontextmenü-Klick ausgeführt wurde, übergibt. Damit die Javascript-Klasse auch ins AdminCentral geladen wird, muss sie im Projekt unter mgnl-resources/js-classes/com/example/CustomDialogOpener.js abgelegt werden.

Der Kontextmenü-Eintrag sieht schlussendlich so aus:

LanguageCopy Kontextmenü

2. Der LanguageCopy-Dialog

Was jetzt noch fehlt ist unser LanguageCopy-Dialog, der die Eingaben des Autors auswertet und die Kopier-Logik schlussendlich ausführt.

Für den Dialog werden wir einige neue Java-Klassen benötigen:

  • LanguageCopyDialogHandler.java wird ausgeführt, wenn der Autor auf “Speichern” klickt. Die Klasse wertet die Eingaben des Autors aus und startet die Kopier-Logik.
  • LanguageCopy.java erweitert DialogButtonSet.java und ist ein custom control, das dem Autor die Kopier-Ziele als Checkboxen anzeigt.
  • ShowMgnlVariable.java ist ein weiteres custom control, das dem Autor den Wert eines URL-Parameters in der Dialog-URL anzeigt. Es ist rein informativer Natur.

Die Dialog-Definition
LanguageCopy Dialog-Definition

Der Dialog in Aktion
LanguageCopy-Dialog

 

Dialog Handler
LanguageCopyDialogHandler.java

Dieser Code überschreibt die onSave()-Methode und führt die Kopierlogik aus. Für die rekursive Kopierlogik können wir hier auf die JCR-API zurückgreifen und die copy()-Methode verwenden. Nach dem Kopiervorgang, aktualisieren wir die Metadaten creationDate, modificationDate und authorID und setzen den Aktivierungs-Status der frisch kopierten Seiten auf “deaktiviert”.

Der Programmcode um nur eine Seite zu kopieren befindet sich in der Methode copyPage(). Diese Methode legt zuerst den Page-Node der zu kopierenden Seite an. Anschliessend werden alle Area-Nodes kopiert und zuletzt alle Properties auf den neu kopierten Node übertragen.

LanguageCopy Custom Control
LanguageCopy.java

Dieses Custom Control ermittelt die möglichen Kopier-Destinationen und zeigt sie dem Autor als Checkboxen an.

Für die Umsetzung leiten wir von der Klasse DialogButtonSet ab. Diese Klasse ist normalerweise für das Rendern von Checkboxen, Radio-Buttons und Select-Listen verantwortlich. Anstatt die Checkbox-Optionen aus der Dialog-Definition zu lesen, generieren wir diese dynamisch, nachdem wir ermittelt haben, welche möglichen Kopier-Destinationen zur Verfügung stehen. Existiert die Seite bereits in allen Sprachen oder fehlt der Eltern-Knoten in den anderen Sprach-Ästen, wird eine Fehlermeldung anstatt den Checkboxen gerendert.

ShowMgnlVariable Custom Control
ShowMgnlVariable.java

Dieses Custom Control holt einen Parameter aus dem Request und zeigt dessen Wert als statischen Text an. Wir verwenden es, um den Pfad der zur kopierenden Seite im Dialog anzuzeigen.

Umgesetzt wird es, in dem wir von der DialogStatic-Klasse erweitern. Das Static-Control zeigt normalerweise den im value-Property definierten String als Label im Dialog an. Wir überschreiben aber für unsere Funktionalität die drawHtml()-Methode und suchen in der Control-Definition nach dem key-Property und versuchen den dort eingetragenen Wert als Attribut im aktuellen Request zu finden. So können wir z.B. mgnlPath als key angeben und es wird uns im LanguageCopy-Dialog ein Label mit dem Pfad der zu kopierenden Seite gerendert.

 

Hinterlasse eine Antwort

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind markiert *

*

*

Du kannst folgende HTML-Tags benutzen: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>