Estendere un componente core extend-component
Scopri come estendere un Componente core esistente da utilizzare con l’Editor SPA dell’AEM. Scopri come estendere un componente esistente è una tecnica potente per personalizzare ed espandere le funzionalità di un’implementazione dell’Editor SPA dell’AEM.
Obiettivo
- Estendi un componente core esistente con proprietà e contenuti aggiuntivi.
- Comprendere le nozioni di base dell'ereditarietà dei componenti con l'utilizzo di
sling:resourceSuperType
. - Scopri come utilizzare il Pattern di delega per modelli Sling per riutilizzare la logica e le funzionalità esistenti.
Cosa verrà creato
In questo capitolo viene creato un nuovo componente Card
. Il componente Card
estende il componente core Immagine aggiungendo ulteriori campi di contenuto, come un titolo e un pulsante di invito all'azione, per eseguire il ruolo di teaser per altri contenuti all'interno dell'SPA.
Card
a seconda dei requisiti del progetto. Si consiglia sempre di utilizzare Componenti core direttamente quando possibile.Prerequisiti
Esaminare gli strumenti e le istruzioni necessari per configurare un ambiente di sviluppo locale.
Ottieni il codice
-
Scarica il punto di partenza per questa esercitazione tramite Git:
code language-shell $ git clone git@github.com:adobe/aem-guides-wknd-spa.git $ cd aem-guides-wknd-spa $ git checkout Angular/extend-component-start
-
Distribuisci la base di codice in un’istanza AEM locale utilizzando Maven:
code language-shell $ mvn clean install -PautoInstallSinglePackage
Se utilizzi AEM 6.x, aggiungi il profilo
classic
:code language-shell $ mvn clean install -PautoInstallSinglePackage -Pclassic
-
Installa il pacchetto finito per il sito di riferimento WKND tradizionale. Le immagini fornite dal sito di riferimento WKND vengono riutilizzate nell'SPA WKND. È possibile installare il pacchetto utilizzando Gestione pacchetti AEM.
Puoi sempre visualizzare il codice finito su GitHub o estrarre il codice localmente passando al ramo Angular/extend-component-solution
.
Implementazione della carta iniziale di Inspect
Un componente iniziale della scheda è stato fornito dal codice iniziale del capitolo. Inspect è il punto di partenza per l’implementazione della scheda.
-
Nell'IDE scelto aprire il modulo
ui.apps
. -
Passare a
ui.apps/src/main/content/jcr_root/apps/wknd-spa-angular/components/card
e visualizzare il file.content.xml
.code language-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"/>
La proprietà
sling:resourceSuperType
punta awknd-spa-angular/components/image
indicando che il componenteCard
eredita la funzionalità dal componente WKND SPA Image. -
Inspect il file
ui.apps/src/main/content/jcr_root/apps/wknd-spa-angular/components/image/.content.xml
:code language-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"/>
sling:resourceSuperType
punta acore/wcm/components/image/v2/image
. Questo indica che il componente Immagine SPA WKND eredita la funzionalità dall’immagine del componente core.Anche nota come Ereditarietà delle risorse Sling per pattern proxy è una potente struttura che consente ai componenti figlio di ereditare funzionalità ed estendere/ignorare il comportamento quando desiderato. L'ereditarietà Sling supporta più livelli di ereditarietà, pertanto alla fine il nuovo componente
Card
eredita la funzionalità dell'immagine del componente core.Molti team di sviluppo si sforzano di essere D.R.Y. (non ripeterti). L’ereditarietà Sling lo rende possibile con l’AEM.
-
Nella cartella
card
aprire il file_cq_dialog/.content.xml
.Questo file è la definizione della finestra di dialogo del componente
Card
. Se si utilizza l'ereditarietà Sling, è possibile utilizzare le funzionalità di Sling Resource Merger per ignorare o estendere parti della finestra di dialogo. In questo esempio, è stata aggiunta una nuova scheda alla finestra di dialogo per acquisire dati aggiuntivi da un autore per popolare il componente Scheda.Proprietà come
sling:orderBefore
consentono a uno sviluppatore di scegliere dove inserire nuove schede o campi modulo. In questo caso, la schedaText
viene inserita prima della schedaasset
. Per utilizzare appieno Sling Resource Merger, è importante conoscere la struttura originale del nodo della finestra di dialogo per la finestra di dialogo del componente immagine. -
Nella cartella
card
aprire il file_cq_editConfig.xml
. Questo file determina il comportamento di trascinamento nell’interfaccia utente di creazione dell’AEM. Quando si estende il componente Immagine, è importante che il tipo di risorsa corrisponda al componente stesso. Rivedi il nodo<parameters>
:code language-xml <parameters jcr:primaryType="nt:unstructured" sling:resourceType="wknd-spa-angular/components/card" imageCrop="" imageMap="" imageRotate=""/>
La maggior parte dei componenti non richiede un
cq:editConfig
, l'Immagine e i discendenti secondari del componente Immagine sono eccezioni. -
Nell'IDE passare al modulo
ui.frontend
, passando aui.frontend/src/app/components/card
: -
Inspect il file
card.component.ts
.Il componente è già stato sottoposto a stubout per la mappatura sul componente AEM
Card
utilizzando la funzione standardMapTo
.code language-js MapTo('wknd-spa-angular/components/card')(CardComponent, CardEditConfig);
Esaminare i tre parametri
@Input
nella classe persrc
,alt
etitle
. Si tratta di valori JSON previsti dal componente AEM mappati al componente Angular. -
Aprire il file
card.component.html
:code language-html <div class="card" *ngIf="hasContent"> <app-image class="card__image" [src]="src" [alt]="alt" [title]="title"></app-image> </div>
In questo esempio si è scelto di riutilizzare il componente immagine Angular esistente
app-image
passando semplicemente i parametri@Input
dacard.component.ts
. Più avanti nell’esercitazione, vengono aggiunte e visualizzate ulteriori proprietà.
Aggiornare il criterio del modello
Con questa implementazione iniziale di Card
, verifica la funzionalità nell'editor SPA dell'AEM. Per visualizzare il componente Card
iniziale è necessario aggiornare il criterio del modello.
-
Distribuisci il codice di avvio in un’istanza locale dell’AEM, se non lo hai già fatto:
code language-shell $ cd aem-guides-wknd-spa $ mvn clean install -PautoInstallSinglePackage
-
Passa al modello per pagina SPA all'indirizzo http://localhost:4502/editor.html/conf/wknd-spa-angular/settings/wcm/templates/spa-page-template/structure.html.
-
Aggiornare il criterio Contenitore di layout per aggiungere il nuovo componente
Card
come componente consentito:Salvare le modifiche al criterio e osservare il componente
Card
come componente consentito:
Componente carta iniziale autore
Creare quindi il componente Card
utilizzando l'editor SPA dell'AEM.
-
Passa a http://localhost:4502/editor.html/content/wknd-spa-angular/us/en/home.html.
-
In modalità
Edit
, aggiungere il componenteCard
aLayout Container
: -
Trascina e rilascia un'immagine da Asset Finder al componente
Card
: -
Apri la finestra di dialogo del componente
Card
e osserva l'aggiunta di una scheda Testo. -
Immetti i seguenti valori nella scheda Testo:
Percorso scheda - scegli una pagina sotto la home page SPA.
Testo CTA - "Ulteriori informazioni"
Titolo carta - lascia vuoto
Ottieni titolo da pagina collegata. Selezionare la casella di controllo per indicare true.
-
Aggiorna la scheda Metadati risorsa per aggiungere valori per Testo alternativo e Didascalia.
Al momento non vengono visualizzate ulteriori modifiche dopo l’aggiornamento della finestra di dialogo. Per esporre i nuovi campi al componente Angular, è necessario aggiornare il modello Sling per il componente
Card
. -
Apri una nuova scheda e passa a CRXDE-Lite. Inspect individua i nodi di contenuto sotto
/content/wknd-spa-angular/us/en/home/jcr:content/root/responsivegrid
per trovare il contenuto del componenteCard
.Osservare che le proprietà
cardPath
,ctaText
,titleFromPage
sono rese permanenti dalla finestra di dialogo.
Aggiorna modello Sling della scheda
Per esporre in definitiva i valori della finestra di dialogo del componente al componente di Angular, è necessario aggiornare il modello Sling che popola il JSON per il componente Card
. Abbiamo anche l’opportunità di implementare due parti della logica di business:
- Se
titleFromPage
è true, restituire il titolo della pagina specificato dacardPath
. In caso contrario, restituire il valore dicardTitle
textfield. - Restituisce la data dell'ultima modifica della pagina specificata da
cardPath
.
Tornare all'IDE desiderato e aprire il modulo core
.
-
Aprire il file
Card.java
incore/src/main/java/com/adobe/aem/guides/wknd/spa/angular/core/models/Card.java
.L'interfaccia
Card
estende attualmentecom.adobe.cq.wcm.core.components.models.Image
ed eredita pertanto i metodi dell'interfacciaImage
. L'interfacciaImage
estende già l'interfacciaComponentExporter
che consente l'esportazione del modello Sling come JSON e la mappatura da parte dell'editor SPA. Non è pertanto necessario estendere esplicitamente l'interfacciaComponentExporter
come nel capitolo Componente personalizzato. -
Aggiungi i seguenti metodi all’interfaccia:
code language-java @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(); }
Questi metodi vengono esposti tramite l’API del modello JSON e passati al componente Angular.
-
Apri
CardImpl.java
. Implementazione dell'interfacciaCard.java
. Questa implementazione è stata parzialmente testata per accelerare l’esercitazione. Osserva l’utilizzo delle annotazioni@Model
e@Exporter
per garantire che il modello Sling possa essere serializzato come JSON tramite Sling Model Exporter.CardImpl.java
utilizza anche il pattern di delega per modelli Sling per evitare di riscrivere la logica dal componente core Immagine. -
Osserva le righe seguenti:
code language-java @Self @Via(type = ResourceSuperType.class) private Image image;
L'annotazione precedente crea un'istanza di un oggetto Image denominato
image
in base all'ereditarietàsling:resourceSuperType
del componenteCard
.code language-java @Override public String getSrc() { return null != image ? image.getSrc() : null; }
È quindi possibile utilizzare semplicemente l'oggetto
image
per implementare i metodi definiti dall'interfacciaImage
, senza dover scrivere direttamente la logica. Questa tecnica è utilizzata pergetSrc()
,getAlt()
egetTitle()
. -
Implementare quindi il metodo
initModel()
per avviare una variabile privatacardPage
in base al valore dicardPath
code language-java @PostConstruct public void initModel() { if(StringUtils.isNotBlank(cardPath) && pageManager != null) { cardPage = pageManager.getPage(this.cardPath); } }
@PostConstruct initModel()
viene chiamato quando il modello Sling viene inizializzato, pertanto è una buona opportunità per inizializzare oggetti che possono essere utilizzati da altri metodi nel modello.pageManager
è uno dei numerosi oggetti globali supportati da Java™ resi disponibili ai modelli Sling tramite l'annotazione@ScriptVariable
. Il metodo getPage accetta un percorso e restituisce un oggetto Page dell'AEM oppure null se il percorso non punta a una pagina valida.Inizializza la variabile
cardPage
, utilizzata dagli altri nuovi metodi per restituire dati sulla pagina collegata sottostante. -
Rivedi le variabili globali già mappate alle proprietà JCR salvate nella finestra di dialogo di authoring. L'annotazione
@ValueMapValue
viene utilizzata per eseguire automaticamente la mappatura.code language-java @ValueMapValue private String cardPath; @ValueMapValue private String ctaText; @ValueMapValue private boolean titleFromPage; @ValueMapValue private String cardTitle;
Queste variabili vengono utilizzate per implementare i metodi aggiuntivi per l'interfaccia
Card.java
. -
Implementare i metodi aggiuntivi definiti nell'interfaccia
Card.java
:code language-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 note NOTE Puoi visualizzare CardImpl.java finito qui. -
Aprire una finestra del terminale e distribuire solo gli aggiornamenti al modulo
core
utilizzando il profilo MavenautoInstallBundle
dalla directorycore
.code language-shell $ cd core/ $ mvn clean install -PautoInstallBundle
Se utilizzi AEM 6.x, aggiungi il profilo
classic
. -
Visualizza la risposta del modello JSON in: http://localhost:4502/content/wknd-spa-angular/us/en.model.json e cerca
wknd-spa-angular/components/card
:code language-json "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" }
Il modello JSON viene aggiornato con altre coppie chiave/valore dopo l'aggiornamento dei metodi nel modello Sling
CardImpl
.
Aggiorna componente Angular
Ora che il modello JSON è compilato con nuove proprietà per ctaLinkURL
, ctaText
, cardTitle
e cardLastModified
, è possibile aggiornare il componente Angular per visualizzarli.
-
Tornare all'IDE e aprire il modulo
ui.frontend
. Se necessario, avviare il server di sviluppo Webpack da una nuova finestra del terminale per visualizzare le modifiche in tempo reale:code language-shell $ cd ui.frontend $ npm install $ npm start
-
Apri
card.component.ts
alleui.frontend/src/app/components/card/card.component.ts
. Aggiungi ulteriori@Input
annotazioni per acquisire il nuovo modello:code language-diff 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;
-
Aggiungere metodi per verificare se l'invito all'azione è pronto e per restituire una stringa di data/ora basata sull'input
cardLastModified
:code language-js 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; } ... }
-
Apri
card.component.html
e aggiungi il seguente markup per visualizzare il titolo, l'invito all'azione e la data dell'ultima modifica:code language-html <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>
Le regole Sass sono già state aggiunte alle
card.component.scss
per assegnare uno stile al titolo, all'invito all'azione e alla data dell'ultima modifica.note note NOTE Puoi visualizzare il codice componente scheda di Angular completato qui. -
Implementa le modifiche complete all’AEM dalla directory principale del progetto utilizzando Maven:
code language-shell $ cd aem-guides-wknd-spa $ mvn clean install -PautoInstallSinglePackage
-
Passa a http://localhost:4502/editor.html/content/wknd-spa-angular/us/en/home.html per visualizzare il componente aggiornato:
-
Dovresti essere in grado di riscrivere il contenuto esistente per creare una pagina simile alla seguente:
Congratulazioni. congratulations
Congratulazioni, hai imparato a estendere un componente AEM e come i modelli e le finestre di dialogo Sling funzionano con il modello JSON.
Puoi sempre visualizzare il codice finito su GitHub o estrarre il codice localmente passando al ramo Angular/extend-component-solution
.