Mappa SPA-komponenter till AEM-komponenter
- Gäller:
- Experience Manager as a Cloud Service
Skapat för:
- Nybörjare
- Utvecklare
- Den universella redigeraren för visuell redigering av headless-innehåll.
- Innehållsfragmentredigeraren för formulärbaserad redigering av rubrikfritt innehåll.
Lär dig mappa Angular-komponenter till Adobe Experience Manager-komponenter (AEM) med AEM SPA Editor JS SDK. Med komponentmappning kan man göra dynamiska uppdateringar av SPA-komponenter i AEM SPA Editor, på samma sätt som vid vanlig redigering i AEM.
Det här kapitlet innehåller en djupdykning i AEM JSON-modell-API:t och hur JSON-innehåll som exponeras av en AEM-komponent automatiskt kan injiceras i en Angular-komponent som props.
Syfte
- Lär dig mappa AEM-komponenter till SPA-komponenter.
- Förstå skillnaden mellan Container-komponenter och Content-komponenter.
- Skapa en ny Angular-komponent som mappar till en befintlig AEM-komponent.
Vad du ska bygga
I det här kapitlet granskas hur den angivna Text
SPA-komponenten mappas till AEM Text
-komponenten. En ny SPA-komponent för Image
skapas som kan användas i SPA och skapas i AEM. Funktionerna i Layoutbehållaren och Mallredigeraren kommer också att användas för att skapa en vy som är lite mer varierad.
Förutsättningar
Granska de verktyg och instruktioner som krävs för att konfigurera en lokal utvecklingsmiljö.
Hämta koden
-
Hämta startpunkten för den här självstudiekursen via Git:
$ git clone git@github.com:adobe/aem-guides-wknd-spa.git $ cd aem-guides-wknd-spa $ git checkout Angular/map-components-start
-
Distribuera kodbasen till en lokal AEM-instans med Maven:
$ mvn clean install -PautoInstallSinglePackage
Om du använder AEM 6.x lägger du till profilen
classic
:$ mvn clean install -PautoInstallSinglePackage -Pclassic
Du kan alltid visa den färdiga koden på GitHub eller checka ut koden lokalt genom att växla till grenen Angular/map-components-solution
.
Mappningsmetod
Det grundläggande konceptet är att mappa en SPA-komponent till en AEM-komponent. AEM-komponenter kör serversidan och exporterar innehåll som en del av JSON-modellens API. JSON-innehållet används av SPA, som kör klientsidan i webbläsaren. En 1:1-mappning mellan SPA-komponenter och en AEM-komponent skapas.
Översikt på hög nivå över mappning av en AEM-komponent till en Angular-komponent
Inspektera textkomponenten
AEM Project Archetype innehåller en Text
-komponent som är mappad till AEM Text-komponent. Det här är ett exempel på en content -komponent, eftersom den återger innehåll från AEM.
Låt oss se hur komponenten fungerar.
Inspektera JSON-modellen
-
Innan du hoppar in i SPA-koden är det viktigt att förstå den JSON-modell som AEM tillhandahåller. Navigera till Core Component Library och visa sidan för Text-komponenten. Core Component Library innehåller exempel på alla AEM Core-komponenter.
-
Välj fliken JSON för ett av exemplen:
Du bör se tre egenskaper:
text
,richText
och:type
.:type
är en reserverad egenskap som visarsling:resourceType
(eller sökväg) för AEM-komponenten. Värdet:type
är det som används för att mappa AEM-komponenten till SPA-komponenten.text
ochrichText
är ytterligare egenskaper som exponeras för SPA-komponenten.
Inspektera komponenten Text
-
Öppna en ny terminal och navigera till mappen
ui.frontend
i projektet. Körnpm install
och sedannpm start
för att starta webbpaketets dev-server:$ cd ui.frontend $ npm run start:mock
Modulen
ui.frontend
är för närvarande inställd på att använda JSON-modellen mock. -
Ett nytt webbläsarfönster öppnas för http://localhost:4200/content/wknd-spa-angular/us/en/home.html
-
Öppna AEM Project för WKND SPA i den utvecklingsmiljö du valt. Expandera modulen
ui.frontend
och öppna filen text.component.ts underui.frontend/src/app/components/text/text.component.ts
: -
Det första området som ska inspekteras är
class TextComponent
på ~rad 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) {} }
@Input() används för att deklarera fält vars värden anges via det mappade JSON-objektet som granskats tidigare.
@HostBinding('innerHtml') get content()
är en metod som visar det redigerade textinnehållet från värdetthis.text
. Om innehållet är RTF (som bestäms av flagganthis.richText
) kringgås Angular inbyggda säkerhet. Angular DomSanitizer används för att"rensa" HTML-råfilen och förhindra serveröverskridande skriptproblem (cross site scripting). Metoden är bunden till egenskapeninnerHtml
med dekoratorn @HostBinding. -
Kontrollera sedan
TextEditConfig
på ~rad 24:const TextEditConfig = { emptyLabel: 'Text', isEmpty: cqModel => !cqModel || !cqModel.text || cqModel.text.trim().length < 1 };
Koden ovan avgör när platshållaren ska återges i AEM redigeringsmiljö. Om metoden
isEmpty
returnerar true återges platshållaren. -
Ta till sist en titt på
MapTo
-anropet på ~rad 53:MapTo('wknd-spa-angular/components/text')(TextComponent, TextEditConfig );
MapTo tillhandahålls av AEM SPA Editor JS SDK (
@adobe/cq-angular-editable-components
). Sökvägenwknd-spa-angular/components/text
representerarsling:resourceType
för AEM-komponenten. Den här sökvägen matchas med:type
som exponeras av JSON-modellen som observerats tidigare. MapTo tolkar JSON-modellsvaret och skickar de korrekta värdena till@Input()
-variablerna i SPA-komponenten.Komponentdefinitionen för AEM
Text
finns påui.apps/src/main/content/jcr_root/apps/wknd-spa-angular/components/text
. -
Experimentera genom att ändra filen en.model.json på
ui.frontend/src/mocks/json/en.model.json
.På ~rad 62 uppdaterar du det första
Text
-värdet till att använda enH1
- ochu
-tagg:"text": { "text": "<h1><u>Hello World!</u></h1>", "richText": true, ":type": "wknd-spa-angular/components/text" }
Gå tillbaka till webbläsaren för att se de effekter som hanteras av webbpaketets dev-server:
Försök att växla egenskapen
richText
mellan true / false för att se hur återgivningslogiken fungerar. -
Granska text.component.html på
ui.frontend/src/app/components/text/text.component.html
.Den här filen är tom eftersom hela innehållet i komponenten anges av egenskapen
innerHTML
. -
Granska app.module.ts vid
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 inkluderas inte explicit, utan dynamiskt via AEMResponsiveGridComponent som tillhandahålls av AEM SPA Editor JS SDK. Därför måste finnas med i listan i arrayen app.module.ts entryComponents .
Skapa bildkomponenten
Skapa sedan en Image
Angular-komponent som är mappad till AEM Image-komponent. Komponenten Image
är ett annat exempel på en content-komponent.
Inspektera JSON
Innan du hoppar in i SPA-koden ska du kontrollera JSON-modellen som tillhandahålls av AEM.
-
Navigera till Bildexemplen i Core Component Library.
Egenskaper för
src
,alt
ochtitle
används för att fylla i SPA-komponentenImage
.NOTE
Andra bildegenskaper visas (lazyEnabled
,widths
) som gör att en utvecklare kan skapa en adaptiv och lat inläsningskomponent. Komponenten som är inbyggd i den här självstudiekursen är enkel och använder inte dessa avancerade egenskaper. -
Återgå till din IDE och öppna
en.model.json
påui.frontend/src/mocks/json/en.model.json
. Eftersom det här är en ny komponent i vårt projekt måste vi"göra dummy" av Image JSON.På ~rad 70 lägger du till en JSON-post för modellen
image
(glöm inte bort det avslutande kommatecknet,
efter den andratext_386303036
) och uppdaterar arrayen: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" ],
Projektet innehåller en exempelbild på
/mock-content/adobestock-140634652.jpeg
som används med webpack-dev-servern.Du kan visa den fullständiga versionen av en.model.json här.
-
Lägg till ett stockfoto som ska visas av komponenten.
Skapa en ny mapp med namnet images under
ui.frontend/src/mocks
. Hämta adobestock-140634652.jpeg och placera den i mappen images som du nyss skapade. Du kan använda din egen bild om du vill.
Implementera komponenten Bild
-
Stoppa webbpaketets dev-server om den startas.
-
Skapa en ny Image-komponent genom att köra Angular CLI
ng generate component
-kommandot från mappenui.frontend
:$ ng generate component components/image
-
Öppna image.component.ts vid
ui.frontend/src/app/components/image/image.component.ts
i den integrerade utvecklingsmiljön och uppdatera enligt följande: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
är konfigurationen som avgör om författarplatshållaren ska återges i AEM utifrån om egenskapensrc
fylls i.@Input()
avsrc
,alt
ochtitle
är de egenskaper som mappas från JSON API.hasImage()
är en metod som avgör om bilden ska återges eller inte.MapTo
mappar SPA-komponenten till AEM-komponenten påui.apps/src/main/content/jcr_root/apps/wknd-spa-angular/components/image
. -
Öppna image.component.html och uppdatera den enligt följande:
<ng-container *ngIf="hasImage"> <img class="image" [src]="src" [alt]="alt" [title]="title"/> </ng-container>
Detta återger elementet
<img>
omhasImage
returnerar true. -
Öppna image.component.scss och uppdatera den enligt följande:
:host-context { display: block; } .image { margin: 1rem 0; width: 100%; border: 0; }
NOTE
Regeln:host-context
är kritisk för att AEM SPA-redigerarplatshållaren ska fungera korrekt. Alla SPA-komponenter som ska redigeras i AEM sidredigerare måste ha den här regeln minst. -
Öppna
app.module.ts
och lägg tillImageComponent
i arrayenentryComponents
:entryComponents: [TextComponent, PageComponent, ImageComponent],
Precis som
TextComponent
läsesImageComponent
in dynamiskt och måste inkluderas ientryComponents
-arrayen. -
Starta webbpaketets dev-server för att se renderingen
ImageComponent
.$ npm run start:mock
Bild har lagts till i SPA
NOTE
Bonusutmaning: Implementera en ny metod för att visa värdet förtitle
som en bildtext under bilden.
Uppdatera principer i AEM
Komponenten ImageComponent
visas bara på webbpaketets dev-server. Distribuera sedan den uppdaterade produktinformationen till AEM och uppdatera mallprofilerna.
-
Stoppa webpack-dev-servern och distribuera ändringarna till AEM med dina Maven-kunskaper från root i projektet:
$ cd aem-guides-wknd-spa $ mvn clean install -PautoInstallSinglePackage
-
Gå till Tools > Templates > WKND SPA Angular från startskärmen i AEM.
Markera och redigera SPA-sidan:
-
Markera layoutbehållaren och klicka på dess policy-ikon för att redigera profilen:
-
Under Tillåtna komponenter > WKND SPA Angular - Innehåll > kontrollerar du Image -komponenten:
Under Standardkomponenter > Lägg till mappning och välj komponenten Image - WKND SPA Angular - Content :
Ange mime-typen av
image/*
.Klicka på Klar om du vill spara principuppdateringarna.
-
I layoutbehållaren klickar du på ikonen policy för komponenten Text :
Skapa en ny princip med namnet WKND SPA-text. Under Plugins > Formatering > markerar du alla rutor för att aktivera ytterligare formateringsalternativ:
Under Plugins > Styckeformat > markerar du kryssrutan för att aktivera styckeformat:
Klicka på Klar för att spara principuppdateringen.
-
Navigera till hemsidan http://localhost:4502/editor.html/content/wknd-spa-angular/us/en/home.html.
Du bör också kunna redigera komponenten
Text
och lägga till ytterligare styckeformat i helskärmsläge . -
Du bör också kunna dra och släppa en bild från Resurssökaren:
-
Lägg till egna bilder via AEM Assets eller installera den färdiga kodbasen för standardreferensplatsen WKND. WKND-referenswebbplatsen innehåller många bilder som kan återanvändas på WKND SPA. Paketet kan installeras med AEM Package Manager.
Inspektera layoutbehållaren
Stöd för layoutbehållaren tillhandahålls automatiskt av AEM SPA Editor SDK. Layoutbehållaren, som anges av namnet, är en container-komponent. Behållarkomponenter är komponenter som accepterar JSON-strukturer som representerar andra komponenter och instansierar dem dynamiskt.
Låt oss inspektera layoutbehållaren ytterligare.
-
Öppna responsive-grid.component.ts på
ui.frontend/src/app/components/responsive-grid
i IDE:import { AEMResponsiveGridComponent,MapTo } from '@adobe/cq-angular-editable-components'; MapTo('wcm/foundation/components/responsivegrid')(AEMResponsiveGridComponent);
AEMResponsiveGridComponent
implementeras som en del av AEM SPA Editor SDK och ingår i projektet viaimport-components
. -
I en webbläsare går du till http://localhost:4502/content/wknd-spa-angular/us/en.model.json
Komponenten Layoutbehållare har
sling:resourceType
wcm/foundation/components/responsivegrid
och känns igen av SPA-redigeraren med egenskapen:type
, precis som komponenternaText
ochImage
.Samma funktioner för att ändra storlek på en komponent med Layoutläge finns i SPA-redigeraren.
-
Gå tillbaka till http://localhost:4502/editor.html/content/wknd-spa-angular/us/en/home.html. Lägg till ytterligare Bild-komponenter och försök ändra storlek på dem med alternativet Layout :
-
Öppna JSON-modellen http://localhost:4502/content/wknd-spa-angular/us/en.model.json igen och observera
columnClassNames
som en del av JSON:Klassnamnet
aem-GridColumn--default--4
anger att komponenten ska vara 4 kolumner bred baserat på ett 12-kolumnsrutnät. Mer information om det responsiva rutnätet finns här. -
Återgå till IDE och i modulen
ui.apps
finns ett klientbibliotek definierat vidui.apps/src/main/content/jcr_root/apps/wknd-spa-angular/clientlibs/clientlib-grid
. Öppna filenless/grid.less
.Den här filen avgör vilka brytpunkter (
default
,tablet
ochphone
) som används av layoutbehållaren. Den här filen är avsedd att anpassas efter projektspecifikationer. För närvarande är brytpunkterna inställda på1200px
och650px
. -
Du bör kunna använda responsiva funktioner och uppdaterade RTF-principer för komponenten
Text
för att skapa en vy som följande:
Grattis!
Du lärde dig att mappa SPA-komponenter till AEM-komponenter och du implementerade en ny Image
-komponent. Du har också en chans att utforska de responsiva funktionerna i layoutbehållaren.
Du kan alltid visa den färdiga koden på GitHub eller checka ut koden lokalt genom att växla till grenen Angular/map-components-solution
.
Nästa steg
Navigering och routning - Lär dig hur flera vyer i SPA kan användas genom att mappa till AEM Pages med SPA Editor SDK. Dynamisk navigering implementeras med Angular Router och läggs till i en befintlig Header-komponent.
Bonus - Beständiga konfigurationer till källkontroll
I många fall, särskilt i början av ett AEM-projekt, är det värdefullt att behålla konfigurationer som mallar och relaterade innehållsprinciper för källkontroll. Detta garanterar att alla utvecklare arbetar mot samma uppsättning innehåll och konfigurationer och kan säkerställa ytterligare enhetlighet mellan miljöer. När ett projekt når en viss mognadsnivå kan rutinen med mallhantering överföras till en särskild grupp med avancerade användare.
Nästa steg kommer att utföras med Visual Studio Code IDE och VSCode AEM Sync men kan utföras med alla verktyg och alla IDE som du har konfigurerat till pull - eller import -innehåll från en lokal instans av AEM.
-
I Visual Studio Code IDE kontrollerar du att du har VSCode AEM Sync installerat via Marketplace-tillägget:
-
Utöka modulen ui.content i Project Explorer och gå till
/conf/wknd-spa-angular/settings/wcm/templates
. -
Högerklicka på mappen
templates
och välj Importera från AEM Server: -
Upprepa stegen för att importera innehåll men välj mappen policies på
/conf/wknd-spa-angular/settings/wcm/policies
. -
Granska filen
filter.xml
som finns på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>
Filen
filter.xml
ansvarar för att identifiera sökvägarna till noder som har installerats med paketet. Observeramode="merge"
på vart och ett av filtren som anger att befintligt innehåll inte ändras, endast nytt innehåll läggs till. Eftersom innehållsförfattare kan uppdatera dessa sökvägar är det viktigt att en koddistribution inte skriver över innehåll. Mer information om hur du arbetar med filterelement finns i dokumentationen för FileVault.Jämför
ui.content/src/main/content/META-INF/vault/filter.xml
ochui.apps/src/main/content/META-INF/vault/filter.xml
för att förstå de olika noder som hanteras av varje modul.