Asignación de componentes de SPA a componentes de AEM map-components
Obtenga información sobre cómo asignar componentes de Angular a componentes de Adobe Experience Manager (AEM) con AEM SPA Editor JS SDK. La asignación de componentes permite a los usuarios realizar actualizaciones dinámicas de los componentes de la SPA en el Editor de SPA de AEM, de forma similar a la creación tradicional de AEM.
Este capítulo profundiza en la API del modelo JSON de AEM y en cómo el contenido JSON expuesto por un componente de AEM se puede insertar automáticamente en un componente de Angular como props.
Objetivo
- Obtenga información sobre cómo asignar componentes de AEM a componentes de SPA.
- Comprenda la diferencia entre los componentes Contenedor y los componentes Contenido.
- Cree un nuevo componente de Angular que se asigne a un componente de AEM existente.
Qué va a generar
Este capítulo analizará cómo se asigna el componente de SPA Text
proporcionado al componente Text
de AEM. Se crea un nuevo componente de SPA Image
que se puede usar en la SPA y crear en AEM. Las características predeterminadas de las directivas Contenedor de diseño y Editor de plantillas también se usarán para crear una vista que tenga un aspecto un poco más variado.
Requisitos previos
Revise las herramientas y las instrucciones necesarias para configurar un entorno de desarrollo local.
Obtener el código
-
Descargue el punto de partida para este tutorial mediante Git:
code language-shell $ git clone git@github.com:adobe/aem-guides-wknd-spa.git $ cd aem-guides-wknd-spa $ git checkout Angular/map-components-start
-
Implemente el código base en una instancia local de AEM mediante Maven:
code language-shell $ mvn clean install -PautoInstallSinglePackage
Si usa AEM 6.x, agregue el perfil
classic
:code language-shell $ mvn clean install -PautoInstallSinglePackage -Pclassic
Siempre puede ver el código terminado en GitHub o desprotegerlo localmente cambiando a la rama Angular/map-components-solution
.
Método de asignación
El concepto básico es asignar un componente de SPA a un componente de AEM. Los componentes de AEM, del lado del servidor de ejecución, exportan contenido como parte de la API del modelo JSON. La SPA consume el contenido JSON, que se ejecuta en el lado del cliente en el explorador. Se crea una asignación 1:1 entre los componentes de SPA y un componente de AEM.
Información general de alto nivel sobre la asignación de un componente AEM a un componente Angular
Inspeccionar el componente Texto
El tipo de archivo del proyecto AEM proporciona un componente Text
asignado al componente Texto de AEM. Este es un ejemplo de un componente content, ya que procesa content de AEM.
Veamos cómo funciona el componente.
Inspeccione el modelo JSON
-
Antes de saltar al código SPA, es importante comprender el modelo JSON que proporciona AEM. Vaya a la Biblioteca de componentes principales y vea la página del componente Texto. La biblioteca de componentes principales proporciona ejemplos de todos los componentes principales de AEM.
-
Seleccione la ficha JSON para uno de los ejemplos:
Debería ver tres propiedades:
text
,richText
y:type
.:type
es una propiedad reservada que enumerasling:resourceType
(o ruta de acceso) del componente AEM. El valor de:type
es lo que se usa para asignar el componente AEM al componente SPA.text
yrichText
son propiedades adicionales que se exponen al componente SPA.
Inspeccionar el componente Texto
-
Abra un nuevo terminal y vaya a la carpeta
ui.frontend
dentro del proyecto. Ejecutenpm install
y luegonpm start
para iniciar el servidor de desarrollo de Webpack:code language-shell $ cd ui.frontend $ npm run start:mock
El módulo
ui.frontend
está configurado actualmente para usar el modelo JSON ficticio. -
Debería ver una nueva ventana del explorador abierta a http://localhost:4200/content/wknd-spa-angular/us/en/home.html
-
En el IDE de su elección, abra el proyecto de AEM para la SPA de WKND. Expanda el módulo
ui.frontend
y abra el archivo text.component.ts enui.frontend/src/app/components/text/text.component.ts
: -
El primer área a inspeccionar es el
class TextComponent
en ~line 35:code language-js export class TextComponent { @Input() richText: boolean; @Input() text: string; @Input() itemName: string; @HostBinding('innerHtml') get content() { return this.richText ? this.sanitizer.bypassSecurityTrustHtml(this.text) : this.text; } @HostBinding('attr.data-rte-editelement') editAttribute = true; constructor(private sanitizer: DomSanitizer) {} }
El decorador @Input() se usa para declarar campos cuyos valores se establecen a través del objeto JSON asignado, revisado anteriormente.
@HostBinding('innerHtml') get content()
es un método que expone el contenido de texto creado del valor dethis.text
. En caso de que el contenido sea texto enriquecido (determinado por la marcathis.richText
), se omite la seguridad integrada de Angular. El DomSanitizer de Angular se usa para "eliminar" el HTML sin procesar y evitar vulnerabilidades de ejecución de scripts en sitios múltiples. El método está enlazado a la propiedadinnerHtml
mediante el decorador @HostBinding. -
A continuación, inspeccione
TextEditConfig
en ~line 24:code language-js const TextEditConfig = { emptyLabel: 'Text', isEmpty: cqModel => !cqModel || !cqModel.text || cqModel.text.trim().length < 1 };
El código anterior es responsable de determinar cuándo procesar el marcador de posición en el entorno de creación de AEM. Si el método
isEmpty
devuelve true, se procesará el marcador de posición. -
Finalmente, eche un vistazo a la llamada de
MapTo
en la línea 53:code language-js MapTo('wknd-spa-angular/components/text')(TextComponent, TextEditConfig );
MapTo lo proporciona AEM SPA Editor JS SDK (
@adobe/cq-angular-editable-components
). La ruta de accesowknd-spa-angular/components/text
representa elsling:resourceType
del componente AEM. Esta ruta de acceso coincide con el:type
expuesto por el modelo JSON observado anteriormente. MapTo analiza la respuesta del modelo JSON y pasa los valores correctos a las variables@Input()
del componente SPA.Puede encontrar la definición del componente
Text
de AEM enui.apps/src/main/content/jcr_root/apps/wknd-spa-angular/components/text
. -
Experimente modificando el archivo en.model.json en
ui.frontend/src/mocks/json/en.model.json
.En la línea 62, actualice el primer valor
Text
para que utilice las etiquetasH1
yu
:code language-json "text": { "text": "<h1><u>Hello World!</u></h1>", "richText": true, ":type": "wknd-spa-angular/components/text" }
Vuelva al explorador para ver los efectos que produce el servidor de desarrollo de Webpack:
Intente alternar la propiedad
richText
entre true / false para ver la lógica de procesamiento en acción. -
Inspeccionar text.component.html en
ui.frontend/src/app/components/text/text.component.html
.Este archivo está vacío porque la propiedad
innerHTML
establece todo el contenido del componente. -
Inspeccione app.module.ts en
ui.frontend/src/app/app.module.ts
.code language-js @NgModule({ imports: [ BrowserModule, SpaAngularEditableComponentsModule, AppRoutingModule ], providers: [ModelManagerService, { provide: APP_BASE_HREF, useValue: '/' }], declarations: [AppComponent, TextComponent, PageComponent, HeaderComponent], entryComponents: [TextComponent, PageComponent], bootstrap: [AppComponent] }) export class AppModule {}
TextComponent no se incluye explícitamente, sino de forma dinámica a través de AEMResponsiveGridComponent proporcionado por el SDK JS del Editor SPA de AEM. Por lo tanto, debe aparecer en la matriz app.module.ts' entryComponents.
Creación del componente de imagen
A continuación, cree un componente de Angular Image
asignado al componente de imagen de AEM. El componente Image
es otro ejemplo de un componente content.
Inspeccione el JSON
Antes de saltar al código SPA, revise el modelo JSON proporcionado por AEM.
-
Vaya a los ejemplos de imagen de la biblioteca de componentes principales.
Las propiedades de
src
,alt
ytitle
se usan para rellenar el componente SPAImage
.note note NOTE Hay otras propiedades de imagen expuestas ( lazyEnabled
,widths
) que permiten a un desarrollador crear un componente de carga diferida y adaptable. El componente integrado en este tutorial es sencillo y no utiliza estas propiedades avanzadas. -
Vuelva a su IDE y abra
en.model.json
a lasui.frontend/src/mocks/json/en.model.json
. Dado que este es un nuevo componente para nuestro proyecto, necesitamos "burlarnos" del JSON de imagen.En la línea ~line 70 agregue una entrada JSON para el modelo
image
(no se olvide de la coma final,
después del segundotext_386303036
) y actualice la matriz:itemsOrder
.code language-json ... ":items": { ... "text_386303036": { "text": "<p>A new text component.</p>\r\n", "richText": true, ":type": "wknd-spa-angular/components/text" }, "image": { "alt": "Rock Climber in New Zealand", "title": "Rock Climber in New Zealand", "src": "/mocks/images/adobestock-140634652.jpeg", ":type": "wknd-spa-angular/components/image" } }, ":itemsOrder": [ "text", "text_386303036", "image" ],
El proyecto incluye una imagen de muestra en
/mock-content/adobestock-140634652.jpeg
que se usa con el servidor de desarrollo de Webpack.Puedes ver en.model.json aquí.
-
Añada una foto estándar para que la muestre el componente.
Cree una nueva carpeta llamada images debajo de
ui.frontend/src/mocks
. Descargue adobestock-140634652.jpeg y colóquelo en la carpeta imágenes recién creada. Siéntase libre de usar su propia imagen, si lo desea.
Implementación del componente de imagen
-
Detenga el servidor de desarrollo de Webpack si se ha iniciado.
-
Cree un nuevo componente de imagen ejecutando el comando
ng generate component
de la CLI de Angular desde la carpetaui.frontend
:code language-shell $ ng generate component components/image
-
En el IDE, abra image.component.ts en
ui.frontend/src/app/components/image/image.component.ts
y actualícelo de la siguiente manera:code language-js import {Component, Input, OnInit} from '@angular/core'; import {MapTo} from '@adobe/cq-angular-editable-components'; const ImageEditConfig = { emptyLabel: 'Image', isEmpty: cqModel => !cqModel || !cqModel.src || cqModel.src.trim().length < 1 }; @Component({ selector: 'app-image', templateUrl: './image.component.html', styleUrls: ['./image.component.scss'] }) export class ImageComponent implements OnInit { @Input() src: string; @Input() alt: string; @Input() title: string; constructor() { } get hasImage() { return this.src && this.src.trim().length > 0; } ngOnInit() { } } MapTo('wknd-spa-angular/components/image')(ImageComponent, ImageEditConfig);
ImageEditConfig
es la configuración para determinar si se debe procesar el marcador de posición de autor en AEM, en función de si se ha rellenado la propiedadsrc
.@Input()
desrc
,alt
ytitle
son las propiedades asignadas desde la API JSON.hasImage()
es un método que determinará si se debe procesar la imagen.MapTo
asigna el componente SPA al componente AEM ubicado enui.apps/src/main/content/jcr_root/apps/wknd-spa-angular/components/image
. -
Abra image.component.html y actualícelo de la siguiente manera:
code language-html <ng-container *ngIf="hasImage"> <img class="image" [src]="src" [alt]="alt" [title]="title"/> </ng-container>
Esto procesará el elemento
<img>
sihasImage
devuelve true. -
Abra image.component.scss y actualícelo de la siguiente manera:
code language-scss :host-context { display: block; } .image { margin: 1rem 0; width: 100%; border: 0; }
note note NOTE La regla :host-context
es crítica para que el marcador de posición del editor de SPA de AEM funcione correctamente. Todos los componentes de SPA que se vayan a crear en el editor de páginas de AEM necesitarán esta regla como mínimo. -
Abra
app.module.ts
y agregueImageComponent
a la matrizentryComponents
:code language-js entryComponents: [TextComponent, PageComponent, ImageComponent],
Al igual que
TextComponent
,ImageComponent
se carga dinámicamente y debe incluirse en la matrizentryComponents
. -
Inicie webpack dev server para ver el procesamiento de
ImageComponent
.code language-shell $ npm run start:mock
Imagen agregada a la SPA
note note NOTE Desafío adicional: Implemente un nuevo método para mostrar el valor de title
como pie de ilustración debajo de la imagen.
Actualizar directivas en AEM
El componente ImageComponent
solo está visible en el servidor de desarrollo de Webpack. A continuación, implemente el SPA actualizado en AEM y actualice las directivas de plantilla.
-
Detenga el servidor de desarrollo de Webpack y, desde la raíz del proyecto, implemente los cambios en AEM con sus habilidades con Maven:
code language-shell $ cd aem-guides-wknd-spa $ mvn clean install -PautoInstallSinglePackage
-
En la pantalla de inicio de AEM, vaya a Herramientas > Plantillas > WKND SPA Angular.
Seleccione y edite la página de SPA:
-
Seleccione el contenedor de diseño y haga clic en su icono directiva para editar la directiva:
-
En Componentes permitidos > WKND SPA Angular - Contenido > compruebe el componente Imagen:
En Componentes predeterminados > Agregar asignación y elija el componente Imagen - WKND SPA Angular - Contenido:
Escriba un tipo mime de
image/*
.Haga clic en Listo para guardar las actualizaciones de la directiva.
-
En el contenedor de diseño, haga clic en el icono directiva para el componente Texto:
Cree una nueva directiva denominada WKND SPA Text. En Complementos > Formato > marque todas las casillas para habilitar opciones de formato adicionales:
En Complementos > Estilos de párrafo > marque la casilla para habilitar estilos de párrafo:
Haga clic en Listo para guardar la actualización de la directiva.
-
Vaya a Página principal http://localhost:4502/editor.html/content/wknd-spa-angular/us/en/home.html.
También debería poder editar el componente
Text
y agregar estilos de párrafo adicionales en el modo pantalla completa. -
También debería poder arrastrar y soltar una imagen desde Buscador de recursos:
-
Agregue sus propias imágenes a través de AEM Assets o instale la base de código terminado para el sitio de referencia WKND estándar. El sitio de referencia WKND incluye muchas imágenes que se pueden reutilizar en la SPA de WKND. El paquete se puede instalar usando Administrador de paquetes de AEM.
Inspeccionar el contenedor de diseño
AEM SPA Editor SDK proporciona automáticamente compatibilidad con el contenedor de diseño. El contenedor de diseño, tal como indica el nombre, es un componente contenedor. Los componentes de contenedor son componentes que aceptan estructuras JSON que representan otros componentes y las instancian dinámicamente.
Vamos a inspeccionar más el contenedor de diseño.
-
En el IDE, abra responsive-grid.component.ts a las
ui.frontend/src/app/components/responsive-grid
:code language-js import { AEMResponsiveGridComponent,MapTo } from '@adobe/cq-angular-editable-components'; MapTo('wcm/foundation/components/responsivegrid')(AEMResponsiveGridComponent);
AEMResponsiveGridComponent
se implementa como parte de AEM SPA Editor SDK y se incluye en el proyecto a través deimport-components
. -
En un explorador, vaya a http://localhost:4502/content/wknd-spa-angular/us/en.model.json
El componente Contenedor de diseño tiene un
sling:resourceType
dewcm/foundation/components/responsivegrid
y el Editor de la SPA lo reconoce usando la propiedad:type
, al igual que los componentesText
yImage
.Las mismas capacidades para cambiar el tamaño de un componente mediante Modo de diseño están disponibles con el Editor de SPA.
-
Volver a http://localhost:4502/editor.html/content/wknd-spa-angular/us/en/home.html. Agregue componentes adicionales de Image e intente cambiar su tamaño con la opción Diseño:
-
Vuelva a abrir el modelo JSON http://localhost:4502/content/wknd-spa-angular/us/en.model.json y observe
columnClassNames
como parte del JSON:El nombre de clase
aem-GridColumn--default--4
indica que el componente debe tener 4 columnas de ancho basado en una cuadrícula de 12 columnas. Encontrará más detalles sobre la cuadrícula adaptable aquí. -
Vuelva al IDE y en el módulo
ui.apps
hay una biblioteca del lado del cliente definida enui.apps/src/main/content/jcr_root/apps/wknd-spa-angular/clientlibs/clientlib-grid
. Abra el archivoless/grid.less
.Este archivo determina los puntos de interrupción (
default
,tablet
yphone
) utilizados por el contenedor de diseño. El propósito de este archivo es personalizarlo según las especificaciones del proyecto. Actualmente los puntos de interrupción están establecidos en1200px
y650px
. -
Debe poder utilizar las capacidades adaptables y las directivas de texto enriquecido actualizadas del componente
Text
para crear una vista como la siguiente:
Enhorabuena. congratulations
Felicidades, ha aprendido a asignar componentes de la SPA a componentes de AEM y ha implementado un nuevo componente Image
. También tiene la oportunidad de explorar las capacidades adaptables de Contenedor de diseño.
Siempre puede ver el código terminado en GitHub o desprotegerlo localmente cambiando a la rama Angular/map-components-solution
.
Siguientes pasos next-steps
Navegación y enrutamiento: descubra cómo se pueden admitir varias vistas en la SPA asignándolas a páginas de AEM con la SDK del Editor de SPA. La navegación dinámica se implementa mediante Angular Router y se añade a un componente de encabezado existente.
Bonificación: mantener configuraciones para el control de código fuente bonus
En muchos casos, especialmente al principio de un proyecto de AEM, es importante mantener las configuraciones, como las plantillas y las directivas de contenido relacionadas, para el control de código fuente. Esto garantiza que todos los desarrolladores trabajen con el mismo conjunto de contenido y configuraciones y puede garantizar una coherencia adicional entre entornos. Una vez que un proyecto alcanza un cierto nivel de madurez, la práctica de administrar plantillas se puede transferir a un grupo especial de usuarios avanzados.
Los siguientes pasos se llevarán a cabo con el IDE de código de Visual Studio y VSCode AEM Sync, pero podrían realizarse con cualquier herramienta y IDE que haya configurado para extraer o importar contenido de una instancia local de AEM.
-
En el IDE de código de Visual Studio, asegúrese de que tiene VSCode AEM Sync instalado mediante la extensión Marketplace:
-
Expanda el módulo ui.content en el explorador del proyecto y vaya a
/conf/wknd-spa-angular/settings/wcm/templates
. -
Haga clic con el botón derecho en la carpeta
templates
y seleccione Importar desde el servidor de AEM: -
Repita los pasos para importar contenido, pero seleccione la carpeta policies ubicada en
/conf/wknd-spa-angular/settings/wcm/policies
. -
Inspeccione el archivo de
filter.xml
ubicado enui.content/src/main/content/META-INF/vault/filter.xml
.code language-xml <!--ui.content filter.xml--> <?xml version="1.0" encoding="UTF-8"?> <workspaceFilter version="1.0"> <filter root="/conf/wknd-spa-angular" mode="merge"/> <filter root="/content/wknd-spa-angular" mode="merge"/> <filter root="/content/dam/wknd-spa-angular" mode="merge"/> <filter root="/content/experience-fragments/wknd-spa-angular" mode="merge"/> </workspaceFilter>
El archivo
filter.xml
es responsable de identificar las rutas de acceso de los nodos instalados con el paquete. Observe elmode="merge"
en cada uno de los filtros que indica que el contenido existente no se modificará, solo se agregará contenido nuevo. Dado que los autores de contenido pueden estar actualizando estas rutas, es importante que una implementación de código sobrescriba el contenido no. Consulte la documentación de FileVault para obtener más información sobre cómo trabajar con elementos de filtro.Compare
ui.content/src/main/content/META-INF/vault/filter.xml
yui.apps/src/main/content/META-INF/vault/filter.xml
para comprender los diferentes nodos administrados por cada módulo.