Die Power des AEM Extension Manager: Ein umfassender Guide
In der sich ständig weiterentwickelnden Landschaft der Verwaltung digitaler Inhalte erweist sich Adobe Experience Manager (AEM) als robuste Lösung für Unternehmen, die personalisierte digitale Erlebnisse bereitstellen möchten. Mit der Einführung des AEM Extension Manager hat Adobe neue Horizonte für Entwickler und Content Manager eröffnet, die damit die Funktionen von AEM erweitern und anpassen können, ohne tief in komplexe Codings eintauchen zu müssen.
In diesem umfassenden Leitfaden lernen Sie den AEM Extension Manager kennen, erfahren mehr über seine Funktionen und erhalten praktische Beispiele für die Erstellung benutzerdefinierter UI-Erweiterungen, einschließlich einer Integration mit DALL-E von OpenAI zur Bilderzeugung direkt in AEM.
Inhalt
- Was ist der AEM Extension Manager?
- Warum UI Extensions?
- Extension Points in AEM
- Die erste UI Extension erstellen
- Deep Dive: Integration von OpenAIs DALL-E 3 in AEM
- Testing and Deploying Extensions
- Best Practices
- Zusammenfassung
Was ist der AEM Extension Manager?
Der AEM Extension Manager ist eine Funktion in Adobe Experience Manager, die es Entwicklern ermöglicht, UI-Erweiterungen zu erstellen, zu verwalten und bereitzustellen, ohne die zentrale AEM-Codebase zu ändern. Diese Erweiterungen werden mit dem Adobe App Builder erstellt und können nahtlos in die AEM-Benutzeroberfläche integriert werden, um benutzerdefinierte Funktionen bereitzustellen, die auf spezifische Geschäftsanforderungen zugeschnitten sind.
Key Features:
- No-Code-Konfiguration: Erweiterungen können ohne Code-Änderungen pro Umgebung konfiguriert werden.
- Umgebungssteuerung: Aktivieren oder Deaktivieren von Erweiterungen auf Umgebungsbasis.
- Schnelles Deployment: Erweiterungen können unabhängig vom AEM-Release-Zyklus bereitgestellt werden.
- Erweiterungen von Erstanbietern und Drittanbietern: Nutzen Sie die Erweiterungen von Adobe oder erstellen Sie Ihre eigenen.
Warum UI Extensions?
UI Extensions bieten eine Möglichkeit, die AEM-Benutzererfahrung ohne den Aufwand herkömmlicher Entwicklungszyklen zu verbessern. Hier sind einige überzeugende Gründe, sie zu verwenden:
- Flexibilität: Entwickeln Sie benutzerdefinierte Benutzeroberflächen und Funktionalitäten, die auf spezifische Autorenanforderungen zugeschnitten sind.
- Wiederverwendbarkeit: Erweiterungen sind unabhängig von der AEM-Codebasis, sodass sie in verschiedenen Projekten oder Kunden wiederverwendet werden können.
- Skalierbarkeit: Da sie auf der serverlosen Plattform von Adobe basieren, können Erweiterungen ohne zusätzliche Infrastruktur skaliert werden.
- Leichte Integration: Erweiterungen können mit APIs und Diensten von Drittanbietern interagieren und so die Möglichkeiten von AEM erweitern.
- Saubere Trennung: Durch die Trennung von Anpassungen wird das Risiko einer Beeinträchtigung der Kernfunktionalität reduziert.
- Vereinfachte Verwaltung: Aktivieren, deaktivieren oder konfigurieren Sie Erweiterungen, ohne AEM neu bereitstellen zu müssen.
Screenshots eines Demo-Projects
Extension Points in AEM
Extensions können an verschiedenen Stellen in AEM integriert werden:
- Content Fragment Admin Console: Passen Sie die Verwaltungsoberfläche für Inhaltsfragmente an.
- Content Fragment Editor: Fügen Sie Funktionalitäten direkt in der Bearbeitungsoberfläche für Inhaltsfragmente hinzu.
- Universal Editor: Erweitern Sie die Fähigkeiten des Universal Editors, der für Headless CMS Anwendungsfälle entscheidend ist.
- Commerce Admin: (Geplant) Erweiterung der Funktionalitäten innerhalb der Commerce-Administrationsoberfläche.
Diese Erweiterungspunkte bieten die Flexibilität, verschiedene Teile der AEM-Benutzeroberfläche zu verbessern, je nach den Anforderungen Ihres Unternehmens.
Die erste UI Extension erstellen
Im Folgenden zeigen wir eine Schritt-für-Schritt-Amleitung. Alternativ gibt es alles direkt über github project für den gesamten Code.
Voraussetzungen:
- Zugang zu Adobe Experience Manager (Cloud-Version)
- Vertrautheit mit React und Node.js
- Einrichtung von Adobe App Builder in Ihrer Umgebung
Schritte:
1. Entwicklungsumgebung einrichten:
- Adobe I/O CLI installieren:
npm install -g @adobe/aio-cli
- Log in CLI: aio login
2. Neues Projekt anlegen:
- Vdobe App Builder-Vorlagen als Gerüst für ein neues Projekt verwenden.
- Zum Beispiel, um eine Content Fragment Admin UI-Erweiterung zu erstellen:
bash aio app init my-aem-extension --template https://github.com/adobe/aem-cf-editor-extension-template
3. Die Projekt Struktur verstehen:
- Aktionen: Enthält Backend-Code (Node.js) für serverlose Funktionen.
- Web Src: Frontend-Code (React) für die UI-Erweiterung.
4. Extension entwickeln:
Frontend:
- Verwenden Sie React Spectrum-Komponenten, um Ihre Benutzeroberfläche zu erstellen.
- Definieren Sie Ihren Erweiterungspunkt und Ihre UI-Komponenten.
Backend:
- Schreiben Sie Node.js-Aktionen, um API-Aufrufe oder Datenverarbeitung zu verarbeiten.
- Verwenden Sie die SDKs von Adobe für die Authentifizierung und Interaktion mit AEM-APIs.
5. Lokales Testen:
- Anwendung lokal mit aio app run ausführen.
- Vorschau aufzeigen durch Abfrageparameter an die AEM-URL: https://experience.adobe.com/?devMode=true&localDevUrl=http://localhost:9080
6. Deploy:
- Staging-Umgebung bereit stellen: aio app deploy.
- In den production workspace wechslen und deployen.
Deep Dive: Integration von OpenAIs DALL-E 3 in AEM
Lassen Sie uns ein praktisches Beispiel für die Erstellung einer Erweiterung durchgehen, die Bilder mit OpenAIs DALL-E generiert und sie in AEM-Inhaltsfragmente integriert.
Zielsetzung:
- Fügen Sie eine Schaltfläche in der Verwaltungskonsole für Inhaltsfragmente hinzu.
- Öffnen Sie beim Anklicken ein Modal, um eine Bildbeschreibung einzugeben.
- Generieren Sie ein Bild mit DALL-E auf der Grundlage der Beschreibung.
- Laden Sie das generierte Bild in AEM Assets hoch.
- Aktualisieren Sie das ausgewählte Inhaltsfragment, um das neue Bild aufzunehmen.
Implementierung:
1. Hinzufügen der Schaltfläche zur Verwaltungskonsole
In der Datei extension-registration.js:
import React from 'react';
import { register } from '@adobe/uix-guest';
import { Image } from '@adobe/react-spectrum-workflow';
register({
extensionPoint: 'ContentFragment.ActionBar',
id: 'generate-image-button',
methods: {
// Configure your Action Bar button here
actionBar: {
getButton() {
return {
'id': 'generate-image', // Unique ID for the button
'label': 'Generate Image', // Button label
'icon': 'PublishCheck' // Button icon
}
},
// Click handler for the extension button
onClick(selections) {
// Collect the selected content fragment paths
const selectionIds = selections.map(selection => selection.id);
// Create a URL that maps to the
const modalURL = "/index.html#" + generatePath(
"/content-fragment/:selection/generate-image-modal",
{
// Set the :selection React route parameter to an encoded, delimited list of paths of the selected content fragments
selection: encodeURIComponent(selectionIds.join('|')),
}
);
// Open the route in the extension modal using the constructed URL
guestConnection.host.modal.showUrl({
title: "Generate Image",
url: modalURL
})
}
},
}
});
2. Erstellen der Modalkomponente
In GenerateImageModal.js:
import React, { useState } from 'react';
import { Dialog, TextField, Button } from '@adobe/react-spectrum';
export const ImageModal = ({ selection, onClose }) => {
const [description, setDescription] = useState('');
async function onSubmitHandler() {
console.log('Started Image Generation orchestration');
// Mark the extension as invoking the action, so the loading spinner is displayed
setActionInvokeInProgress(true);
// Set the HTTP headers to access the Adobe I/O runtime action
const headers = {
Authorization: `Bearer ${guestConnection.sharedContext.get('auth').imsToken}`,
'x-gw-ims-org-id': guestConnection.sharedContext.get('auth').imsOrg,
};
// Set the parameters to pass to the Adobe I/O Runtime action
const params = {
aemHost: `https://${guestConnection.sharedContext.get('aemHost')}`,
fragmentId: fragmentIds[0],
imageDescription,
};
const generateImageAction = 'generate-image';
try {
const generateImageActionResponse = await actionWebInvoke(allActions[generateImageAction], headers, params);
// Set the response from the Adobe I/O Runtime action
setActionResponse(generateImageActionResponse);
console.log(`Response from ${generateImageAction}:`, actionResponse);
} catch (e) {
// Log and store any errors
console.error(e);
}
// Set the action as no longer being invoked, so the loading spinner is hidden
setActionInvokeInProgress(false);
}
return (<Provider theme={defaultTheme} colorScheme="light">
<Content width="100%">
<Flex width="100%">
<Form width="100%">
<TextField
label="Image Description"
description="The image description in natural language, for e.g. Alaskan adventure in wilderness, animals, and flowers."
isRequired
validationState={validationState?.propertyName}
onChange={setImageDescription}
contextualHelp=(<ContextualHelp>
<Heading>Need help?</Heading>
<Content>
<Text>
The
<strong>description of an image</strong>
you are looking for in the natural language, for e.g. "Family vacation on the beach with blue ocean, dolphins, boats and drink"
</Text>
</Content>
</ContextualHelp>)
/>
<ButtonGroup align="end">
<Button variant="accent" onPress={onSubmitHandler}>Create Image</Button>
<Button variant="accent" onPress={() => guestConnection.host.modal.close()}>Close</Button>
</ButtonGroup>
</Form>
</Flex>
</Content>
</Provider>
);
}
};
3. Backend Actions
In actions/generateImage/index.js:
const { OpenAIApi } = require('openai');
const { uploadAsset } = require('@adobe/aem-upload');
async function main(params) {
const { description, contentFragmentPath } = params;
// Generate image using DALL·E
const openai = new OpenAI({
apiKey: params.OPENAI_API_KEY,
});
const response = await openai.images.generate({
model: "dall-e-3", //dall-e-3
prompt: params.imageDescription,
n: 1,
size: '1024x1024',
quality: "standard",
});
generatedImageURL = response.data[0].url;
// Download the image
const imageBuffer = await downloadImage(imageUrl);
// Upload image to AEM
const binaryUpload = new DirectBinaryUpload();
await binaryUpload.uploadFiles(options)
.then((result) => {
logger.info(`got response from image upload`);
// Handle Error
result.getErrors().forEach((error) => {
if (error.getCode() === codes.ALREADY_EXISTS) {
logger.error('The generated image already exists');
}
});
// Handle Upload result and check for errors
result.getFileUploadResults().forEach((fileResult) => {
// log file upload result
logger.info(`File upload result ${JSON.stringify(fileResult)}`);
fileResult.getErrors().forEach((fileErr) => {
if (fileErr.getCode() === codes.ALREADY_EXISTS) {
const fileName = fileResult.getFileName();
logger.error(`The generated image already exists ${fileName}`);
}
});
});
})
.catch((err) => {
logger.info(`Failed to uploaded generated image to AEM${err}`);
});
logger.info('Successfully uploaded generated image to AEM');
// Update content fragment
const body = {
properties: {
elements: {
[imgPropName]: {
value: relativeImgPath,
},
},
},
};
const res = await fetch(`${params.aemHost}${fragmenPath.replace('/content/dam/', '/api/assets/')}.json`, {
method: 'put',
body: JSON.stringify(body),
headers: {
Authorization: `Bearer ${accessToken}`,
'Content-Type': 'application/json',
},
});
if (res.ok) {
logger.info(`Successfully updated ${fragmenPath}`);
return fragmenPath;
}
Testing und Deployment
Lokales Testen
- Verwenden Sie die aio app run, um die Erweiterung lokal zu testen.
- Die Erweiterung wird unter http://localhost:9080 verfügbar sein.
Vorschau in AEM
Fügen Sie die Parameter devMode und localDevUrl zu Ihrer AEM-URL hinzu:
https://experience.adobe.com/?devMode=true&localDevUrl=http://localhost:9080
Bereitstellung
- Bereitstellen in Staging: aio app deploy
- Wechseln Sie zum Produktionsarbeitsbereich: aio cloudmanager:set-workspace Production
Bereitstellung in der Produktion: aio app deploy
- Aktivieren der Erweiterung in AEM
- Navigieren Sie zum Extension Manager in AEM (experience.adobe.com > Extension Manager).
- Suchen Sie Ihre Erweiterung unter der entsprechenden Umgebung.
- Aktivieren Sie die Erweiterung, indem Sie ihren Status umschalten.
Example: Integrating OpenAI's DALL·E für die Image Generation
Use Case: Autoren möchten Bilder auf der Grundlage von Textaufforderungen direkt in der Verwaltungskonsole für Inhaltsfragmente generieren.
Lösungsansatz:
- Hinzufügen einer benutzerdefinierten Schaltfläche: Verwenden Sie den Erweiterungsmanager, um eine Schaltfläche „Bild generieren“ zur Aktionsleiste des Inhaltsfragments hinzuzufügen.
- Erstellen Sie einen modalen Dialog: Wenn die Schaltfläche angeklickt wird, zeigen Sie ein Modal an, in dem der Autor eine Textaufforderung eingeben kann.
- Rufen Sie OpenAIs API auf: Nach der Eingabe ruft die Erweiterung eine serverlose Aktion auf, die die Eingabeaufforderung an die DALL-E-API von OpenAI sendet.
- Hochladen des generierten Bildes: Das zurückgegebene Bild wird in AEM Assets hochgeladen.
- Aktualisieren Sie das Inhaltsfragment: Das Inhaltsfragment wird aktualisiert, um auf das neue Bild zu verweisen.
Technische Implementierung:
- Front-End: Entwickelt mit React, unter Verwendung von Adobes React Spectrum Komponenten für Konsistenz.
- Back-End: Node.js-Aktionen, die auf Adobe I/O Runtime laufen, verarbeiten API-Aufrufe und Interaktionen mit AEM.
Benefits:
- Verbessertes Autorenerlebnis: Autoren können Bilder erstellen und verwenden, ohne AEM zu verlassen.
- Nahtlose Integration: Die AEM-Codebasis muss nicht geändert werden.
- Wiederverwendbarkeit: Die Erweiterung kann in verschiedenen Projekten verwendet oder mit der Community geteilt werden.
Vorteile der Verwendung von Extensions:
- Flexibel: Passen Sie die AEM-Benutzeroberfläche an spezifische Geschäftsanforderungen an.
- Keine Änderung der Codebasis: Halten Sie Anpassungen getrennt und verringern Sie so das Risiko, die Kernfunktionalität zu beeinträchtigen.
- Wiederverwendbarkeit: Nutzen Sie Erweiterungen in mehreren Projekten oder mit der gesamten Adobe-Community.
- Vereinfachte Verwaltung: Aktivieren, deaktivieren oder konfigurieren Sie Erweiterungen, ohne AEM erneut bereitstellen zu müssen.
- Sicherheit: Erweiterungen werden im authentifizierten Kontext des Anwenders ausgeführt, um sichere Interaktionen zu gewährleisten.
Best Practices
- Authentifizierung: Nutzen Sie die Authentifizierungsmechanismen von Adobe, um sicher mit AEM-APIs zu interagieren.
- Umgebungsvariablen: Speichern Sie sensible Daten wie API-Schlüssel sicher in der Konfiguration von App Builder.
- Leistung: Da Erweiterungen clientseitig ausgeführt werden, sollten Sie sicherstellen, dass Ihr Code optimiert ist, um Verzögerungen auf der Benutzeroberfläche zu vermeiden.
- Fehlerbehandlung: Implementieren Sie eine robuste Fehlerbehandlung, um den Benutzern ein sinnvolles Feedback zu geben.
- Wiederverwendbarkeit: Entwerfen Sie Erweiterungen so generisch wie möglich, damit sie projektübergreifend wiederverwendet werden können.
- Testen: Testen Sie Erweiterungen immer in einer Entwicklungs- oder Staging-Umgebung, bevor Sie sie in der Produktion einsetzen.
- Dokumentation: Pflegen Sie eine klare Dokumentation für Ihre Erweiterungen, um die zukünftige Wartung und den Austausch zu erleichtern.
- Beitrag zur Gemeinschaft: Stellen Sie Ihre Erweiterungen über Adobe Exchange zur Verfügung, um einen Beitrag zur Community zu leisten.
Zusammenfassung
Der AEM Extension Manager ermöglicht es Entwicklern, das AEM-Erlebnis ohne die Einschränkungen herkömmlicher Entwicklungszyklen zu verbessern und anzupassen. Durch die Nutzung von UI-Erweiterungen und Adobes App Builder können Sie maßgeschneiderte Funktionen bereitstellen, die spezifische Geschäftsanforderungen erfüllen, die Authoring-Erlebnisse verbessern und leistungsstarke Drittanbieterdienste wie DALL-E von OpenAI integrieren.
Da sich die digitale Landschaft ständig weiterentwickelt, spielen Tools wie der AEM Extension Manager eine entscheidende Rolle, damit Organisationen agil und innovativ bleiben können. Ganz gleich, ob Sie als Entwickler Ihren Workflow optimieren möchten oder als Autor von Inhalten auf der Suche nach erweiterten Funktionen sind, der Extension Manager bietet Ihnen einen Weg nach vorne im Adobe Experience Manager-Ökosystem.
Haben Sie Fragen oder benötigen Sie Unterstützung bei Ihren AEM-Projekten? Wenden Sie sich bitte direkt an uns!
References: