pstrohmeyer
Occasional Observer

Plugin für Datenquellen im ContentCreator ?

Hallo zusammen,

im Zusammenhang eines Kundenwunsches würden wir gerne die Datenquellenansicht im ContentCreator erweitern (bspw. über ein InlineEdit Plugin)

blobid1.png

Wir hatten verschiedene Plugintypen ausprobiert:

  • WebeditInlineEditItemsPlugin
  • MediaManagementItemsPlugin
  • WebeditToolbarActionsItemsPlugin

Per WebeditToolbarActionsItemsPlugin kriegen wir über den ToolbarContext Zugriff auf das Content2 Element, allerdings nicht das vom User ausgewählte Dataset
Im ODFS und der access + dev API konnten wir keinen gesonderten Context oder Plugintypen für die ContentCreator Ansicht für Datenquellen finden.

Weiß jemand ob es eine Möglichkeit gibt die Ansicht zu erweitern (bspw. über ein InlineEdit Plugin) um an die vom User ausgewählten Entities/Dataset Objekte dranzukommen?

VG

5 Replies
marcel_ruths
Returning Observer

Fast 3 Jahre nach diesem Post, leider keine Antwort bzgl. Crownpeak zu diesem Thema.

Auch für uns wäre eine solche Integration als Inline-Edit Plugin an Datensätzen sehr hilfreich. An anderen Stellen funktioniert das Inline-Edit Plugin Management bei uns bereits sehr gut. 

Im Zuge dessen wäre es sicherlich sinnvoll neben der Datenquellen-Ansicht auch die Medien-Verwaltung mit zu berücksichtigen da auch hier potentiell der Need besteht mit Inline-Edit Buttons an Medien zu arbeiten.

Wir haben uns als Workaround damit beholfen ein "Skript" an den Datensätzen zu hängen. Das lässt sich nämlich "Inline" integrieren. Über den "Execute Script" Button am Datensatz gibt es hier eine Auswahl der potentiellen Skripte. Es wäre schön wenn man solche "Scripte" auch als Plugin in ein Modul auslagern könnte.

Eine entsprechende Idee mit Feature Request habe ich bereits erstellt.

0 Kudos
mbergmann
Crownpeak employee

Hallo Marcel,


Im Zuge dessen wäre es sicherlich sinnvoll neben der Datenquellen-Ansicht auch die Medien-Verwaltung mit zu berücksichtigen da auch hier potentiell der Need besteht mit Inline-Edit Buttons an Medien zu arbeiten.

Für die Medienverwaltung geht das ja schon länger - nur eben nicht über ein InlineEdit-Plugin (das für die Nutzung innerhalb der Vorschauseite gedacht ist) sondern über ein MediaManagementItemsPlugin.

Was die Datenquellen angeht, gibt es seit kurzem auch eine Möglichkeit - quasi die Entsprechung zum MediaManagementItemsPlugin - nur eben für die Datenquellen-Ansicht. 

Das ist aktuell allerdings (noch) eine Art "Spezialfall" - aus technischen Gründen (separates Artefakt...) ist das aktuell noch nicht im ApiDoc enthalten, da sind wir aber dran.

Es ist aber in diesem Ausnahmefall schon möglich (und in Ordnung), das zu nutzen. Hierzu muss zusätzlich "de.espirit.cxt.cc:cxt-cc-api:2.2.8" als Abhängigkeit eingebunden werden (ist über das Cloud-Artifactory verfügbar). Bitte nicht mit ins FSM legen - wie auch die fs-isolated-runtime.jar darf das nur als "provided" genutzt werden, also z.B. folgendermaßen in der build.gradle:

...
dependencies {
...
compileOnly group: 'de.espirit.cxt.cc', name: 'cxt-cc-api', version: "2.2.8"
compileOnly group: 'de.espirit.firstspirit', name: 'fs-isolated-runtime', ...
...
}

Relevant sind hier die Interfaces in de.espirit.cxt.cc.plugin.entity - im Endeffekt sind die "analog" zu denen im Paket de.espirit.firstspirit.webedit.plugin.media (für das MediaManagementItemsPlugin).

"Einstiegspunkt" ist dann entsprechend das EntityManagementItemsPlugin.

 

Wichtiger "Disclaimer" in dem Zusammenhang:

Nicht alles, was da sonst noch so drin liegt sollte einfach so genutzt werden - die entsprechende Doku kommt wie gesagt später noch. Es gilt weiterhin, dass nur "offiziell dokumentierte Klassen/Methoden" genutzt werden sollten - mit der hier beschriebenen Ausnahme für das EntityManagementItemsPlugin bzw. das o.g. package mit den dafür benötigten Interfaces.

Ich hoffe, das hilft 😉

Viele Grüße

Michael

 

marcel_ruths
Returning Observer

Hi Michael, danke für die Ausführlichen Infos und Details. Wir verwenden allerdings eine OnPrem Variante von FS. Könnt ihr uns die cxt-cc-api zur Verfügung stellen? Oder uns per file.crownpeak.com zukommen lassen? Ich vermute wir haben keinen Zugriff auf die Cloud-Artifactory?

Die Integration als "provided" ist mir soweit klar. Wir verwenden zwar Maven statts Gradle aber das ist wird ja dann wie du schon sagest analog wie bei der isolated runtime integriert.

Wichtig wäre noch wir verwenden aktuell noch Verson 2025-01. Können wir damit ebenfalls schon auf das EntityManagementItemsPlugin zugreifen?

Und letzte Frage ich habe dann zum Schluss einfach ein ExecutableEntityManagementItem und ClientScriptProvidingEntityManagementItem zur Verfügung was ich dann einbauen kann?

 

0 Kudos
marcel_ruths
Returning Observer

Hi @mbergmann ich habe mir einige Fragen bereits selbst beantwortet. Das cxt-cc-api package habe ich mir auf unserem FS-Server aus dem cxt-cc.fsm Modul geholt und dann bei uns in Maven eingebunden. Mit Version 2025-01 gibt es die passenden Klassen bereits allerdings ist es hier die Version 2.6.24 die verwendet wird.

Die notwendigen Klassen bzw. Import sind bzw. heißen:

import de.espirit.cxt.cc.plugin.entity.EntityManagementItemsPlugin;
import de.espirit.cxt.cc.plugin.entity.ExecutableEntityManagementItem;
import de.espirit.cxt.cc.plugin.entity.EntityManagementItem;
import de.espirit.cxt.cc.plugin.entity.EntityManagementContext;
import de.espirit.cxt.cc.plugin.entity.ClientScriptProvidingEntityManagementItem;

Natürlich sind die Methoden alle als "Unstable" markiert, ich nehme an das ihr diese noch zu de.espirit.firstspirit.webedit. Umziehen werdet zur API. Gibt's hier schon Pläne wann das der Fall sein wird? Außer der Lokation wird sich nichts mehr ändern oder nehm ich mal an sonst hättest du uns hier sicherlich die Nutzung nicht empfohlen.?

Für alle weiteren die es hier helfen sollte: Hier unser "Minimal-Example" zur Darstellung einer FS-ID eines Datensatzes in einer Message-Box in der Datensatz-Ansicht. Natürlich könnte man damit dann auch diverse weitere Executable oder Client-Script Plugins analog zum MediaManagement oder Inline-Toolbars bauen.

Michael vielen Dank nochmal für die Informationen und auch das schnelle Feedback. Es war im Grunde ja alles bereits da lediglich die Dokumentation und die Freigabe fehlt aktuell noch👌


/**
* Plug-in to provide menu items for use in the ContentCreator dataset item menu. These menu actions present the
* FS-ID of a dataset in the ContentCreator.
*/
public class PageInfoInlineDatasetItemsPlugin implements EntityManagementItemsPlugin {

private BaseContext baseContext;

/**
* Setup method. Store the context this dataset menu item plug-in operates in.
*
* @param context The context the plug-in lives in.
*/
@Override
public void setUp(@NotNull final BaseContext context) {
baseContext = context;
}


/**
* Closure method. If necessary, destruct any objects that cannot be handled properly by the garbage collector.
*/
@Override
public void tearDown() {
baseContext.logDebug("tearDown is called");
}

@NotNull
@Override
public Collection<? extends EntityManagementItem> getItems() {
return Collections.singletonList(new ShowDatasetFSID());
}


/**
* This class defines a JavaScript toolbar menu item that displays a message box with a FS ID of the current selected dataset
*/
private static class ShowDatasetFSID implements ExecutableEntityManagementItem {

public static final String BEGIN_QUOTE = "\"";
public static final String END_QUOTE = BEGIN_QUOTE + " );";
public static final String SHOW_MESSAGE = "top.WE_API.Common.showMessage(";

/**
* Return the absolute or relative URL to an icon image file.
*
* @param context The item's operational context.
* @return The path to an icon image file.
*/
@Override
public String getIconPath(@NotNull final EntityManagementContext context) {
return "icons/database-search-icon.svg";
}


/**
* Return the label of this menu item.
*
* @param context The item's operational context.
* @return A label text.
*/
@NotNull
@Override
public String getLabel(@NotNull final EntityManagementContext context) {
return LocalizedMessage.INLINE_FS_ID_TITLE.text(
context.requireSpecialist(WebeditUiAgent.TYPE).getDisplayLanguage().getLocale());
}


/**
* This method assembles and returns the JavaScript code as a simple {@link String} object; the code will be executed
* on the client side when the menu item is clicked. The JavaScript here draws a simple message box with the FS ID
* of the dataset selected.
*
* @param context The item's operational context.
* @return A {@link String} of JavaScript code.
*/
@Override
public void execute(final EntityManagementContext context) {
final OperationAgent operationAgent = context.requireSpecialist(OperationAgent.TYPE);
ClientScriptOperation operation = operationAgent.getOperation(ClientScriptOperation.TYPE);
if (context.getElement() != null)
{
IDProvider element = context.getElement();
if (element instanceof Dataset) {
showDatasetFsID(context.getElement(), operation);
}
else if (element instanceof PageRef) {
showPageRefFsIDs(context.getElement(), operation);
}
else if (element instanceof Page) {
showElementFsID(context.getElement(), operation, "The Page ID is: ");
}
else
{
showElementFsID(context.getElement(), operation, "The Element ID is: ");
}
}
else
{
showMessageWithFsID(operation, SHOW_MESSAGE + BEGIN_QUOTE + "Error - The ID of the element could not be determined"
+ END_QUOTE);
}
}

private static void showElementFsID(IDProvider element, ClientScriptOperation operation, String x) {
Object fsId = element.getId();
if (!fsId.toString().isEmpty()) {
showMessageWithFsID(operation, SHOW_MESSAGE + BEGIN_QUOTE + x + fsId
+ END_QUOTE);
}
}

private static void showPageRefFsIDs(IDProvider element, ClientScriptOperation operation) {
Object fsId = element.getId();
Object fsPageId = ((PageRef) element).getPageId();
if (!fsId.toString().isEmpty() && !fsPageId.toString().isEmpty()) {
showMessageWithFsID(operation, SHOW_MESSAGE + BEGIN_QUOTE + "The PageRef ID is: " + fsId + " and the referenced PageID is: " + fsPageId
+ END_QUOTE);
}
}

private static void showDatasetFsID(IDProvider element, ClientScriptOperation operation) {
Object fsIdField = ((Dataset)element).getFormData().get(null, "fs_id").get();
if (fsIdField != null) {
String fsId = fsIdField.toString();

showMessageWithFsID(operation, SHOW_MESSAGE + BEGIN_QUOTE + "The dataset ID is: " + fsId
+ END_QUOTE);
}
}

private static void showMessageWithFsID(ClientScriptOperation operation, String message) {
operation.perform(message, false);
}


/**
* Determine if this menu item should be enabled or disabled, depending on the current context.
*
* @param context This item's current operational context.
* @return {@code true} if the menu item should be enabled, {@code false} if it should be disabled.
*/
@Override
public boolean isEnabled(@NotNull final EntityManagementContext context) {
return true;
}


/**
* Determine if this menu item should be visible or not, depending on the current context.
*
* @param context This item's current operation context.
* @return {@code true} if the menu item should be shown in the menu, {@code false} if it should be hidden.
*/
@Override
public boolean isVisible(@NotNull final EntityManagementContext context) {
final IDProvider element = context.getElement();
return ((element instanceof Section && !(element instanceof SectionReference) && !(element instanceof Content2Section)) || element instanceof Page || element instanceof PageRef || element instanceof Dataset);
}
}
}


0 Kudos

Hallo Marcel,

ich nehme an das ihr diese noch zu de.espirit.firstspirit.webedit. Umziehen werdet zur API. Gibt's hier schon Pläne wann das der Fall sein wird? Außer der Lokation wird sich nichts mehr ändern oder nehm ich mal an sonst hättest du uns hier sicherlich die Nutzung nicht empfohlen.?

ich habe intern nochmal nachgefragt.

Kurzversion: Nein, eine Änderung des Packages ist nicht geplant.

Ein bisschen Hintergrund-Info:

Das bestehende Package de.espirit.firstspirit.webedit stammt noch aus Zeiten, in denen der ContentCreator noch fester Bestandteil der FirstSpirit-Kern-Implementierung war. Der ContentCreator ist (technisch) schon vor längerer Zeit in ein eigenes Modul gewandert, und hat damit einhergehend ein eigenes Package bekommen. Die Bestands-API-Klassen (in de.espirit.firstspirit.webedit) können wir aber natürlich nicht einfach in andere Packages verschieben.

Bezogen auf de.espirit.cxt.cc.plugin: Geplant ist weder ein Umzug des Packages, noch die Aufnahme der Klassen in das fs-isolated-runtime.jar, und auch nicht die Aufnahme des JavaDoc in das FirstSpirit-ApiDoc.

Die API-Dokumentation von solchen separaten Funktionalitäten wie dem ContentCreator, OCM und MSM, wird in Zukunft - wie man es von anderen Produkten/Modulen kennt - über die Doku-Landing-Page erreichbar sein (als separate Doku).

Die @Experimental-Klassifikation wird im Zuge der API-Veröffentlichung nochmal neu bewertet.

Viele Grüße

Michael