Scopri come estendere un componente core esistente da utilizzare con l’editor di SPA AEM. Scopri come estendere un componente esistente è una tecnica potente per personalizzare ed espandere le funzionalità di un’implementazione di AEM Editor .
sling:resourceSuperType
.In questo capitolo, un nuovo Card
viene creato. La Card
estensione del componente Componente core immagine aggiunta di campi di contenuto aggiuntivi come un titolo e un pulsante Invito all’azione per eseguire il ruolo di un teaser per altri contenuti all’interno dell’SPA.
In un'implementazione reale, può essere più appropriato utilizzare semplicemente il Componente teaser che estendano Componente core immagine per creare un Card
a seconda dei requisiti del progetto. Si consiglia sempre di utilizzare Componenti core direttamente quando possibile.
Rivedere gli strumenti e le istruzioni necessari per la configurazione di un ambiente di sviluppo locale.
Scarica il punto di partenza per questa esercitazione tramite Git:
$ 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:
$ mvn clean install -PautoInstallSinglePackage
Se utilizzi AEM 6.x aggiungi le classic
profilo:
$ mvn clean install -PautoInstallSinglePackage -Pclassic
Installa il pacchetto finito per il tradizionale Sito di riferimento WKND. Le immagini fornite da Sito di riferimento WKND viene riutilizzato nel SPA WKND. Il pacchetto può essere installato utilizzando Gestione pacchetti AEM.
Puoi sempre visualizzare il codice finito su GitHub o controlla il codice localmente passando al ramo Angular/extend-component-solution
.
Il codice iniziale del capitolo fornisce un componente scheda iniziale. Inspect è il punto di partenza per l’implementazione di Card.
Nell’IDE che preferisci, apri le ui.apps
modulo .
Passa a ui.apps/src/main/content/jcr_root/apps/wknd-spa-angular/components/card
e visualizza .content.xml
file.
<?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
punti wknd-spa-angular/components/image
che indicano che Card
eredita la funzionalità dal componente Immagine SPA WKND.
Inspect il file 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"/>
Tieni presente che sling:resourceSuperType
punti core/wcm/components/image/v2/image
. Questo indica che il componente Immagine SPA WKND eredita la funzionalità dall’immagine del componente core.
Noto anche come Pattern proxy L’ereditarietà di risorse Sling è un potente pattern di progettazione che consente ai componenti secondari di ereditare funzionalità ed estendere/sovrascrivere il comportamento quando desiderato. L’ereditarietà Sling supporta più livelli di ereditarietà, quindi in ultima analisi la nuova Card
Il componente eredita la funzionalità dell’immagine del componente core.
Molti team di sviluppo si sforzano di essere D.R.Y. (non ripetersi). L’ereditarietà Sling lo rende possibile con AEM.
Sotto card
cartella, apri il file _cq_dialog/.content.xml
.
Questo file è la definizione della finestra di dialogo del componente per Card
componente. Se utilizzi l’ereditarietà Sling, è possibile utilizzare le funzioni 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 compilare il componente Scheda.
Proprietà simili sling:orderBefore
consentire agli sviluppatori di scegliere dove inserire nuove schede o campi modulo. In questo caso, il Text
viene inserita prima della asset
scheda . Per sfruttare appieno lo Sling Resource Merger, è importante conoscere la struttura del nodo di dialogo originale per il Finestra di dialogo del componente immagine.
Sotto card
cartella, apri il file _cq_editConfig.xml
. Questo file determina il comportamento di trascinamento nell’interfaccia utente di AEM authoring. Quando estendi il componente Immagine, è importante che il tipo di risorsa corrisponda al componente stesso. Consulta la sezione <parameters>
nodo:
<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
, i discendenti immagine e figlio del componente Immagine sono eccezioni.
Nello switch IDE al ui.frontend
modulo, passaggio a ui.frontend/src/app/components/card
:
Inspect il file card.component.ts
.
Il componente è già stato bloccato per la mappatura sul AEM Card
Componente che utilizza lo standard MapTo
funzione .
MapTo('wknd-spa-angular/components/card')(CardComponent, CardEditConfig);
Rivedi i tre @Input
nella classe per src
, alt
e title
. Questi sono valori JSON attesi dal componente AEM mappato al componente Angular.
Aprire il file card.component.html
:
<div class="card" *ngIf="hasContent">
<app-image class="card__image" [src]="src" [alt]="alt" [title]="title"></app-image>
</div>
In questo esempio abbiamo scelto di riutilizzare il componente Immagine Angular esistente app-image
semplicemente passando @Input
parametri da card.component.ts
. Successivamente nell’esercitazione, vengono aggiunte e visualizzate ulteriori proprietà.
Con questa iniziale Card
implementazione esamina la funzionalità nell’editor di SPA AEM. Per visualizzare il Card
È necessario un aggiornamento del criterio del modello.
Distribuisci il codice iniziale in un'istanza locale di AEM, se non lo hai già fatto:
$ cd aem-guides-wknd-spa
$ mvn clean install -PautoInstallSinglePackage
Passa al modello di pagina SPA in http://localhost:4502/editor.html/conf/wknd-spa-angular/settings/wcm/templates/spa-page-template/structure.html.
Aggiornare i criteri del Contenitore di layout per aggiungere il nuovo Card
come componente consentito:
Salva le modifiche al criterio e osserva il Card
come componente consentito:
Quindi, crea le Card
mediante l’editor SPA AEM.
Passa a http://localhost:4502/editor.html/content/wknd-spa-angular/us/en/home.html.
In Edit
aggiungi la Card
nella Layout Container
:
Trascina e rilascia un’immagine da Asset Finder nella Card
componente:
Apri Card
finestra di dialogo dei componenti e notare l’aggiunta di un Testo Tab.
Immetti i seguenti valori nel Testo scheda:
Percorso scheda - scegli una pagina sotto la home page di SPA.
Testo CTA - "Ulteriori informazioni"
Titolo della scheda - lasciare vuoto
Ottieni titolo dalla pagina collegata - seleziona la casella di controllo per indicare true.
Aggiorna Metadati risorsa scheda 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 Card
componente.
Apri una nuova scheda e passa a CRXDE-Lite. Inspect i nodi di contenuto sotto /content/wknd-spa-angular/us/en/home/jcr:content/root/responsivegrid
per trovare Card
contenuto componente.
Osserva che le proprietà cardPath
, ctaText
, titleFromPage
vengono mantenuti dalla finestra di dialogo.
Per esporre in ultima analisi i valori dalla finestra di dialogo del componente al componente Angular, è necessario aggiornare il modello Sling che popola il JSON per il Card
componente. Abbiamo anche l'opportunità di implementare due elementi di logica di business:
titleFromPage
a true, restituisce il titolo della pagina specificata da cardPath
altrimenti restituisce il valore di cardTitle
campo di testo.cardPath
.Torna all’IDE che preferisci e apri la core
modulo .
Apri il file . Card.java
a core/src/main/java/com/adobe/aem/guides/wknd/spa/angular/core/models/Card.java
.
Osserva che il Card
interfaccia attualmente estesa com.adobe.cq.wcm.core.components.models.Image
e pertanto eredita i metodi Image
interfaccia. La Image
l'interfaccia estende già ComponentExporter
Interfaccia che consente l’esportazione del modello Sling come JSON e mappato dall’editor SPA. Pertanto non è necessario estendere esplicitamente ComponentExporter
interfaccia come quella di Capitolo Componente personalizzato.
Aggiungi i seguenti metodi all’interfaccia:
@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
. Questa è l'attuazione Card.java
interfaccia. Questa implementazione è stata parzialmente bloccata per accelerare l’esercitazione. Osserva l'uso @Model
e @Exporter
annotazioni per garantire che il modello Sling possa essere serializzato come JSON tramite l’esportazione di modelli Sling.
CardImpl.java
utilizza anche Pattern di delega per modelli Sling per evitare di riscrivere la logica dal componente di base Immagine .
Osserva le seguenti righe:
@Self
@Via(type = ResourceSuperType.class)
private Image image;
L’annotazione sopra crea un’istanza di un oggetto Immagine denominato image
in base ai sling:resourceSuperType
eredità del Card
componente.
@Override
public String getSrc() {
return null != image ? image.getSrc() : null;
}
È quindi possibile utilizzare semplicemente il image
oggetto per implementare i metodi definiti dal Image
interfaccia, senza dover scrivere noi stessi la logica. Questa tecnica viene utilizzata per getSrc()
, getAlt()
e getTitle()
.
Quindi, implementa initModel()
metodo per avviare una variabile privata cardPage
in base al valore di cardPath
@PostConstruct
public void initModel() {
if(StringUtils.isNotBlank(cardPath) && pageManager != null) {
cardPage = pageManager.getPage(this.cardPath);
}
}
La @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. La pageManager
è uno dei diversi Oggetti globali supportati da Java™ messi a disposizione di Sling Models tramite @ScriptVariable
annotazione. La getPage prende un percorso e restituisce un AEM Pagina oggetto o nullo se il percorso non punta a una pagina valida.
Inizializza il cardPage
, che viene utilizzata dagli altri metodi per restituire dati sulla pagina collegata sottostante.
Esamina le variabili globali già mappate alle proprietà JCR salvate nella finestra di dialogo dell’autore. La @ValueMapValue
viene utilizzata per eseguire automaticamente la mappatura.
@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 Card.java
interfaccia.
Implementa i metodi aggiuntivi definiti nella Card.java
interfaccia:
@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;
}
È possibile visualizzare Ho finito CardImpl.java qui.
Apri una finestra terminale e distribuisci solo gli aggiornamenti della core
modulo che utilizza Maven autoInstallBundle
dal profilo core
directory.
$ cd core/
$ mvn clean install -PautoInstallBundle
Se utilizzi AEM 6.x aggiungi le classic
profilo.
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
:
"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 coppie chiave/valore aggiuntive dopo l’aggiornamento dei metodi in CardImpl
Modello Sling.
Ora che il modello JSON è popolato con nuove proprietà per ctaLinkURL
, ctaText
, cardTitle
e cardLastModified
possiamo aggiornare il componente Angular per visualizzarli.
Torna all’IDE e apri la ui.frontend
modulo . Facoltativamente, avviare il server webpack dev da una nuova finestra terminale per visualizzare le modifiche in tempo reale:
$ cd ui.frontend
$ npm install
$ npm start
Apri card.component.ts
a ui.frontend/src/app/components/card/card.component.ts
. Aggiungi il @Input
annotazioni per acquisire il nuovo modello:
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;
Aggiungi i metodi per verificare se l’invito all’azione è pronto e per restituire una stringa di data/ora basata su cardLastModified
input:
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 l’ultima data di modifica:
<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 in card.component.scss
per assegnare uno stile al titolo, invoca l’azione e l’ultima data di modifica.
È possibile visualizzare il completamento Angular il codice del componente della scheda qui.
Distribuisci le modifiche complete da AEM dalla radice del progetto utilizzando Maven:
$ 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:
Per creare una pagina simile alla seguente, dovresti essere in grado di ricreare il contenuto esistente:
Congratulazioni, hai imparato a estendere un componente AEM e come modelli e finestre di dialogo Sling funzionano con il modello JSON.
Puoi sempre visualizzare il codice finito su GitHub o controlla il codice localmente passando al ramo Angular/extend-component-solution
.