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
Rivedi 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 estrarlo 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.Many development teams strive to be D.R.Y. (don't repeat yourself). Sling inheritance makes this possible with AEM.
-
Beneath the
cardfolder, open the file_cq_dialog/.content.xml.This file is the Component Dialog definition for the
Cardcomponent. If using Sling inheritance, it is possible to use features of the Sling Resource Merger to override or extend portions of the dialog. In this sample, a new tab has been added to the dialog to capture additional data from an author to populate the Card Component.Properties like
sling:orderBeforeallow a developer to choose where to insert new tabs or form fields. In this case, theTexttab is inserted before theassettab. To make full use of the Sling Resource Merger, it is important to know the original dialog node structure for the Image component dialog. -
Beneath the
cardfolder, open the file_cq_editConfig.xml. This file dictates the drag and drop behavior in the AEM authoring UI. When extending the Image component, it is important that the resource type matches the component itself. Review the<parameters>node:code language-xml <parameters jcr:primaryType="nt:unstructured" sling:resourceType="wknd-spa-angular/components/card" imageCrop="" imageMap="" imageRotate=""/>Most components do not require a
cq:editConfig, the Image, and child descendents of the Image component are exceptions. -
In the IDE switch to the
ui.frontendmodule, navigating toui.frontend/src/app/components/card:
-
Ispeziona il file
card.component.ts.The component has already been stubbed out to map to the AEM
CardComponent using the standardMapTofunction.code language-js MapTo('wknd-spa-angular/components/card')(CardComponent, CardEditConfig);Review the three
@Inputparameters in the class forsrc,alt, andtitle. These are expected JSON values from the AEM component that are mapped to the Angular component. -
Open the 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 this example we chose to reuse the existing Angular Image component
app-imageby simply passing the@Inputparameters fromcard.component.ts. Later in the tutorial, additional properties are added and displayed.
Aggiornare il criterio del modello
With this initial Card implementation review the functionality in the AEM SPA Editor. To see the initial Card component an update to the Template policy is needed.
-
Deploy the starter code to a local instance of AEM, if you haven't already:
code language-shell $ cd aem-guides-wknd-spa $ mvn clean install -PautoInstallSinglePackage -
Passa al modello pagina SPA all'indirizzo http://localhost:4502/editor.html/conf/wknd-spa-angular/settings/wcm/templates/spa-page-template/structure.html.
-
Update the Layout Container's policy to add the new
Cardcomponent as an allowed component:
Save the changes to the policy, and observe the
Cardcomponent as an allowed component:
Author initial Card component
Next, author the Card component using the AEM SPA Editor.
-
Passa a http://localhost:4502/editor.html/content/wknd-spa-angular/us/en/home.html.
-
In
Editmode, add theCardcomponent to theLayout Container:
-
Drag and drop an image from the Asset finder onto the
Cardcomponent:
-
Open the
Cardcomponent dialog and notice the addition of a Text Tab. -
Enter the following values on the Text tab:
Card Path - choose a page beneath the SPA homepage.
CTA Text - "Read More"
Card Title - leave blank
Get title from linked page - check the checkbox to indicate true.
-
Update the Asset Metadata tab to add values for Alternative Text and Caption.
Currently no additional changes appear after updating the dialog. To expose the new fields to the Angular Component, we need to update the Sling Model for the
Cardcomponent. -
Open a new tab and navigate to CRXDE-Lite. Inspect the content nodes beneath
/content/wknd-spa-angular/us/en/home/jcr:content/root/responsivegridto find theCardcomponent content.
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 estrarlo localmente passando al ramo Angular/extend-component-solution.