Mapear componentes de SPA para componentes do AEM map-components
- O editor universal para editar conteúdo headless visualmente.
- O editor de fragmentos de conteúdo para editar conteúdo headless com base em formulários.
Saiba como mapear componentes do Angular para componentes do Adobe Experience Manager (AEM) com o AEM SPA Editor JS SDK. O mapeamento de componentes permite que os usuários façam atualizações dinâmicas em componentes SPA no Editor SPA do AEM, de modo semelhante à criação tradicional no AEM.
Este capítulo detalha a API do modelo JSON do AEM e mostra como o conteúdo JSON exposto por um componente do AEM pode ser inserido automaticamente em um componente do Angular como props.
Objetivo
- Saiba como mapear componentes do AEM para componentes 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 existente do AEM.
O que você vai criar
Este capítulo verificará como o componente de SPA Text fornecido é mapeado para o componente Text do AEM. Um novo componente de SPA Image é criado e 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 do AEM local usando Maven:
code language-shell $ mvn clean install -PautoInstallSinglePackageSe 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 de SPA para um componente do 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 de SPA e um componente do AEM é criado.
Visão geral de alto nível do mapeamento de um componente do AEM para um componente do Angular
Inspecione 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.
Inspecionar 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 do AEM.
-
Selecione a guia JSON para um dos exemplos:
Você deve ver três propriedades:
text,richTexte: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.texterichTextsão propriedades adicionais expostas ao componente de SPA.
Inspecionar o componente de Texto
-
Abra um novo terminal e navegue até a pasta
ui.frontenddentro do projeto. Executenpm installe depoisnpm startpara iniciar o servidor de desenvolvimento do webpack:code language-shell $ cd ui.frontend $ npm run start:mockO módulo
ui.frontendestá 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 WKND SPA. Expanda o módulo
ui.frontende abra o arquivo text.component.ts emui.frontend/src/app/components/text/text.component.ts:
-
A primeira área a ser inspecionada é o
class TextComponentna 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. Caso o conteúdo seja rich text (determinado pelo sinalizadorthis.richText), a segurança interna do Angular é ignorada. O DomSanitizer da Angular é usado para "limpar" o HTML bruto e evitar vulnerabilidades de script entre sites. O método está associado à propriedadeinnerHtmlusando o decorador @HostBinding. -
Em seguida, verifique o
TextEditConfigem ~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 de autor do AEM. Se o método
isEmptyretornar true, o espaço reservado será renderizado. -
Por fim, dê uma olhada na chamada
MapToem ~line 53:code language-js MapTo('wknd-spa-angular/components/text')(TextComponent, TextEditConfig );MapTo é fornecido pelo AEM SPA Editor JS SDK (
@adobe/cq-angular-editable-components). O caminhowknd-spa-angular/components/textrepresenta osling:resourceTypedo componente AEM. Esse caminho corresponde ao:typeexposto pelo modelo JSON observado anteriormente. MapTo analisa a resposta do modelo JSON e passa os valores corretos para as variáveis@Input()do componente SPA.Você pode encontrar a definição do componente
Textdo AEM 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
Textpara usar as marcasH1eu: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
richTextentre true / false para ver a lógica de renderização em ação. -
Inspecionar 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. -
Inspecione 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 AEM SPA Editor JS SDK. Portanto, deve ser listado na matriz app.module.ts' entryComponents.
Criar o componente de Imagem
Em seguida, crie um componente do Angular Image que seja mapeado para o componente de Imagem do AEM. O componente Image é outro exemplo de um componente content.
Inspecionar 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,altetitlesão usadas para popular o componente de 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.jsonemui.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.jpegque é 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
ng generate componentda Angular CLI 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.tse 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,altetitlesão as propriedades mapeadas da API JSON.hasImage()é um método que determinará se a imagem deve ser renderizada.MapTomapeia 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>sehasImageretornar 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 do editor de SPA do AEM funcione corretamente. Todos os componentes de SPA que devem ser criados no editor de páginas do AEM precisarão dessa regra no mínimo. -
Abra
app.module.tse 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 titlecomo uma legenda abaixo da imagem.
Atualizar políticas no AEM
O componente ImageComponent só é visível no servidor de desenvolvimento do webpack. Em seguida, implante o SPA atualizado no AEM e atualize as políticas do modelo.
-
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 > WKND SPA Angular.
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 > WKND SPA Angular - Conteúdo > verifique o componente Imagem:
Em Componentes Padrão > Adicionar mapeamento e escolha o componente Imagem - WKND SPA Angular - 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 WKND SPA Text. 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
Texte 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 WKND inclui muitas imagens que podem ser reutilizadas no SPA do WKND. O pacote pode ser instalado usando o Gerenciador de Pacotes da AEM.
do Gerenciador de Pacotes
Inspecione o contêiner de layout
O suporte para o Contêiner de layout é fornecido automaticamente pelo SDK do Editor SPA do 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 do 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:resourceTypedewcm/foundation/components/responsivegride é reconhecido pelo Editor SPA usando a propriedade:type, exatamente como os componentesTexteImage.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
columnClassNamescomo parte do JSON:
O nome de classe
aem-GridColumn--default--4indica 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.appshá 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,tabletephone) 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 como1200pxe650px. -
Você deve ser capaz de usar os recursos responsivos e as políticas de rich text atualizadas do componente
Textpara criar uma exibição como a seguinte:
Parabéns! congratulations
Parabéns, você aprendeu a mapear componentes de SPA para Componentes do 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 é possível oferecer suporte a várias exibições no SPA mapeando para Páginas do AEM com o SDK do Editor de SPA. A navegação dinâmica é implementada usando o Angular Router e adicionada a um componente Cabeçalho existente.
Bônus - Configurações persistentes para o controle de origem bonus
Em muitos casos, especialmente no início de um projeto do 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 pode ser 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
templatese selecione Importar do AEM Server:
-
Repita as etapas para importar o conteúdo, mas selecione a pasta políticas localizada em
/conf/wknd-spa-angular/settings/wcm/policies. -
Inspecione o arquivo
filter.xmllocalizado 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.xmleui.apps/src/main/content/META-INF/vault/filter.xmlpara entender os diferentes nós gerenciados por cada módulo.