Sviluppo di un componente personalizzato per AEM Screens as a Cloud Service developing-a-custom-component-for-aem-screens
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.
Panoramica overview
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.
Prerequisiti prerequisites
Per completare questa esercitazione, sono necessari i seguenti elementi:
-
Feature Pack di Screens più recente
-
Lettore AEM Screens
-
Ambiente di sviluppo locale
I passaggi dell'esercitazione e le schermate vengono eseguiti utilizzando CRXDE Liti. È inoltre possibile utilizzare gli IDE per completare l'esercitazione. Ulteriori informazioni sull'utilizzo di un IDE per sviluppare con AEM sono disponibili qui.
Configurazione del progetto project-setup
Il codice sorgente di un progetto Screens viene in genere gestito come progetto Maven con più moduli. Per accelerare l'esercitazione, è stato pregenerato un progetto utilizzando AEM Project Archetype 13. Ulteriori dettagli sulla creazione di un progetto con Archetipo progetto AEM Maven sono disponibili qui.
- Scarica e installa i seguenti pacchetti utilizzando Gestione pacchetti CRX:
Ottieni file
Facoltativamente se si lavora con Eclipse o un altro IDE, scaricare il pacchetto di origine seguente. Distribuisci il progetto in un’istanza AEM locale utilizzando il comando Maven:
mvn -PautoInstallPackage clean install
Avvia progetto di esecuzione We.Retail di HelloWorld SRC Screens
-
In Gestione pacchetti CRX, verificare che siano installati i due pacchetti seguenti:
- screens-weretail-run.ui.content-0.0.1-SNAPSHOT.zip
- screens-weretail-run.ui.apps-0.0.1-SNAPSHOT.zip
Screens We.Retail Esegui pacchetti Ui.Apps e Ui.Content installati tramite CRX Package Manager
-
Il pacchetto screens-weretail-run.ui.apps installa il codice sotto
/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 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.
note note NOTE 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 componente
helloworld
è solo un segnaposto. Nel corso dell’esercitazione, viene aggiunta una funzionalità che consente all’autore di aggiornare il messaggio visualizzato dal componente. -
Il pacchetto screens-weretail-run.ui.content 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 di Screens. Il contenuto sotto 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 del Screens. Verifica che sia visibile il progetto di esecuzione We.Retail.
Creare il componente Hello World hello-world-cmp
Il componente Hello World è un componente semplice che consente a un utente di inserire un messaggio da visualizzare sullo schermo. Il componente è basato sul modello di 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.
- La maggior parte dei componenti Screens deve essere eseguita a schermo intero sui dispositivi di digital signage di destinazione
- La maggior parte dei componenti Screens deve essere incorporata nei canali di sequenza per generare presentazioni
- L’authoring deve consentire di modificare singoli componenti in un canale di sequenza, pertanto il loro rendering a schermo intero non è necessario
-
In CRXDE-Lite
http://localhost:4502/crx/de/index.jsp
(o IDE scelto), passa a/apps/weretail-run/components/content/helloworld.
Aggiungi le seguenti proprietà al componente
helloworld
:code language-none jcr:title="Hello World" sling:resourceSuperType="foundation/components/parbase" componentGroup="We.Retail Run - Content"
Proprietà per /apps/weretail-run/components/content/helloworld
Il componente
helloworld
estende il componente foundation/components/parbase in modo che possa essere utilizzato correttamente in un canale di sequenza. -
Crea un file sotto
/apps/weretail-run/components/content/helloworld
denominatohelloworld.html.
Compila il file con quanto segue:
code language-xml <!--/* /apps/weretail-run/components/content/helloworld/helloworld.html */--> <!--/* production: preview authoring mode + unspecified mode (that is, on publish) */--> <sly data-sly-test.production="${wcmmode.preview || wcmmode.disabled}" data-sly-include="production.html" /> <!--/* edit: any other authoring mode, that is, edit, design, scaffolding, and so on. */--> <sly data-sly-test="${!production}" data-sly-include="edit.html" />
I componenti Screens richiedono due rendering diversi a seconda della modalità di authoring utilizzata:
- Produzione: modalità Anteprima o Publish (wcmmode=disabled)
- Modifica: utilizzato per tutte le altre modalità di creazione, ovvero modifica, progettazione, scaffolding, sviluppatore…
helloworld.html
funge da commutatore, controllando quale modalità di authoring è attiva e reindirizzando a un altro script HTL. Una convenzione comune utilizzata dai componenti Screens consiste nell'avere uno scriptedit.html
per la modalità di modifica e uno scriptproduction.html
per la modalità di produzione. -
Crea un file sotto
/apps/weretail-run/components/content/helloworld
denominatoproduction.html.
Compila il file con quanto segue:
code language-xml <!--/* /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>
Il markup di produzione riportato sopra si riferisce al componente Hello World. Poiché il componente viene utilizzato su un canale Sequenza, è incluso un attributo
data-duration
. L'attributodata-duration
viene utilizzato dal canale della sequenza per sapere per quanto tempo deve essere visualizzato un elemento della sequenza.Il componente esegue il rendering di un tag
div
eh1
con testo.${properties.message}
è una parte dello script HTL che restituisce il contenuto di una proprietà JCR denominatamessage
. In seguito viene creata una finestra di dialogo che consente all'utente di immettere un valore per il testo della proprietàmessage
.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 dell'AEM.
-
Crea un file sotto
/apps/weretail-run/components/content/helloworld
denominatoedit.html.
Compila il file con quanto segue:
code language-xml <!--/* /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>
Il markup di modifica qui sopra si riferisce al 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.
cq-placeholder
edata-emptytext
eseguono il rendering dell'etichetta Hello World come segnaposto in questo caso. La stringa per l’etichetta può essere internazionalizzata utilizzando i18n per supportare l’authoring in più lingue. -
Copia finestra di dialogo immagine Screens da utilizzare per il componente Hello World.
È più semplice iniziare da una finestra di dialogo esistente e quindi apportare modifiche.
- Copia la finestra di dialogo da:
/libs/screens/core/components/content/image/cq:dialog
- Incolla la finestra di dialogo sotto
/apps/weretail-run/components/content/helloworld
- Copia la finestra di dialogo da:
-
Aggiorna 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:
code language-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 is shown in the sequence, in milliseconds" fieldLabel="Duration (ms)" min="0" name="./duration"/> </items> </column> </items> </sequence> </items> </content> </jcr:root>
textfield
per il messaggio viene salvato in una proprietà denominatamessage
enumberfield
per la durata viene salvato in una proprietà denominataduration
. In/apps/weretail-run/components/content/helloworld/production.html
HTL fa riferimento a entrambe queste proprietà come${properties.message}
e${properties.duration}
.Finestra di dialogo Hello World - completato
Creare librerie lato client clientlibs
Le librerie lato client forniscono un meccanismo per organizzare e gestire i file CSS e JavaScript necessari per un’implementazione AEM.
I componenti AEM Screens vengono riprodotti in modo diverso nelle modalità Modifica e Anteprima/Produzione. Vengono 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
, creare una cartella denominataclientlibs
. -
Nella cartella
clientlibs
creare un nodo denominatoshared
di tipocq: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 alla libreria client CSS e JS tramite un prefisso of/etc.clientlibs.
-
-
Crea il file denominato
css.txt
sotto la cartella condivisa.Compila il file con quanto segue:
code language-none #base=css styles.less
-
Creare una cartella denominata
css
sotto la cartellashared
. Aggiungere un file denominatostyle.less
sotto la cartellacss
. La struttura delle librerie client ora dovrebbe essere simile alla seguente:Invece di scrivere direttamente CSS, questa esercitazione utilizza MENO. LESS è un popolare precompilatore CSS che supporta variabili, mixin e funzioni CSS. Le librerie client AEM supportano in modo nativo la compilazione LESS. È possibile utilizzare gli Sass o altri precompilatori, ma questi devono essere compilati al di fuori dell’AEM.
-
Popolare
/apps/weretail-run/components/content/helloworld/clientlibs/shared/css/styles.less
con quanto segue:code language-css /** 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 la cartella della libreria client
shared
per creare una libreria client denominataproduction
.Copia la libreria client condivisa per creare una libreria client di produzione.
-
Aggiorna la proprietà
categories
della libreria client di produzione in modo che siacq.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 quanto segue:code language-css /** 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.
È possibile utilizzare una terza categoria di libreria client: cq.screens.components.edit
per aggiungere al componente stili specifici di sola modifica.
cq.screens.components
cq.screens.components.edit
cq.screens.components.production
Creare una pagina di progettazione design-page
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.
Di seguito viene creata una pagina Progettazione dell'esecuzione di We.Retail in cui sono memorizzate tutte le configurazioni specifiche del progetto.
-
In CRXDE Liti
http://localhost:4502/crx/de/index.jsp#/apps/settings/wcm/designs
, passa a/apps/settings/wcm/designs
-
Creare un nodo sotto la cartella delle progettazioni, denominato
we-retail-run
con un tipo dicq:Page
. -
Nella pagina
we-retail-run
aggiungere un altro nodo denominatojcr:content
di tipont:unstructured
. Aggiungi le seguenti proprietà al nodojcr:content
:table 0-row-3 1-row-3 2-row-3 3-row-3 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
Creare un canale sequenza create-sequence-channel
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 AEM, passa a Screens > We.Retail Ru n > e seleziona Canali.
-
Fai clic sul pulsante Crea
- Scegli Crea entità
-
Nella procedura guidata Crea:
-
Passaggio modello - scegli Canale sequenza
-
Passaggio proprietà
- Scheda Base > Titolo = Canale Inattivo
- Scheda Canale > seleziona Rendi canale online
-
-
Apri le proprietà della pagina per il canale inattivo. Aggiornare il campo Struttura 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 creato per aprirlo.
-
Passa alla modalità pagina Progettazione.
-
Fai clic sull'icona chiave inglese in Parsys per configurare i componenti consentiti.
-
Selezionare il gruppo Screens e il gruppo Esecuzione We.Retail - Contenuto.
-
-
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 CRXDE Liti
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
. La proprietàcomponents
ora includegroup:Screens
,group:We.Retail Run - Content
.Configurazione del progetto in /apps/settings/wcm/designs/we-retail-run
Modello per gestori personalizzati custom-handlers
Se il componente personalizzato utilizza risorse esterne, come risorse (immagini, video, font e icone), rappresentazioni di risorse specifiche o librerie lato client (css e js), queste risorse non vengono aggiunte automaticamente alla configurazione offline. Il motivo è che Adobe raggruppa solo il markup HTML per impostazione predefinita.
Per personalizzare e ottimizzare le risorse esatte scaricate sul lettore, Adobe offre un meccanismo di estensione per i componenti personalizzati, in modo da esporre le loro dipendenze alla logica di caching offline in Screens.
La sezione seguente mostra 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 seguente fornisce i requisiti minimi in 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>
Tutti gli elementi insieme putting-it-all-together
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.
Codice finito finished-code
Di seguito è riportato il codice finito dell'esercitazione. 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.