Erfahren Sie, wie Sie Angular-Komponenten Adobe Experience Manager (AEM)-Komponenten mit dem AEM SPA Editor JS SDK zuordnen. Die Komponentenzuordnung ermöglicht es Benutzenden, im AEM-SPA-Editor dynamische Aktualisierungen an SPA-Komponenten vorzunehmen, ähnlich wie beim herkömmlichen AEM-Authoring.
In diesem Kapitel werden die AEM JSON-Modell-API und die Möglichkeiten erläutert, wie der von einer AEM-Komponente angezeigte JSON-Inhalt automatisch als Props in eine Angular-Komponente eingefügt werden kann.
In diesem Kapitel wird untersucht, wie die Text
-SPA-Komponente der AEM-Text
-Komponente zugeordnet wird. Eine neue Image
-SPA-Komponente wird erstellt, die in der SPA verwendet und in AEM verfasst werden kann. Vorkonfigurierte Funktionen der Richtlinien zum Layout-Container und zum Vorlagen-Editor werden auch verwendet, um eine Ansicht zu erstellen, die etwas abwechslungsreicher erscheint.
Vergegenwärtigen Sie sich die erforderlichen Tools und Anweisungen zum Einrichten einer lokalen Entwicklungsumgebung.
Laden Sie den Ausgangspunkt für dieses Tutorial über Git herunter:
$ git clone git@github.com:adobe/aem-guides-wknd-spa.git
$ cd aem-guides-wknd-spa
$ git checkout Angular/map-components-start
Stellen Sie die Code-Basis mithilfe von Maven in einer lokalen AEM-Instanz bereit:
$ mvn clean install -PautoInstallSinglePackage
Fügen Sie bei Verwendung von AEM 6.x das Profil classic
hinzu:
$ mvn clean install -PautoInstallSinglePackage -Pclassic
Sie können den fertigen Code jederzeit auf GitHub ansehen oder den Code lokal auschecken, indem Sie zu der Verzweigung Angular/map-components-solution
wechseln.
Das grundlegende Konzept besteht darin, eine SPA-Komponente einer AEM-Komponente zuzuordnen. Server-seitig ausgeführte AEM-Komponenten exportieren Inhalte als Teil der JSON-Modell-API. Der JSON-Inhalt wird von der SPA verwendet, die Client-seitig im Browser ausgeführt wird. Es wird eine 1:1-Zuordnung zwischen SPA-Komponenten und einer AEM-Komponente erstellt.
Allgemeine Übersicht über die Zuordnung einer AEM-Komponente zu einer Angular-Komponente
Der AEM-Projektarchetyp bietet eine Text
-Komponente, die der AEM-Textkomponente zugeordnet ist. Dies ist ein Beispiel für eine Inhaltskomponente, da sie Inhalte von AEM rendert.
Sehen wir uns an, wie die Komponente funktioniert.
Bevor wir zum SPA-Code kommen, müssen Sie zunächst das von AEM bereitgestellte JSON-Modell verstehen. Navigieren Sie zur Kernkomponentenbibliothek und rufen Sie die Seite für die Textkomponente auf. Die Kernkomponentenbibliothek enthält Beispiele für alle AEM-Kernkomponenten.
Wählen Sie die Registerkarte JSON für eines der folgenden Beispiele aus:
Es sollten drei Eigenschaften angezeigt werden: text
, richText
und :type
.
:type
ist eine reservierte Eigenschaft, die den sling:resourceType
(oder Pfad) der AEM-Komponente auflistet. Der Wert von :type
wird verwendet, um die AEM-Komponente der SPA zuzuordnen.
text
und richText
sind zusätzliche Eigenschaften, die für die SPA-Komponente bereitgestellt werden.
Öffnen Sie ein neues Terminal und navigieren Sie zum Ordner ui.frontend
innerhalb des Projekts. Führen Sie npm install
und dann npm start
aus, um den webpack-Dev-Server zu starten:
$ cd ui.frontend
$ npm run start:mock
Das Modul ui.frontend
ist aktuell auf die Verwendung des JSON-Pseudomodells eingerichtet.
Es sollte ein neues Browser-Fenster zu sehen sein, in dem http://localhost:4200/content/wknd-spa-angular/us/en/home.html geöffnet ist.
Öffnen Sie in der IDE Ihrer Wahl das AEM-Projekt für die WKND-SPA. Erweitern Sie das Modul ui.frontend
und öffnen Sie die Datei text.component.ts unter ui.frontend/src/app/components/text/text.component.ts
:
Der erste zu prüfende Bereich ist class TextComponent
(ungefähr bei Zeile 35):
export class TextComponent {
@Input() richText: boolean;
@Input() text: string;
@Input() itemName: string;
@HostBinding('innerHtml') get content() {
return this.richText
? this.sanitizer.bypassSecurityTrustHtml(this.text)
: this.text;
}
@HostBinding('attr.data-rte-editelement') editAttribute = true;
constructor(private sanitizer: DomSanitizer) {}
}
Der Decorator @Input() wird verwendet, um Felder zu deklarieren, deren Werte über das zugeordnete und zuvor überprüfte JSON-Objekt festgelegt werden.
@HostBinding('innerHtml') get content()
ist eine Methode, die den erstellten Textinhalt aus dem Wert von this.text
bereitstellt. Wenn es sich bei dem Inhalt um Rich-Text handelt (bestimmt durch die Markierung this.richText
), wird die integrierte Sicherheitsfunktion von Angular umgangen. DomSanitizer von Angular wird verwendet, um unformatiertes HTML zu „bereinigen“ und Sicherheitslücken beim Cross-Site Scripting zu vermeiden. Die Methode ist über den Decorator @HostBinding an die Eigenschaft innerHtml
gebunden.
Überprüfen Sie als Nächstes TextEditConfig
(ungefähr bei Zeile 24):
const TextEditConfig = {
emptyLabel: 'Text',
isEmpty: cqModel =>
!cqModel || !cqModel.text || cqModel.text.trim().length < 1
};
Der obige Code bestimmt, wann der Platzhalter in der AEM Author-Umgebung gerendert werden soll. Wenn die Methode isEmpty
den Wert true zurückgibt, wird der Platzhalter gerendert.
Sehen Sie sich abschließend den MapTo
-Aufruf (ungefähr bei Zeile 53) an:
MapTo('wknd-spa-angular/components/text')(TextComponent, TextEditConfig );
MapTo wird vom AEM SPA Editor JS SDK (@adobe/cq-angular-editable-components
) bereitgestellt. Der Pfad wknd-spa-angular/components/text
steht für das sling:resourceType
-Element der AEM-Komponente. Dieser Pfad wird mit :type
abgeglichen, das von dem zuvor festgestellten JSON-Modell bereitgestellt wird. MapTo analysiert die JSON-Modellantwort und übergibt die richtigen Werte an die @Input()
-Variablen der SPA-Komponente.
Sie finden die AEM-Text
-Komponentendefinition unter ui.apps/src/main/content/jcr_root/apps/wknd-spa-angular/components/text
.
Experimentieren Sie ein wenig, indem Sie die Datei en.model.json Datei unter ui.frontend/src/mocks/json/en.model.json
ändern.
Aktualisieren Sie ungefähr bei Zeile 62 den ersten Text
-Wert, um ein H1
- und u
-Tag zu verwenden:
"text": {
"text": "<h1><u>Hello World!</u></h1>",
"richText": true,
":type": "wknd-spa-angular/components/text"
}
Kehren Sie zum Browser zurück, um das vom webpack-Dev-Server bereitgestellte Ergebnis zu sehen:
Schalten Sie bei der Eigenschaft richText
zwischen true/false um, um die Render-Logik in Aktion zu sehen.
Überprüfen Sie text.component.html unter ui.frontend/src/app/components/text/text.component.html
.
Diese Datei ist leer, da der gesamte Inhalt der Komponente durch die Eigenschaft innerHTML
festgelegt wird.
Überprüfen Sie app.module.ts unter ui.frontend/src/app/app.module.ts
.
@NgModule({
imports: [
BrowserModule,
SpaAngularEditableComponentsModule,
AppRoutingModule
],
providers: [ModelManagerService, { provide: APP_BASE_HREF, useValue: '/' }],
declarations: [AppComponent, TextComponent, PageComponent, HeaderComponent],
entryComponents: [TextComponent, PageComponent],
bootstrap: [AppComponent]
})
export class AppModule {}
TextComponent ist nicht explizit enthalten, sondern dynamisch über AEMResponsiveGridComponent, bereitgestellt vom AEM SPA Editor JS SDK. Daher muss dies im entryComponents-Array von app.module.ts aufgelistet sein.
Erstellen Sie als Nächstes eine Image
-Angular-Komponente, die der Bildkomponente von AEM zugeordnet ist. Die Image
-Komponente ist ein weiteres Beispiel für eine Inhaltskomponente.
Bevor wir zum SPA-Code kommen, überprüfen Sie das von AEM bereitgestellte JSON-Modell.
Navigieren Sie zu den Bildbeispielen in der Kernkomponentenbibliothek.
Die Eigenschaften src
, alt
und title
werden zum Auffüllen der Image
-SPA-Komponente verwendet.
Es werden andere Bildeigenschaften bereitgestellt (lazyEnabled
, widths
), die es Entwickelnden ermöglichen, eine adaptive und Lazy-Loading-basierte Komponente zu erstellen. Die in diesem Tutorial erstellte Komponente ist einfach und verwendet nicht diese erweiterten Eigenschaften.
Kehren Sie zu Ihrer IDE zurück und öffnen Sie en.model.json
unter ui.frontend/src/mocks/json/en.model.json
. Da dies eine neue Komponente für unser Projekt ist, müssen wir das Bild-JSON mit Pseudoinhalten versehen.
Fügen Sie ungefähr bei Zeile 70 einen JSON-Eintrag für das image
-Modell hinzu (das nachfolgende Komma ,
nach dem zweiten text_386303036
-Eintrag nicht vergessen) und aktualisieren Sie das Array :itemsOrder
.
...
":items": {
...
"text_386303036": {
"text": "<p>A new text component.</p>\r\n",
"richText": true,
":type": "wknd-spa-angular/components/text"
},
"image": {
"alt": "Rock Climber in New Zealand",
"title": "Rock Climber in New Zealand",
"src": "/mocks/images/adobestock-140634652.jpeg",
":type": "wknd-spa-angular/components/image"
}
},
":itemsOrder": [
"text",
"text_386303036",
"image"
],
Das Projekt enthält ein Beispielbild unter /mock-content/adobestock-140634652.jpeg
, das mit dem webpack-Dev-Server verwendet wird.
Die vollständige en.model.json-Datei können Sie hier einsehen.
Fügen Sie ein lizenzfreies Foto hinzu, das von der Komponente angezeigt werden soll.
Erstellen Sie einen neuen Ordner mit dem Namen images unterhalb von ui.frontend/src/mocks
. Laden Sie adobestock-140634652.jpeg herunter und legen Sie das Bild im neu erstellten Ordner images ab. Sie können auch ein eigenes Bild verwenden.
Halten Sie den webpack-Dev-Server an, sofern gestartet.
Erstellen Sie eine neue Bildkomponente durch Ausführen des Angular-Befehlszeilenbefehls ng generate component
im Ordner ui.frontend
:
$ ng generate component components/image
Öffnen Sie in der IDE image.component.ts unter ui.frontend/src/app/components/image/image.component.ts
und führen Sie folgende Aktualisierung aus:
import {Component, Input, OnInit} from '@angular/core';
import {MapTo} from '@adobe/cq-angular-editable-components';
const ImageEditConfig = {
emptyLabel: 'Image',
isEmpty: cqModel =>
!cqModel || !cqModel.src || cqModel.src.trim().length < 1
};
@Component({
selector: 'app-image',
templateUrl: './image.component.html',
styleUrls: ['./image.component.scss']
})
export class ImageComponent implements OnInit {
@Input() src: string;
@Input() alt: string;
@Input() title: string;
constructor() { }
get hasImage() {
return this.src && this.src.trim().length > 0;
}
ngOnInit() { }
}
MapTo('wknd-spa-angular/components/image')(ImageComponent, ImageEditConfig);
ImageEditConfig
ist die Konfiguration, die bestimmt, ob der Autorenplatzhalter in AEM gerendert werden soll – und zwar abhängig davon, ob die Eigenschaft src
angegeben ist.
@Input()
von src
, alt
und title
sind die Eigenschaften, die von der JSON-API zugeordnet sind.
hasImage()
ist eine Methode, die bestimmt, ob das Bild gerendert werden soll.
MapTo
ordnet die SPA-Komponente der AEM-Komponente unter ui.apps/src/main/content/jcr_root/apps/wknd-spa-angular/components/image
zu.
Öffnen Sie image.component.html und führen Sie folgende Aktualisierung aus:
<ng-container *ngIf="hasImage">
<img class="image" [src]="src" [alt]="alt" [title]="title"/>
</ng-container>
Dadurch wird das <img>
-Element gerendert, wenn hasImage
den Wert true zurückgibt.
Öffnen Sie image.component.scss und führen Sie folgende Aktualisierung aus:
:host-context {
display: block;
}
.image {
margin: 1rem 0;
width: 100%;
border: 0;
}
Die :host-context
-Regel ist wichtig, damit der Platzhalter des AEM-SPA-Editors ordnungsgemäß funktioniert. Alle SPA-Komponenten, die im AEM-Seiten-Editor erstellt werden sollen, benötigen mindestens diese Regel.
Öffnen Sie app.module.ts
und fügen Sie ImageComponent
dem Array entryComponents
hinzu:
entryComponents: [TextComponent, PageComponent, ImageComponent],
ImageComponent
wird wie TextComponent
dynamisch geladen und muss im Array entryComponents
enthalten sein.
Starten Sie den Webpack-Dev-Server, um ImageComponent
zu rendern.
$ npm run start:mock
Der SPA hinzugefügtes Bild
Bonusaufgabe: Implementieren Sie eine neue Methode zum Anzeigen des Werts von title
als Bildbeschriftung.
Die ImageComponent
-Komponente ist nur im webpack-Dev-Server sichtbar. Stellen Sie als Nächstes die aktualisierte SPA in AEM bereit und aktualisieren Sie die Vorlagenrichtlinien.
Halten Sie den Webpack-Dev-Server an und stellen Sie im Stammprojekt die Änderungen für AEM mithilfe von Maven bereit:
$ cd aem-guides-wknd-spa
$ mvn clean install -PautoInstallSinglePackage
Navigieren Sie auf dem AEM-Startbildschirm zu Tools > Vorlagen > WKND SPA Angular.
Wählen Sie die SPA-Seite aus und bearbeiten Sie diese:
Wählen Sie den Layout-Container aus und klicken Sie auf das Richtliniensymbol, um die Richtlinie zu bearbeiten:
Aktivieren Sie unter Zugelassene Komponenten > WKND SPA Angular – Inhalt das Kontrollkästchen für die Bildkomponente:
Wählen Sie unter Standardkomponenten > Zuordnung hinzufügen die Komponente Bild – WKND SPA Angular – Inhalt aus:
Geben Sie einen MIME-Typ von image/*
ein.
Klicken Sie auf Fertig, um die Richtlinienaktualisierungen zu speichern.
Klicken Sie unter Layout-Container auf das Richtliniensymbol für die Textkomponente:
Erstellen Sie eine neue Richtlinie mit dem Namen WKND SPA Text. Unter Plugins > Formatierung > markieren Sie alle Kästchen, um zusätzliche Formatierungsoptionen zu aktivieren:
Kreuzen Sie unter Plugins > Absatzformate > das Kontrollkästchen Absatzformate aktivieren an:
Klicken Sie auf Fertig, um die Richtlinienaktualisierung zu speichern.
Navigieren Sie zur Homepage http://localhost:4502/editor.html/content/wknd-spa-angular/us/en/home.html.
Sie sollten auch dazu in der Lage sein, die Text
-Komponente zu bearbeiten und zusätzliche Absatzformate im Vollbildmodus hinzuzufügen.
Sie sollten auch dazu in der Lage sein, ein Bild per Drag-and-Drop aus dem Asset-Finder zu ziehen:
Fügen Sie Ihre eigenen Bilder über AEM Assets hinzu oder installieren Sie die fertige Code-Basis für die Standard-WKND-Referenz-Site. Die WKND-Referenz-Site enthält viele Bilder, die auf der WKND-SPA wiederverwendet werden können. Das Paket kann mit dem Package Manager von AEM installiert werden.
Unterstützung für den Layout-Container wird automatisch vom AEM SPA Editor SDK bereitgestellt. Der Layout-Container ist, wie der Name schon sagt, eine Container-Komponente. Container-Komponenten sind Komponenten, die JSON-Strukturen akzeptieren, die andere Komponenten darstellen und dynamisch instanziieren.
Überprüfen wir den Layout-Container weiter.
Öffnen Sie in der IDE responsive-grid.component.ts unter ui.frontend/src/app/components/responsive-grid
:
import { AEMResponsiveGridComponent,MapTo } from '@adobe/cq-angular-editable-components';
MapTo('wcm/foundation/components/responsivegrid')(AEMResponsiveGridComponent);
Die AEMResponsiveGridComponent
wird als Teil des AEM SPA Editor SDK implementiert und über import-components
in das Projekt eingefügt.
Navigieren Sie in einem Browser zu http://localhost:4502/content/wknd-spa-angular/us/en.model.json
Die Komponente Layout-Container verfügt über einen sling:resourceType
von wcm/foundation/components/responsivegrid
und wird vom SPA-Editor mithilfe der :type
-Eigenschaft erkannt, genau wie die Komponenten Text
und Image
.
Die gleichen Funktionen für die Neuskalierung einer Komponente über den Layout-Modus sind im SPA-Editor verfügbar.
Kehren Sie zu http://localhost:4502/editor.html/content/wknd-spa-angular/us/en/home.html zurück. Fügen Sie zusätzliche Bildkomponenten hinzu und versuchen Sie, sie mithilfe der Option Layout neu zu skalieren:
Öffnen Sie das JSON-Modell http://localhost:4502/content/wknd-spa-angular/us/en.model.json erneut und betrachten Sie die columnClassNames
als Teil von JSON:
Der Klassenname aem-GridColumn--default--4
gibt an, dass die Komponente basierend auf einem 12-Spalten-Raster 4 Spalten breit sein sollte. Weitere Informationen zum Responsiven Raster finden Sie hier.
Kehren Sie zur IDE zurück. Im ui.apps
-Modul gibt es eine Client-seitige Bibliothek, die unter ui.apps/src/main/content/jcr_root/apps/wknd-spa-angular/clientlibs/clientlib-grid
definiert ist. Öffnen Sie die Datei less/grid.less
.
Diese Datei bestimmt die Haltepunkte (default
, tablet
und phone
), die der Layout-Container verwendet. Diese Datei soll gemäß den Projektspezifikationen angepasst werden. Derzeit sind die Haltepunkte auf 1200px
und 650px
festgelegt.
Sie sollten in der Lage sein, die responsiven Funktionen und die aktualisierten Rich-Text-Richtlinien der Text
-Komponente zu verwenden, um eine Ansicht wie die folgende zu erstellen:
Herzlichen Glückwunsch! Sie haben gelernt, wie Sie SPA-Komponenten AEM-Komponenten zuordnen, und Sie haben eine neue Image
-Komponente implementiert. Außerdem hatten Sie eine Gelegenheit, die responsiven Funktionen des Layout-Containers zu erkunden.
Sie können den fertigen Code jederzeit auf GitHub ansehen oder den Code lokal auschecken, indem Sie zur Verzweigung Angular/map-components-solution
wechseln.
Navigation und Routing – Erfahren Sie, wie mehrere Ansichten in der SPA unterstützt werden können, indem Sie sie mit dem SPA Editor SDK AEM-Seiten zuordnen. Die dynamische Navigation wird mithilfe des Angular-Routers implementiert und einer vorhandenen Header-Komponente hinzugefügt.
In vielen Fällen, insbesondere zu Beginn eines AEM-Projekts, ist es nützlich, Konfigurationen wie Vorlagen und zugehörige Inhaltsrichtlinien beizubehalten, um die Quelle zu verwalten. Dadurch wird sichergestellt, dass alle Entwicklerinnen und Entwickler mit demselben Inhaltssatz und denselben Konfigurationen arbeiten, und zusätzliche Konsistenz zwischen Umgebungen gewährleistet. Sobald ein Projekt einen gewissen Reifegrad erreicht hat, kann die Verwaltung von Vorlagen einer speziellen Gruppe von Power-Benutzenden übertragen werden.
Die nächsten Schritte werden mit der Visual Studio Code-IDE und VSCode AEM Sync durchgeführt, jedoch kann jedes beliebige Tool und jede IDE verwendet werden, für die Sie konfiguriert haben, dass sie Inhalt von einer lokalen Instanz von AEM abrufen oder importieren.
Stellen Sie in der Visual Studio Code-IDE sicher, dass Sie VSCode AEM Sync über die Marketplace-Erweiterung installiert haben:
Erweitern Sie das ui.content-Modul im Project Explorer und navigieren Sie zu /conf/wknd-spa-angular/settings/wcm/templates
.
Klicken Sie mit der rechten Maustaste auf den Ordner templates
und wählen Sie Importieren aus AEM Server:
Wiederholen Sie die Schritte zum Importieren von Inhalten, aber wählen Sie den Ordner policies unter /conf/wknd-spa-angular/settings/wcm/policies
aus.
Überprüfen Sie die Datei filter.xml
unter ui.content/src/main/content/META-INF/vault/filter.xml
.
<!--ui.content filter.xml-->
<?xml version="1.0" encoding="UTF-8"?>
<workspaceFilter version="1.0">
<filter root="/conf/wknd-spa-angular" mode="merge"/>
<filter root="/content/wknd-spa-angular" mode="merge"/>
<filter root="/content/dam/wknd-spa-angular" mode="merge"/>
<filter root="/content/experience-fragments/wknd-spa-angular" mode="merge"/>
</workspaceFilter>
Die Datei filter.xml
ist für die Identifizierung der Pfade von Knoten verantwortlich, die mit dem Paket installiert werden. mode="merge"
bei jedem Filter bedeutet, dass vorhandener Inhalt nicht geändert wird, sondern nur neue Inhalte hinzugefügt werden. Da Inhaltsautorinnen und Inhaltsautoren diese Pfade möglicherweise aktualisieren, ist es wichtig, dass Inhalte bei einer Code-Bereitstellung nicht überschrieben werden. Weitere Informationen zum Arbeiten mit Filterelementen finden Sie in der FileVault-Dokumentation.
Vergleichen Sie ui.content/src/main/content/META-INF/vault/filter.xml
und ui.apps/src/main/content/META-INF/vault/filter.xml
, um sich mit den verschiedenen, von den einzelnen Modulen verwalteten Knoten vertraut zu machen.