Utöka en kärnkomponent
- 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 hur du utökar en befintlig Core Component som ska användas med AEM SPA Editor. Att förstå hur man utökar en befintlig komponent är en kraftfull teknik för att anpassa och utöka funktionerna i en AEM SPA Editor-implementering.
Syfte
- Utöka en befintlig Core Component med ytterligare egenskaper och innehåll.
- Förstå grunderna för komponentarv med användningen av
sling:resourceSuperType
. - Lär dig hur du använder delegeringsmönstret för delningsmodeller för att återanvända befintlig logik och befintliga funktioner.
Vad du ska bygga
I det här kapitlet skapas en ny Card
-komponent. Komponenten Card
utökar Image Core Component genom att lägga till ytterligare innehållsfält som en Title och en Call to action-knapp för att utföra rollen som teaser för annat innehåll i SPA.
Card
-komponent beroende på projektkraven. Du bör alltid använda kärnkomponenter direkt när det är möjligt.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/extend-component-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
-
Installera det färdiga paketet för den traditionella WKND-referensplatsen. Bilderna som tillhandahålls av WKND-referensplatsen återanvänds i WKND SPA. Paketet kan installeras med AEM Package Manager.
Du kan alltid visa den färdiga koden på GitHub eller checka ut koden lokalt genom att växla till grenen Angular/extend-component-solution
.
Inspektera den inledande kortimplementeringen
En initial kortkomponent har tillhandahållits av kapitelstartkoden. Granska startpunkten för kortimplementeringen.
-
Öppna modulen
ui.apps
i den IDE du väljer. -
Navigera till
ui.apps/src/main/content/jcr_root/apps/wknd-spa-angular/components/card
och visa filen.content.xml
.<?xml version="1.0" encoding="UTF-8"?> <jcr:root xmlns:sling="http://sling.apache.org/jcr/sling/1.0" xmlns:cq="http://www.day.com/jcr/cq/1.0" xmlns:jcr="http://www.jcp.org/jcr/1.0" jcr:primaryType="cq:Component" jcr:title="Card" sling:resourceSuperType="wknd-spa-angular/components/image" componentGroup="WKND SPA Angular - Content"/>
Egenskapen
sling:resourceSuperType
pekar påwknd-spa-angular/components/image
som anger att komponentenCard
ärver funktionaliteten från WKND SPA Image-komponenten. -
Granska filen
ui.apps/src/main/content/jcr_root/apps/wknd-spa-angular/components/image/.content.xml
:<?xml version="1.0" encoding="UTF-8"?> <jcr:root xmlns:sling="http://sling.apache.org/jcr/sling/1.0" xmlns:cq="http://www.day.com/jcr/cq/1.0" xmlns:jcr="http://www.jcp.org/jcr/1.0" jcr:primaryType="cq:Component" jcr:title="Image" sling:resourceSuperType="core/wcm/components/image/v2/image" componentGroup="WKND SPA Angular - Content"/>
Observera att
sling:resourceSuperType
pekar påcore/wcm/components/image/v2/image
. Detta anger att WKND SPA Image-komponenten ärver funktionaliteten från Core Component Image.Det kallas också Proxymönstret Att dela resursarv är ett kraftfullt designmönster som tillåter att underordnade komponenter ärver funktioner och utökar/åsidosätter beteenden när det behövs. Sling-arv har stöd för flera nivåer av arv, så i slutändan ärver den nya
Card
-komponenten funktionerna i Core Component Image.Många utvecklingsteam strävar efter att bli D.R.Y. (upprepa inte dig själv). Sling arv gör detta möjligt med AEM.
-
Öppna filen
_cq_dialog/.content.xml
under mappencard
.Den här filen är definitionen för komponentdialogrutan för komponenten
Card
. Om du använder Samling-arv är det möjligt att använda funktionerna i Samling av resurser för att åsidosätta eller utöka delar av dialogrutan. I det här exemplet har en ny flik lagts till i dialogrutan för att hämta ytterligare data från en författare som ska fylla i kortkomponenten.Egenskaper som
sling:orderBefore
låter en utvecklare välja var nya flikar eller formulärfält ska infogas. I det här fallet infogas flikenText
före flikenasset
. Om du vill använda Sling Resource Merger fullt ut är det viktigt att du känner till den ursprungliga dialognodstrukturen för dialogrutan Bildkomponent. -
Öppna filen
_cq_editConfig.xml
under mappencard
. Den här filen styr dra och släpp-funktionen i AEM redigeringsgränssnitt. När du utökar bildkomponenten är det viktigt att resurstypen matchar själva komponenten. Granska noden<parameters>
:<parameters jcr:primaryType="nt:unstructured" sling:resourceType="wknd-spa-angular/components/card" imageCrop="" imageMap="" imageRotate=""/>
De flesta komponenter kräver inte en
cq:editConfig
, bilden och de underordnade för Image-komponenten är undantag. -
I IDE-växeln till modulen
ui.frontend
navigerar du tillui.frontend/src/app/components/card
: -
Granska filen
card.component.ts
.Komponenten har redan delats ut för att mappa till AEM
Card
-komponenten med standardfunktionenMapTo
.MapTo('wknd-spa-angular/components/card')(CardComponent, CardEditConfig);
Granska de tre
@Input
parametrarna i klassen försrc
,alt
ochtitle
. Dessa är förväntade JSON-värden från AEM-komponenten som mappas till Angular-komponenten. -
Öppna filen
card.component.html
:<div class="card" *ngIf="hasContent"> <app-image class="card__image" [src]="src" [alt]="alt" [title]="title"></app-image> </div>
I det här exemplet valde vi att återanvända den befintliga Angular Image-komponenten
app-image
genom att helt enkelt skicka@Input
-parametrarna fråncard.component.ts
. Senare i självstudiekursen läggs ytterligare egenskaper till och visas.
Uppdatera mallprincipen
I den här initiala Card
-implementeringen granskas funktionen i AEM SPA Editor. Om du vill visa den inledande Card
-komponenten krävs en uppdatering av mallprincipen.
-
Distribuera startkoden till en lokal instans av AEM, om du inte redan gjort det:
$ cd aem-guides-wknd-spa $ mvn clean install -PautoInstallSinglePackage
-
Gå till SPA-sidmallen på http://localhost:4502/editor.html/conf/wknd-spa-angular/settings/wcm/templates/spa-page-template/structure.html.
-
Uppdatera layoutbehållarens princip så att den nya
Card
-komponenten läggs till som en tillåten komponent:Spara ändringarna i principen och observera komponenten
Card
som en tillåten komponent:
Initialkortskomponent för författare
Därefter redigerar du komponenten Card
med AEM SPA Editor.
-
Gå till http://localhost:4502/editor.html/content/wknd-spa-angular/us/en/home.html.
-
I
Edit
-läget lägger du till komponentenCard
iLayout Container
: -
Dra och släpp en bild från Resurssökaren till komponenten
Card
: -
Öppna dialogrutan för komponenten
Card
och lägg märke till att en Text -flik har lagts till. -
Ange följande värden på fliken Text:
Kortsökväg - välj en sida under SPA-startsidan.
CTA-text - "Läs mer"
Korttitel - lämna tomt
Hämta rubrik från länkad sida - markera kryssrutan för att ange true.
-
Uppdatera fliken Resursmetadata om du vill lägga till värden för Alternativ text och Bildtext.
Inga ytterligare ändringar visas efter att dialogrutan har uppdaterats. Om du vill visa de nya fälten för Angular-komponenten måste du uppdatera Sling-modellen för
Card
-komponenten. -
Öppna en ny flik och gå till CRXDE-Lite. Sök efter
Card
-komponentinnehållet genom att granska innehållsnoderna under/content/wknd-spa-angular/us/en/home/jcr:content/root/responsivegrid
.Observera att egenskaperna
cardPath
,ctaText
,titleFromPage
bevaras av dialogrutan.
Uppdatera kortförsäljningsmodell
För att slutligen visa värdena från komponentdialogen för Angular-komponenten måste vi uppdatera Sling-modellen som fyller i JSON för Card
-komponenten. Vi har också möjlighet att implementera två affärslogikfunktioner:
- Om
titleFromPage
till true returnerar du sidans rubrik som anges avcardPath
, annars returneras värdet för textfältetcardTitle
. - Returnera det senaste ändringsdatumet för sidan som anges av
cardPath
.
Gå tillbaka till den utvecklingsmiljö du valt och öppna modulen core
.
-
Öppna filen
Card.java
vidcore/src/main/java/com/adobe/aem/guides/wknd/spa/angular/core/models/Card.java
.Observera att gränssnittet
Card
för närvarande utökarcom.adobe.cq.wcm.core.components.models.Image
och därför ärver metoderna för gränssnittetImage
. GränssnittetImage
utökar redan gränssnittetComponentExporter
som gör att Sling Model kan exporteras som JSON och mappas av SPA-redigeraren. Därför behöver vi inte utöka gränssnittetComponentExporter
explicit, som vi gjorde i kapitlet Anpassad komponent. -
Lägg till följande metoder i gränssnittet:
@ProviderType public interface Card extends Image { /*** * The URL to populate the CTA button as part of the card. * The link should be based on the cardPath property that points to a page. * @return String URL */ public String getCtaLinkURL(); /*** * The text to display on the CTA button of the card. * @return String CTA text */ public String getCtaText(); /*** * The date to be displayed as part of the card. * This is based on the last modified date of the page specified by the cardPath * @return */ public Calendar getCardLastModified(); /** * Return the title of the page specified by cardPath if `titleFromPage` is set to true. * Otherwise return the value of `cardTitle` * @return */ public String getCardTitle(); }
Dessa metoder visas via JSON-modellens API och skickas till Angular-komponenten.
-
Öppna
CardImpl.java
. Detta är implementeringen av gränssnittetCard.java
. Implementeringen har delvis stoppats för att snabba upp självstudiekursen. Observera att anteckningarna@Model
och@Exporter
används för att se till att Sling Model kan serialiseras som JSON via Sling Model Exporter.CardImpl.java
använder också delegeringsmönstret för delningsmodeller för att undvika att logiken från Image Core-komponenten skrivs om. -
Observera följande rader:
@Self @Via(type = ResourceSuperType.class) private Image image;
Anteckningen ovan instansierar ett bildobjekt med namnet
image
baserat påsling:resourceSuperType
-arvet för komponentenCard
.@Override public String getSrc() { return null != image ? image.getSrc() : null; }
Det går sedan att använda objektet
image
för att implementera metoder som definieras av gränssnittetImage
, utan att behöva skriva logiken själv. Den här tekniken används förgetSrc()
,getAlt()
ochgetTitle()
. -
Implementera sedan metoden
initModel()
för att initiera en privat variabelcardPage
baserat på värdet förcardPath
@PostConstruct public void initModel() { if(StringUtils.isNotBlank(cardPath) && pageManager != null) { cardPage = pageManager.getPage(this.cardPath); } }
@PostConstruct initModel()
anropas när delningsmodellen initieras och därför är det en bra möjlighet att initiera objekt som kan användas av andra metoder i modellen.pageManager
är ett av flera Java™-bakomliggande globala objekt som är tillgängliga för Sling-modeller via anteckningen@ScriptVariable
. Metoden getPage tar en sökväg och returnerar ett AEM Page-objekt eller null om sökvägen inte pekar på en giltig sida.Detta initierar variabeln
cardPage
, som används av andra nya metoder för att returnera data om den underliggande länkade sidan. -
Granska de globala variabler som redan är mappade till JCR-egenskaperna som sparade författardialogrutan.
@ValueMapValue
-anteckningen används för att utföra mappningen automatiskt.@ValueMapValue private String cardPath; @ValueMapValue private String ctaText; @ValueMapValue private boolean titleFromPage; @ValueMapValue private String cardTitle;
Dessa variabler används för att implementera ytterligare metoder för gränssnittet
Card.java
. -
Implementera ytterligare metoder som definierats i gränssnittet
Card.java
:@Override public String getCtaLinkURL() { if(cardPage != null) { return cardPage.getPath() + ".html"; } return null; } @Override public String getCtaText() { return ctaText; } @Override public Calendar getCardLastModified() { if(cardPage != null) { return cardPage.getLastModified(); } return null; } @Override public String getCardTitle() { if(titleFromPage) { return cardPage != null ? cardPage.getTitle() : null; } return cardTitle; }
NOTE
Du kan visa den färdiga CardImpl.java här. -
Öppna ett terminalfönster och distribuera bara uppdateringarna till modulen
core
med profilen MavenautoInstallBundle
från katalogencore
.$ cd core/ $ mvn clean install -PautoInstallBundle
Om du använder AEM 6.x lägger du till profilen
classic
. -
Visa JSON-modellsvaret på: http://localhost:4502/content/wknd-spa-angular/us/en.model.json och sök efter
wknd-spa-angular/components/card
:"card": { "ctaText": "Read More", "cardTitle": "Page 1", "title": "Woman chillaxing with river views in Australian bushland", "src": "/content/wknd-spa-angular/us/en/home/_jcr_content/root/responsivegrid/card.coreimg.jpeg/1595190732886/adobestock-216674449.jpeg", "alt": "Female sitting on a large rock relaxing in afternoon dappled light the Australian bushland with views over the river", "cardLastModified": 1591360492414, "ctaLinkURL": "/content/wknd-spa-angular/us/en/home/page-1.html", ":type": "wknd-spa-angular/components/card" }
Observera att JSON-modellen uppdateras med ytterligare nyckel-/värdepar efter att metoderna i
CardImpl
-segmentmodellen har uppdaterats.
Uppdatera Angular-komponent
Nu när JSON-modellen har fyllts i med nya egenskaper för ctaLinkURL
, ctaText
, cardTitle
och cardLastModified
kan vi uppdatera Angular-komponenten så att de visas.
-
Återgå till IDE och öppna modulen
ui.frontend
. Du kan också starta webbpaketets dev-server från ett nytt terminalfönster för att se ändringarna i realtid:$ cd ui.frontend $ npm install $ npm start
-
Öppna
card.component.ts
ui.frontend/src/app/components/card/card.component.ts
. Lägg till ytterligare@Input
anteckningar för att hämta den nya modellen:export class CardComponent implements OnInit { @Input() src: string; @Input() alt: string; @Input() title: string; + @Input() cardTitle: string; + @Input() cardLastModified: number; + @Input() ctaLinkURL: string; + @Input() ctaText: string;
-
Lägg till metoder för att kontrollera om Call to action är klart och för att returnera en datum/tid-sträng baserat på
cardLastModified
-indata:export class CardComponent implements OnInit { ... get hasCTA(): boolean { return this.ctaLinkURL && this.ctaLinkURL.trim().length > 0 && this.ctaText && this.ctaText.trim().length > 0; } get lastModifiedDate(): string { const lastModifiedDate = this.cardLastModified ? new Date(this.cardLastModified) : null; if (lastModifiedDate) { return lastModifiedDate.toLocaleDateString(); } return null; } ... }
-
Öppna
card.component.html
och lägg till följande kod för att visa titeln, call to action och det senaste ändringsdatumet:<div class="card" *ngIf="hasContent"> <app-image class="card__image" [src]="src" [alt]="alt" [title]="title"></app-image> <div class="card__content"> <h2 class="card__title"> {{cardTitle}} <span class="card__lastmod" *ngIf="lastModifiedDate">{{lastModifiedDate}}</span> </h2> <div class="card__action-container" *ngIf="hasCTA"> <a [routerLink]="ctaLinkURL" class="card__action-link" [title]="ctaText"> {{ctaText}} </a> </div> </div> </div>
Sass-regler har redan lagts till
card.component.scss
för att formatera titeln, call to action och det senaste ändringsdatumet.NOTE
Du kan visa den färdiga koden för Angular-kortkomponenten här. -
Använd de fullständiga ändringarna i AEM från projektets rot i Maven:
$ cd aem-guides-wknd-spa $ mvn clean install -PautoInstallSinglePackage
-
Navigera till http://localhost:4502/editor.html/content/wknd-spa-angular/us/en/home.html för att se den uppdaterade komponenten:
-
Du bör kunna omskapa det befintliga innehållet för att skapa en sida som ser ut ungefär så här:
Grattis!
Grattis! Du har lärt dig hur du utökar en AEM-komponent och hur Sling-modeller och dialogrutor fungerar med JSON-modellen.
Du kan alltid visa den färdiga koden på GitHub eller checka ut koden lokalt genom att växla till grenen Angular/extend-component-solution
.