Estendere un componente core extend-component
- Editor universale per la modifica visiva di contenuti headless.
- Editor frammenti di contenuto per la modifica di contenuti headless basata su modulo.
Scopri come estendere un Componente core esistente da utilizzare con l’Editor SPA di AEM. Scopri come estendere un componente esistente è una tecnica potente per personalizzare ed espandere le funzionalità di un’implementazione dell’Editor SPA di 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 campi di contenuto aggiuntivi come un titolo e un pulsante Call to action per eseguire il ruolo di teaser per altri contenuti nell'applicazione a pagina singola.
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 -
Implementa la base di codice in un’istanza AEM locale utilizzando Maven:
code language-shell $ mvn clean install -PautoInstallSinglePackageSe 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'applicazione a pagina singola WKND. È possibile installare il pacchetto utilizzando Gestione pacchetti di AEM.
Puoi sempre visualizzare il codice finito su GitHub o estrarre il codice localmente passando al ramo Angular/extend-component-solution.
Ispezionare l’implementazione iniziale della carta
Un componente iniziale della scheda è stato fornito dal codice iniziale del capitolo. Ispeziona 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/carde 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:resourceSuperTypepunta awknd-spa-angular/components/imageindicando che il componenteCarderedita la funzionalità dal componente immagine SPA WKND. -
Esaminare 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:resourceSuperTypepunta 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
Carderedita 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 AEM.
-
Nella cartella
cardaprire 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:orderBeforeconsentono a uno sviluppatore di scegliere dove inserire nuove schede o campi modulo. In questo caso, la schedaTextviene 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
cardaprire il file_cq_editConfig.xml. Questo file determina il comportamento di trascinamento nell’interfaccia utente di authoring di 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:
-
Controllare il file
card.component.ts.Il componente è già stato sottoposto a stubout per la mappatura al componente AEM
Cardutilizzando la funzione standardMapTo.code language-js MapTo('wknd-spa-angular/components/card')(CardComponent, CardEditConfig);Esaminare i tre parametri
@Inputnella classe persrc,altetitle. 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 di Angular esistente
app-imagesemplicemente passando i parametri@Inputdacard.component.ts. Più avanti nell’esercitazione, vengono aggiunte e visualizzate ulteriori proprietà.
Aggiornare il criterio del modello
Con questa implementazione iniziale di Card, controlla la funzionalità nell'editor SPA di AEM. Per visualizzare il componente Card iniziale è necessario aggiornare il criterio del modello.
-
Distribuisci il codice di avvio in un’istanza locale di 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
Cardcome componente consentito:
Salvare le modifiche al criterio e osservare il componente
Cardcome componente consentito:
Componente carta iniziale autore
Quindi, creare il componente Card utilizzando l'editor SPA di AEM.
-
Passa a http://localhost:4502/editor.html/content/wknd-spa-angular/us/en/home.html.
-
In modalità
Edit, aggiungere il componenteCardaLayout Container:
-
Trascina e rilascia un'immagine da Asset Finder al componente
Card:
-
Apri la finestra di dialogo del componente
Carde osserva l'aggiunta di una scheda Testo. -
Immetti i seguenti valori nella scheda Testo:
Percorso scheda - scegli una pagina sotto la home page dell'applicazione a pagina singola.
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. Esaminare i nodi di contenuto sotto
/content/wknd-spa-angular/us/en/home/jcr:content/root/responsivegridper trovare il contenuto del componenteCard.
Osservare che le proprietà
cardPath,ctaText,titleFromPagesono 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 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 dicardTitletextfield. - Restituisce la data dell'ultima modifica della pagina specificata da
cardPath.
Tornare all'IDE desiderato e aprire il modulo core.
-
Aprire il file
Card.javaincore/src/main/java/com/adobe/aem/guides/wknd/spa/angular/core/models/Card.java.L'interfaccia
Cardestende attualmentecom.adobe.cq.wcm.core.components.models.Imageed eredita pertanto i metodi dell'interfacciaImage. L'interfacciaImageestende già l'interfacciaComponentExporterche consente l'esportazione del modello Sling come JSON e la mappatura da parte dell'editor SPA. Non è pertanto necessario estendere esplicitamente l'interfacciaComponentExportercome 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@Modele@Exporterper garantire che il modello Sling possa essere serializzato come JSON tramite Sling Model Exporter.CardImpl.javautilizza 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
imagein base all'ereditarietàsling:resourceSuperTypedel componenteCard.code language-java @Override public String getSrc() { return null != image ? image.getSrc() : null; }È quindi possibile utilizzare semplicemente l'oggetto
imageper 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 privatacardPagein base al valore dicardPathcode 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 AEM Page 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
@ValueMapValueviene 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
coreutilizzando il profilo MavenautoInstallBundledalla directorycore.code language-shell $ cd core/ $ mvn clean install -PautoInstallBundleSe 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.tsalleui.frontend/src/app/components/card/card.component.ts. Aggiungi ulteriori@Inputannotazioni 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 Call to action è pronto e per restituire una stringa 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.htmle aggiungi il seguente markup per visualizzare il titolo, il call to action 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.scssper assegnare uno stile al titolo, al call to action e alla data dell'ultima modifica.note note NOTE Puoi visualizzare il codice del componente Angular Card completato qui. -
Implementa le modifiche complete ad 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.