Mapear componentes do SPA para componentes do AEM map-components
Saiba como mapear componentes do Angular para componentes do Adobe Experience Manager (AEM AEM SPA) com o SDK JS do editor do. O mapeamento de componentes permite que os usuários façam atualizações dinâmicas nos componentes do SPA no editor SPA AEM, de forma semelhante à criação tradicional do AEM.
Este capítulo detalha a API do modelo JSON do AEM e mostra como o conteúdo JSON exposto por um componente AEM pode ser injetado automaticamente em um componente do Angular como props.
Objetivo
- Saiba como mapear componentes de AEM para componentes de SPA.
- Entenda a diferença entre os componentes de Contêiner e os componentes de Conteúdo.
- Crie um novo componente do Angular que mapeie para um componente AEM existente.
O que você vai criar
Este capítulo verificará como o componente do SPA Text
fornecido é mapeado para o componente AEM Text
. É criado um novo componente de SPA Image
que pode ser usado no SPA e criado no AEM. Os recursos prontos das políticas do Contêiner de layout e Editor de modelos também serão usados para criar um modo de exibição um pouco mais variado na aparência.
Pré-requisitos
Revise as ferramentas e instruções necessárias para configurar um ambiente de desenvolvimento local.
Obter o código
-
Baixe o ponto de partida para este tutorial pelo 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
-
Implante a base de código em uma instância de AEM local usando Maven:
code language-shell $ mvn clean install -PautoInstallSinglePackage
Se estiver usando o AEM 6.x, adicione o perfil
classic
:code language-shell $ mvn clean install -PautoInstallSinglePackage -Pclassic
Você sempre pode exibir o código concluído em GitHub ou verificar o código localmente alternando para a ramificação Angular/map-components-solution
.
Abordagem de mapeamento
O conceito básico é mapear um componente SPA para um componente AEM. Componentes do AEM, executar no lado do servidor, exportar conteúdo como parte da API do modelo JSON. O conteúdo JSON é consumido pelo SPA, executando no lado do cliente no navegador. Um mapeamento 1:1 entre componentes SPA e um componente AEM é criado.
Visão geral de alto nível do mapeamento de um componente AEM para um componente de Angular
Inspect, o componente de Texto
O Arquétipo de Projeto do AEM fornece um componente Text
que é mapeado para o componente de Texto do AEM. Este é um exemplo de um componente conteúdo, no qual ele renderiza conteúdo do AEM.
Vamos ver como o componente funciona.
Inspect e o modelo JSON
-
Antes de pular para o código SPA, é importante entender o modelo JSON que o AEM fornece. Navegue até a Biblioteca de Componentes principais e exiba a página do componente de Texto. A Biblioteca de componentes principais fornece exemplos de todos os componentes principais AEM.
-
Selecione a guia JSON para um dos exemplos:
Você deve ver três propriedades:
text
,richText
e:type
.:type
é uma propriedade reservada que lista osling:resourceType
(ou caminho) do Componente AEM. O valor de:type
é o que é usado para mapear o componente AEM para o componente SPA.text
erichText
são propriedades adicionais expostas ao componente SPA.
Inspect, o componente de Texto
-
Abra um novo terminal e navegue até a pasta
ui.frontend
dentro do projeto. Executenpm install
e depoisnpm start
para iniciar o servidor de desenvolvimento do webpack:code language-shell $ cd ui.frontend $ npm run start:mock
O módulo
ui.frontend
está configurado atualmente para usar o modelo JSON simulado. -
Você deve ver uma nova janela de navegador aberta para http://localhost:4200/content/wknd-spa-angular/us/en/home.html
-
No IDE de sua escolha, abra o projeto AEM para o SPA WKND. Expanda o módulo
ui.frontend
e abra o arquivo text.component.ts emui.frontend/src/app/components/text/text.component.ts
: -
A primeira área a ser inspecionada é o
class TextComponent
na linha ~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) {} }
O decorador @Input() é usado para declarar campos cujos valores são definidos por meio do objeto JSON mapeado, revisado anteriormente.
@HostBinding('innerHtml') get content()
é um método que expõe o conteúdo do texto criado a partir do valor dethis.text
. No caso de o conteúdo ser rich text (determinado pelo sinalizadorthis.richText
), a segurança interna do Angular é ignorada. O DomSanitizer do Angular é usado para "depurar" o HTML bruto e evitar vulnerabilidades de Script entre sites. O método está associado à propriedadeinnerHtml
usando o decorador @HostBinding. -
Em seguida, verifique o
TextEditConfig
em ~line 24:code language-js const TextEditConfig = { emptyLabel: 'Text', isEmpty: cqModel => !cqModel || !cqModel.text || cqModel.text.trim().length < 1 };
O código acima é responsável por determinar quando renderizar o espaço reservado no ambiente do autor do AEM. Se o método
isEmpty
retornar true, o espaço reservado será renderizado. -
Por fim, dê uma olhada na chamada
MapTo
em ~line 53:code language-js MapTo('wknd-spa-angular/components/text')(TextComponent, TextEditConfig );
MapTo é fornecido pelo SDK JS do Editor SPA AEM (
@adobe/cq-angular-editable-components
). O caminhowknd-spa-angular/components/text
representa osling:resourceType
do componente AEM. Esse caminho corresponde ao:type
exposto pelo modelo JSON observado anteriormente. MapTo analisa a resposta do modelo JSON e transmite os valores corretos para as variáveis@Input()
do componente SPA.Você pode encontrar a definição do componente AEM
Text
emui.apps/src/main/content/jcr_root/apps/wknd-spa-angular/components/text
. -
Experimente modificando o arquivo en.model.json em
ui.frontend/src/mocks/json/en.model.json
.Em ~line 62, atualize o primeiro valor
Text
para usar as marcasH1
eu
:code language-json "text": { "text": "<h1><u>Hello World!</u></h1>", "richText": true, ":type": "wknd-spa-angular/components/text" }
Retorne ao navegador para ver os efeitos do servidor de desenvolvimento do webpack:
Tente alternar a propriedade
richText
entre true / false para ver a lógica de renderização em ação. -
Inspect text.component.html em
ui.frontend/src/app/components/text/text.component.html
.Este arquivo está vazio porque todo o conteúdo do componente está definido pela propriedade
innerHTML
. -
Inspect o app.module.ts em
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 {}
O TextComponent não está incluído explicitamente, mas dinamicamente por meio de AEMResponsiveGridComponent fornecido pelo SDK JS do Editor de SPA AEM. Portanto, deve ser listado na matriz app.module.ts' entryComponents.
Criar o componente de Imagem
Em seguida, crie um componente de Angular Image
que seja mapeado para o componente de imagem AEM 2}.O componente Image
é outro exemplo de um componente content.
Inspect, o JSON
Antes de pular para o código SPA, inspecione o modelo JSON fornecido pelo AEM.
-
Navegue até os exemplos de imagem na biblioteca de Componentes principais.
Propriedades de
src
,alt
etitle
são usadas para popular o componente SPAImage
.note note NOTE Há outras propriedades de Imagem expostas ( lazyEnabled
,widths
) que permitem a um desenvolvedor criar um componente adaptável e de carregamento lento. O componente compilado neste tutorial é simples e não usa essas propriedades avançadas. -
Retorne ao IDE e abra o
en.model.json
emui.frontend/src/mocks/json/en.model.json
. Como este é um componente novo para o nosso projeto, precisamos "simular" o JSON de imagem.Em ~line 70, adicione uma entrada JSON para o modelo
image
(não se esqueça da vírgula à direita,
após o segundotext_386303036
) e atualize a 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" ],
O projeto inclui uma imagem de exemplo em
/mock-content/adobestock-140634652.jpeg
que é usada com o servidor de desenvolvimento do webpack.Você pode exibir o en.model.json completo aqui.
-
Adicione uma foto do estoque a ser exibida pelo componente.
Crie uma nova pasta chamada imagens abaixo de
ui.frontend/src/mocks
. Baixe adobestock-140634652.jpeg e coloque-o na pasta images recém-criada. Você pode usar sua própria imagem, se desejar.
Implementar o componente de Imagem
-
Pare o servidor de desenvolvimento do webpack, se iniciado.
-
Crie um novo componente de Imagem executando o comando Angular CLI
ng generate component
na pastaui.frontend
:code language-shell $ ng generate component components/image
-
No IDE, abra image.component.ts em
ui.frontend/src/app/components/image/image.component.ts
e atualize da seguinte maneira: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
é a configuração para determinar se o espaço reservado do autor deve ser renderizado no AEM, com base no preenchimento da propriedadesrc
.@Input()
desrc
,alt
etitle
são as propriedades mapeadas da API JSON.hasImage()
é um método que determinará se a imagem deve ser renderizada.MapTo
mapeia o componente SPA para o componente AEM localizado emui.apps/src/main/content/jcr_root/apps/wknd-spa-angular/components/image
. -
Abra image.component.html e atualize da seguinte maneira:
code language-html <ng-container *ngIf="hasImage"> <img class="image" [src]="src" [alt]="alt" [title]="title"/> </ng-container>
Isso renderizará o elemento
<img>
sehasImage
retornar true. -
Abra image.component.scss e atualize da seguinte maneira:
code language-scss :host-context { display: block; } .image { margin: 1rem 0; width: 100%; border: 0; }
note note NOTE A regra :host-context
é crítica para que o espaço reservado para o editor de SPA AEM funcione corretamente. Todos os componentes do SPA que devem ser criados no editor de página do AEM precisarão dessa regra no mínimo. -
Abra
app.module.ts
e adicioneImageComponent
à matrizentryComponents
:code language-js entryComponents: [TextComponent, PageComponent, ImageComponent],
Assim como o
TextComponent
, oImageComponent
é carregado dinamicamente e deve ser incluído na matrizentryComponents
. -
Inicie o servidor de desenvolvimento do webpack para ver a renderização de
ImageComponent
.code language-shell $ npm run start:mock
Imagem adicionada ao SPA
note note NOTE Desafio de bônus: implemente um novo método para exibir o valor de title
como uma legenda abaixo da imagem.
Atualizar políticas no AEM
O componente ImageComponent
só é visível no servidor de desenvolvimento do webpack. SPA Em seguida, implante o AEM atualizado e atualize as políticas do template.
-
Pare o servidor de desenvolvimento do webpack e, a partir da raiz do projeto, implante as alterações no AEM usando suas habilidades em Maven:
code language-shell $ cd aem-guides-wknd-spa $ mvn clean install -PautoInstallSinglePackage
-
Na tela inicial do AEM, navegue até Ferramentas > Modelos > Angular SPA WKND.
Selecione e edite a Página do SPA:
-
Selecione o Contêiner de layout e clique em seu ícone de política para editar a política:
-
Em Componentes Permitidos > Angular SPA WKND - Conteúdo > verifique o componente Imagem:
Em Componentes Padrão > Adicionar mapeamento e escolha o componente Imagem - Angular SPA WKND - Conteúdo:
Insira um tipo MIME de
image/*
.Clique em Concluído para salvar as atualizações de política.
-
No Contêiner de Layout, clique no ícone política para o componente Texto:
Crie uma nova política chamada Texto SPA WKND. Em Plugins > Formatação > marque todas as caixas para habilitar opções de formatação adicionais:
Em Plug-ins > Estilos de parágrafo >, marque a caixa para Habilitar estilos de parágrafo:
Clique em Concluído para salvar a atualização de política.
-
Navegue até a Página inicial http://localhost:4502/editor.html/content/wknd-spa-angular/us/en/home.html.
Você também pode editar o componente
Text
e adicionar outros estilos de parágrafo no modo tela cheia. -
Você também pode arrastar e soltar uma imagem do Localizador de ativos:
-
Adicione suas próprias imagens via AEM Assets ou instale a base de código concluída para o site de referência WKND padrão. O site de referência da WKND inclui muitas imagens que podem ser reutilizadas no SPA da WKND. O pacote pode ser instalado usando o Gerenciador de Pacotes do AEM.
do Gerenciador de Pacotes
Inspect o contêiner de layout
O suporte para o Contêiner de layout é fornecido automaticamente pelo SDK do Editor de SPA AEM. O Contêiner de Layout, conforme indicado pelo nome, é um componente contêiner. Componentes de contêiner são componentes que aceitam estruturas JSON que representam outros componentes e os instanciam dinamicamente.
Vamos analisar mais detalhadamente o Contêiner de layout.
-
No IDE, abra responsive-grid.component.ts em
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);
O
AEMResponsiveGridComponent
é implementado como parte do SDK do Editor SPA AEM e está incluído no projeto viaimport-components
. -
Em um navegador, navegue até http://localhost:4502/content/wknd-spa-angular/us/en.model.json
O componente Contêiner de Layout tem um
sling:resourceType
dewcm/foundation/components/responsivegrid
e é reconhecido pelo Editor de SPA usando a propriedade:type
, exatamente como os componentesText
eImage
.Os mesmos recursos de redimensionamento de um componente usando o Modo de layout estão disponíveis com o Editor de SPA.
-
Retorne a http://localhost:4502/editor.html/content/wknd-spa-angular/us/en/home.html. Adicione componentes adicionais de Imagem e tente redimensioná-los usando a opção Layout:
-
Abra novamente o modelo JSON http://localhost:4502/content/wknd-spa-angular/us/en.model.json e observe o
columnClassNames
como parte do JSON:O nome de classe
aem-GridColumn--default--4
indica que o componente deve ter 4 colunas de largura com base em uma grade de 12 colunas. Mais detalhes sobre a grade responsiva podem ser encontrados aqui. -
Retorne ao IDE e no módulo
ui.apps
há uma biblioteca do lado do cliente definida emui.apps/src/main/content/jcr_root/apps/wknd-spa-angular/clientlibs/clientlib-grid
. Abra o arquivoless/grid.less
.Este arquivo determina os pontos de interrupção (
default
,tablet
ephone
) usados pelo Contêiner de Layout. Este arquivo deve ser personalizado de acordo com as especificações do projeto. Os pontos de interrupção estão definidos como1200px
e650px
. -
Você deve ser capaz de usar os recursos responsivos e as políticas de rich text atualizadas do componente
Text
para criar uma exibição como a seguinte:
Parabéns. congratulations
Parabéns, você aprendeu a mapear componentes de SPA para componentes de AEM e implementou um novo componente Image
. Você também pode explorar os recursos responsivos do Contêiner de layout.
Você sempre pode exibir o código concluído em GitHub ou verificar o código localmente alternando para a ramificação Angular/map-components-solution
.
Próximas etapas next-steps
Navegação e Roteamento - Saiba como várias exibições no SPA podem ser suportadas pelo mapeamento para Páginas AEM com o SDK do Editor de SPA. A navegação dinâmica é implementada usando o Angular Router e adicionada a um componente Header existente.
Bônus - Configurações persistentes para o controle de origem bonus
Em muitos casos, especialmente no início de um projeto AEM, é valioso manter as configurações, como modelos e políticas de conteúdo relacionadas, no controle de origem. Isso garante que todos os desenvolvedores trabalhem com o mesmo conjunto de conteúdo e configurações e possa garantir consistência adicional entre os ambientes. Quando um projeto atinge um determinado nível de maturidade, a prática de gerenciar modelos pode ser transferida para um grupo especial de usuários avançados.
As próximas etapas ocorrerão usando o IDE do Visual Studio Code e o VSCode AEM Sync, mas podem ser realizadas usando qualquer ferramenta e qualquer IDE que você tenha configurado para extrair ou importar conteúdo de uma instância local do AEM.
-
No Visual Studio Code IDE, verifique se você tem o VSCode AEM Sync instalado por meio da extensão do Marketplace:
-
Expanda o módulo ui.content no Gerenciador de projetos e navegue até
/conf/wknd-spa-angular/settings/wcm/templates
. -
Clique com o botão direito do mouse na pasta
templates
e selecione Importar do Servidor AEM: -
Repita as etapas para importar o conteúdo, mas selecione a pasta políticas localizada em
/conf/wknd-spa-angular/settings/wcm/policies
. -
Inspect o arquivo
filter.xml
localizado emui.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>
O arquivo
filter.xml
é responsável por identificar os caminhos dos nós instalados com o pacote. Observe omode="merge"
em cada filtro que indica que o conteúdo existente não será modificado, somente o novo conteúdo será adicionado. Como os autores de conteúdo podem estar atualizando esses caminhos, é importante que uma implantação de código não substitua o conteúdo. Consulte a documentação do FileVault para obter mais detalhes sobre como trabalhar com elementos de filtro.Compare
ui.content/src/main/content/META-INF/vault/filter.xml
eui.apps/src/main/content/META-INF/vault/filter.xml
para entender os diferentes nós gerenciados por cada módulo.