Il seguente tutorial illustra i passaggi necessari per creare un componente personalizzato per AEM Screens. AEM Screens riutilizza molti modelli di progettazione e tecnologie esistenti di altri prodotti AEM. Il tutorial evidenzia differenze e considerazioni speciali durante lo sviluppo per AEM Screens.
Questo tutorial è destinato agli sviluppatori che hanno poca esperienza con AEM Screens. In questo tutorial viene creato un semplice componente "Hello World" per un canale Sequence in AEM Screens. Una finestra di dialogo consente agli autori di aggiornare il testo visualizzato.
Per completare questa esercitazione, è necessario quanto segue:
Pacchetto di funzioni per gli schermi più recenti
Lettore AEM Screens
Ambiente di sviluppo locale
I passaggi del tutorial e le schermate vengono eseguiti utilizzando CRXDE-Lite. È inoltre possibile utilizzare gli IDE per completare l'esercitazione. Ulteriori informazioni sull'utilizzo di un IDE per sviluppare con AEM si trova qui.
Il codice sorgente di un progetto Screens viene in genere gestito come progetto Maven con più moduli. Per accelerare l’esercitazione, un progetto è stato pregenerato utilizzando Archetipo progetto AEM 13. Ulteriori dettagli su creazione di un progetto con Archetipo progetto AEM Maven disponibile qui.
Ottieni file
Facoltativamente se lavori con Eclipse o un altro IDE, scarica il pacchetto sorgente seguente. Distribuisci il progetto in un’istanza AEM locale utilizzando il comando Maven:
mvn -PautoInstallPackage clean install
Avvia il progetto di esecuzione We.Retail di HelloWorld SRC Screens
In entrata Gestione pacchetti CRX verifica che siano installati i due pacchetti seguenti:
Screens Esecuzione di pacchetti Ui.Apps e Ui.Content tramite CRX Package Manager
Il screens-weretail-run.ui.apps il pacchetto installa il codice sotto a /apps/weretail-run
.
Questo pacchetto contiene il codice responsabile del rendering dei componenti personalizzati per il progetto. Questo pacchetto include il codice del componente ed eventuali codici JavaScript o CSS necessari. Questo pacchetto incorpora anche screens-weretail-run.core-0.0.1-SNAPSHOT.jar che contiene il codice Java necessario per il progetto.
In questa esercitazione non viene scritto alcun codice Java. Se è necessaria una logica di business più complessa, è possibile creare e distribuire Java di back-end utilizzando il bundle Java di base.
Rappresentazione del codice ui.apps in CRXDE Lite
Il helloworld Il componente è attualmente solo un segnaposto. Nel corso dell’esercitazione, verrà aggiunta una funzionalità che consente all’autore di aggiornare il messaggio visualizzato dal componente.
Il screens-weretail-run.ui.content il pacchetto installa il codice sotto:
/conf/we-retail-run
/content/dam/we-retail-run
/content/screens/we-retail-run
Questo pacchetto contiene il contenuto iniziale e la struttura di configurazione necessaria per il progetto. /conf/we-retail-run
contiene tutte le configurazioni per il progetto di esecuzione We.Retail. /content/dam/we-retail-run
include l’avvio delle risorse digitali per il progetto. /content/screens/we-retail-run
contiene la struttura del contenuto Screens. Il contenuto sotto tutti questi percorsi viene aggiornato principalmente in AEM. Per promuovere la coerenza tra gli ambienti (locale, di sviluppo, di staging, di produzione) spesso nel controllo del codice sorgente viene salvata una struttura di contenuto di base.
Passa al progetto AEM Screens > Esecuzione We.Retail:
Dal menu Start dell’AEM > fai clic sull’icona Schermi. Verifica che sia visibile il progetto di esecuzione We.Retail.
Il componente Hello World è un componente semplice che consente a un utente di inserire un messaggio da visualizzare sullo schermo. Il componente è basato su Modello del componente AEM Screens: https://github.com/Adobe-Marketing-Cloud/aem-screens-component-template.
AEM Screens presenta alcuni vincoli interessanti che non sono necessariamente validi per i componenti WCM Sites tradizionali.
In entrata CRXDE-Lite http://localhost:4502/crx/de/index.jsp
(o IDE scelto) Accedi a /apps/weretail-run/components/content/helloworld.
Aggiungi le seguenti proprietà alla helloworld
componente:
jcr:title="Hello World"
sling:resourceSuperType="foundation/components/parbase"
componentGroup="We.Retail Run - Content"
Proprietà per /apps/weretail-run/components/content/helloworld
Il helloworld il componente estende foundation/components/parbase in modo che possa essere utilizzato correttamente all'interno di un canale di sequenza.
Crea un file sotto /apps/weretail-run/components/content/helloworld
denominato helloworld.html.
Compila il file con quanto segue:
<!--/*
/apps/weretail-run/components/content/helloworld/helloworld.html
*/-->
<!--/* production: preview authoring mode + unspecified mode (i.e. on publish) */-->
<sly data-sly-test.production="${wcmmode.preview || wcmmode.disabled}" data-sly-include="production.html" />
<!--/* edit: any other authoring mode, i.e. edit, design, scaffolding, etc. */-->
<sly data-sly-test="${!production}" data-sly-include="edit.html" />
I componenti Screens richiedono due rendering diversi a seconda di quale modalità di authoring è in uso:
helloworld.html
funge da switch, controllando quale modalità di authoring è attualmente attiva e reindirizzando a un altro script HTL. Una convenzione comune utilizzata dai componenti Screens consiste nell’avere edit.html
script per la modalità di modifica e un production.html
script per la modalità di produzione.
Crea un file sotto /apps/weretail-run/components/content/helloworld
denominato production.html.
Compila il file con quanto segue:
<!--/*
/apps/weretail-run/components/content/helloworld/production.html
*/-->
<div data-duration="${properties.duration}" class="cmp-hello-world">
<h1 class="cmp-hello-world__message">${properties.message}</h1>
</div>
Di seguito è riportato il markup di produzione per il componente Hello World. A data-duration
Questo attributo è incluso poiché il componente viene utilizzato su un canale Sequenza. Il data-duration
L'attributo viene utilizzato dal canale della sequenza per sapere per quanto tempo deve essere visualizzato un elemento della sequenza.
Il componente genera un div
e un h1
con testo. ${properties.message}
è una porzione dello script HTL che restituisce il contenuto di una proprietà JCR denominata message
. Successivamente viene creata una finestra di dialogo che consente all’utente di immettere un valore per message
testo della proprietà.
Si noti inoltre che con il componente viene utilizzata la notazione BEM (Block Element Modifier). BEM è una convenzione di codifica CSS che semplifica la creazione di componenti riutilizzabili. BEM è la notazione utilizzata da Componenti core AEM.
Crea un file sotto /apps/weretail-run/components/content/helloworld
denominato edit.html.
Compila il file con quanto segue:
<!--/*
/apps/weretail-run/components/content/helloworld/edit.html
*/-->
<!--/* if message populated */-->
<div
data-sly-test.message="${properties.message}"
class="aem-Screens-editWrapper cmp-hello-world">
<p class="cmp-hello-world__message">${message}</p>
</div>
<!--/* empty place holder */-->
<div data-sly-test="${!message}"
class="aem-Screens-editWrapper cq-placeholder cmp-hello-world"
data-emptytext="${'Hello World' @ i18n, locale=request.locale}">
</div>
Di seguito è riportato il markup di modifica per il componente Hello World. Nel primo blocco viene visualizzata una versione di modifica del componente, se il messaggio della finestra di dialogo è stato popolato.
Se non è stato immesso alcun messaggio di dialogo, viene eseguito il rendering del secondo blocco. Il cq-placeholder
e data-emptytext
eseguire il rendering dell’etichetta Hello World come detentore del luogo in tale caso. La stringa per l’etichetta può essere internazionalizzata utilizzando i18n per supportare l’authoring in più lingue.
Finestra di dialogo Copia immagine di Screens da utilizzare per il componente Hello World.
È più semplice iniziare da una finestra di dialogo esistente e quindi apportare modifiche.
/libs/screens/core/components/content/image/cq:dialog
/apps/weretail-run/components/content/helloworld
Aggiorna la finestra di dialogo Hello World per includere una scheda per il messaggio.
Aggiorna la finestra di dialogo in modo che corrisponda a quanto segue. La struttura dei nodi JCR della finestra di dialogo finale è presentata di seguito in XML:
<?xml version="1.0" encoding="UTF-8"?>
<jcr:root xmlns:sling="https://sling.apache.org/jcr/sling/1.0" xmlns:cq="https://www.day.com/jcr/cq/1.0" xmlns:jcr="https://www.jcp.org/jcr/1.0" xmlns:nt="https://www.jcp.org/jcr/nt/1.0"
jcr:primaryType="nt:unstructured"
jcr:title="Hello World"
sling:resourceType="cq/gui/components/authoring/dialog">
<content
jcr:primaryType="nt:unstructured"
sling:resourceType="granite/ui/components/coral/foundation/tabs"
size="L">
<items jcr:primaryType="nt:unstructured">
<message
jcr:primaryType="nt:unstructured"
jcr:title="Message"
sling:resourceType="granite/ui/components/coral/foundation/fixedcolumns">
<items jcr:primaryType="nt:unstructured">
<column
jcr:primaryType="nt:unstructured"
sling:resourceType="granite/ui/components/coral/foundation/container">
<items jcr:primaryType="nt:unstructured">
<message
jcr:primaryType="nt:unstructured"
sling:resourceType="granite/ui/components/coral/foundation/form/textfield"
fieldDescription="Message for component to display"
fieldLabel="Message"
name="./message"/>
</items>
</column>
</items>
</message>
<sequence
jcr:primaryType="nt:unstructured"
jcr:title="Sequence"
sling:resourceType="granite/ui/components/coral/foundation/fixedcolumns">
<items jcr:primaryType="nt:unstructured">
<column
jcr:primaryType="nt:unstructured"
sling:resourceType="granite/ui/components/coral/foundation/container">
<items jcr:primaryType="nt:unstructured">
<duration
jcr:primaryType="nt:unstructured"
sling:resourceType="granite/ui/components/coral/foundation/form/numberfield"
defaultValue=""
fieldDescription="Amount of time the image will be shown in the sequence, in milliseconds"
fieldLabel="Duration (ms)"
min="0"
name="./duration"/>
</items>
</column>
</items>
</sequence>
</items>
</content>
</jcr:root>
Il campo di testo per il messaggio verrà salvato in una proprietà denominata message
e che il campo numerico per la Durata venga salvato in una proprietà denominata duration
. Entrambe queste proprietà sono indicate in /apps/weretail-run/components/content/helloworld/production.html
da HTL come ${properties.message}
e ${properties.duration}
.
Hello World - finestra di dialogo completata
Le librerie lato client forniscono un meccanismo per organizzare e gestire i file CSS e JavaScript necessari per un’implementazione AEM.
Il rendering dei componenti di AEM Screens varia in modalità Modifica rispetto alla modalità Anteprima/Produzione. Verranno create due librerie client, una per la modalità di modifica e una per l’anteprima/produzione.
Crea una cartella per le librerie lato client per il componente Hello World.
Sotto /apps/weretail-run/components/content/helloworld
crea una nuova cartella denominata clientlibs
.
Sotto clientlibs
cartella crea un nuovo nodo denominato shared
di tipo cq:ClientLibraryFolder.
Aggiungi le seguenti proprietà alla libreria client condivisa:
allowProxy
| Booleano | true
categories
| Stringa[] | cq.screens.components
Proprietà per /apps/weretail-run/components/content/helloworld/clientlibs/shared
La proprietà Categories è una stringa che identifica la libreria client. La categoria cq.screens.component viene utilizzata sia in modalità Modifica che Anteprima/Produzione. Di conseguenza, qualsiasi CSS/JS definito nella libreria client condivisa viene caricato in tutte le modalità.
È consigliabile non esporre mai percorsi direttamente a /apps in un ambiente di produzione. La proprietà allowProxy garantisce che venga fatto riferimento alle librerie client CSS e JS tramite un prefisso of/etc.clientlibs.
Crea file denominato css.txt
sotto la cartella condivisa.
Compila il file con quanto segue:
#base=css
styles.less
Crea una cartella denominata css
sotto shared
cartella. Aggiungi un file denominato style.less
sotto css
cartella. La struttura delle librerie client ora dovrebbe essere simile alla seguente:
Invece di scrivere direttamente CSS, questa esercitazione utilizza MENO. MENO è un popolare precompilatore CSS che supporta variabili, mixin e funzioni CSS. Le librerie client AEM supportano in modo nativo la compilazione LESS. È possibile utilizzare Sass o altri precompilatori, che tuttavia devono essere compilati al di fuori dell’AEM.
Popolare /apps/weretail-run/components/content/helloworld/clientlibs/shared/css/styles.less
con le seguenti caratteristiche:
/**
Shared Styles
/apps/weretail-run/components/content/helloworld/clientlibs/shared/css/styles.less
**/
.cmp-hello-world {
background-color: #fff;
&__message {
color: #000;
font-family: Helvetica;
text-align:center;
}
}
Copiare e incollare shared
cartella della libreria client per creare una nuova libreria client denominata production
.
Copiare la libreria client condivisa per creare una nuova libreria client di produzione
Aggiornare il categories
proprietà della libreria client di produzione da cq.screens.components.production.
In questo modo gli stili vengono caricati solo in modalità Anteprima/Produzione.
Proprietà per /apps/weretail-run/components/content/helloworld/clientlibs/production
Popolare /apps/weretail-run/components/content/helloworld/clientlibs/production/css/styles.less
con le seguenti caratteristiche:
/**
Production Styles
/apps/weretail-run/components/content/helloworld/clientlibs/production/css/styles.less
**/
.cmp-hello-world {
height: 100%;
width: 100%;
position: fixed;
&__message {
position: relative;
font-size: 5rem;
top:25%;
}
}
Gli stili di cui sopra visualizzano il messaggio centrato al centro dello schermo, ma solo in modalità di produzione.
Una terza categoria di librerie client: cq.screens.components.edit
può essere utilizzato per aggiungere al componente stili specifici per la sola modifica.
Categoria Clientlib | Utilizzo |
---|---|
cq.screens.components |
Stili e script condivisi tra le modalità di modifica e di produzione |
cq.screens.components.edit |
Stili e script utilizzati solo in modalità di modifica |
cq.screens.components.production |
Stili e script utilizzati solo in modalità di produzione |
AEM Screens utilizza Modelli di pagina statici e Configurazioni di progettazione per le modifiche globali. Le configurazioni di progettazione vengono spesso utilizzate per configurare i componenti consentiti per Parsys su un canale. Una best practice consiste nell’archiviare queste configurazioni in un modo specifico per l’app.
Sotto viene creata una pagina Progettazione esecuzione We.Retail in cui vengono memorizzate tutte le configurazioni specifiche del progetto Esecuzione We.Retail.
In entrata CRXDE-Lite http://localhost:4502/crx/de/index.jsp#/apps/settings/wcm/designs
passa a /apps/settings/wcm/designs
Crea un nuovo nodo sotto la cartella delle progettazioni, denominato we-retail-run
con un tipo di cq:Page
.
Sotto we-retail-run
, aggiungere un altro nodo denominato jcr:content
di tipo nt:unstructured
. Aggiungi le seguenti proprietà alla jcr:content
nodo:
Nome | Tipo | Valore |
---|---|---|
jcr:title | Stringa | Esecuzione We.Retail |
sling:resourceType | Stringa | wcm/core/components/designer |
cq:doctype | Stringa | html_5 |
Pagina di progettazione in /apps/settings/wcm/designs/we-retail-run
Il componente Hello World deve essere utilizzato su un canale di sequenza. Per testare il componente, viene creato un nuovo canale di sequenza.
Dal menu Start dell’AEM, vai a Schermi > Ru We.Retail n > e seleziona Canali.
Fai clic su Crea pulsante
Nella procedura guidata Crea:
Passaggio modello - scegli Canale sequenza
Apri le proprietà della pagina per il canale inattivo. Aggiorna il campo Progettazione in modo che punti a /apps/settings/wcm/designs/we-retail-run,
la pagina di progettazione creata nella sezione precedente.
Configurazione di progettazione che punta a /apps/settings/wcm/designs/we-retail-run
Modifica il canale inattivo appena creato per aprirlo.
Passa alla modalità pagina Progettazione Modalità
Fai clic su chiave inglese Icona in Parsys per configurare i componenti consentiti
Seleziona la Schermi gruppo e Esecuzione We.Retail - Contenuto gruppo.
Passa alla modalità pagina Modifica. Il componente Hello World può ora essere aggiunto alla pagina e combinato con altri componenti del canale di sequenza.
In entrata CRXDE-Lite http://localhost:4502/crx/de/index.jsp#/apps/settings/wcm/designs/we-retail-run/jcr%3Acontent/sequencechannel/par
passa a /apps/settings/wcm/designs/we-retail-run/jcr:content/sequencechannel/par
. Osserva components
La proprietà ora include group:Screens
, group:We.Retail Run - Content
.
Configurazione del progetto in /apps/settings/wcm/designs/we-retail-run
Se il componente personalizzato utilizza risorse esterne come risorse (immagini, video, font, icone, ecc.), rappresentazioni di risorse specifiche o librerie lato client (css, js, ecc.), queste non vengono aggiunte automaticamente alla configurazione offline in quanto per impostazione predefinita il markup HTML viene raggruppato solo.
Per personalizzare e ottimizzare le risorse esatte scaricate sul lettore, offriamo un meccanismo di estensione per i componenti personalizzati che consente di esporre le loro dipendenze alla logica di caching offline in Screens.
La sezione seguente presenta il modello per i gestori di risorse offline personalizzati e i requisiti minimi in pom.xml
per quel progetto specifico.
package …;
import javax.annotation.Nonnull;
import org.apache.felix.scr.annotations.Component;
import org.apache.felix.scr.annotations.Reference;
import org.apache.felix.scr.annotations.Service;
import org.apache.sling.api.resource.Resource;
import org.apache.sling.api.resource.ResourceUtil;
import org.apache.sling.api.resource.ValueMap;
import com.adobe.cq.screens.visitor.OfflineResourceHandler;
@Service(value = OfflineResourceHandler.class)
@Component(immediate = true)
public class MyCustomHandler extends AbstractResourceHandler {
@Reference
private …; // OSGi services injection
/**
* The resource types that are handled by the handler.
* @return the handled resource types
*/
@Nonnull
@Override
public String[] getSupportedResourceTypes() {
return new String[] { … };
}
/**
* Accept the provided resource, visit and traverse it as needed.
* @param resource The resource to accept
*/
@Override
public void accept(@Nonnull Resource resource) {
ValueMap properties = ResourceUtil.getValueMap(resource);
/* You can directly add explicit paths for offline caching using the `visit`
method of the visitor. */
// retrieve a custom property from the component
String myCustomRenditionUrl = properties.get("myCustomRenditionUrl", String.class);
// adding that exact asset/rendition/path to the offline manifest
this.visitor.visit(myCustomRenditionUrl);
/* You can delegate handling for dependent resources so they are also added to
the offline cache using the `accept` method of the visitor. */
// retrieve a referenced dependent resource
String referencedResourcePath = properties.get("myOtherResource", String.class);
ResourceResolver resolver = resource.getResourceResolver();
Resource referencedResource = resolver.getResource(referencedResourcePath);
// let the handler for that resource handle it
if (referencedResource != null) {
this.visitor.accept(referencedResource);
}
}
}
Il codice che segue riporta i requisiti minimi di pom.xml
per quel progetto specifico:
<dependencies>
…
<!-- Felix annotations -->
<dependency>
<groupId>org.apache.felix</groupId>
<artifactId>org.apache.felix.scr.annotations</artifactId>
<version>1.9.0</version>
<scope>provided</scope>
</dependency>
<!-- Screens core bundle with OfflineResourceHandler/AbstractResourceHandler -->
<dependency>
<groupId>com.adobe.cq.screens</groupId>
<artifactId>com.adobe.cq.screens</artifactId>
<version>1.5.90</version>
<scope>provided</scope>
</dependency>
…
</dependencies>
Il video seguente mostra il componente finito e come può essere aggiunto a un canale Sequenza. Il canale viene quindi aggiunto a una visualizzazione Posizione e infine assegnato a un lettore Screens.
Di seguito è riportato il codice finito dell'esercitazione. Il screens-weretail-run.ui.apps-0.0.1-SNAPSHOT.zip e screens-weretail-run.ui.content-0.0.1-SNAPSHOT.zip sono i pacchetti AEM compilati. SRC-screens-weretail-run-0.0.1.zip è il codice sorgente non compilato che può essere distribuito utilizzando Maven.