Estender um Componente principal extend-component
Saiba como estender um Componente principal existente para ser usado com o Editor de SPA AEM. AEM Entender como estender um componente existente é uma técnica poderosa para personalizar e expandir os recursos de uma implementação do Editor de SPA.
Objetivo
- Estender um Componente principal existente com propriedades e conteúdo adicionais.
- Entenda os fundamentos da herança de componentes com o uso do
sling:resourceSuperType
. - Saiba como usar o Padrão de delegação para que os Modelos do Sling reutilizem a lógica e a funcionalidade existentes.
O que você vai criar
Neste capítulo, uma nova Card
componente é criado. A variável Card
O componente estende a Componente principal da imagem inclusão de campos de conteúdo adicionais, como um Título e um botão de Chamada para ação, para executar a função de um teaser para outro conteúdo no SPA.
Card
componente dependendo dos requisitos do projeto. É sempre recomendável usar Componentes principais diretamente, quando possível.Pré-requisitos
Analisar as ferramentas e instruções necessárias para a configuração de 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/extend-component-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 AEM 6.x adicione o
classic
perfil:code language-shell $ mvn clean install -PautoInstallSinglePackage -Pclassic
-
Instale o pacote concluído para o tradicional Site de referência da WKND. As imagens fornecidas por Site de referência da WKND é reutilizado no SPA WKND. O pacote pode ser instalado usando Gerenciador de pacotes AEM.
Você sempre pode exibir o código concluído em GitHub ou confira o código localmente alternando para a ramificação Angular/extend-component-solution
.
Implementação inicial do Cartão Inspect
Um componente Cartão inicial foi fornecido pelo código inicial do capítulo. O Inspect é o ponto de partida para a implementação do Cartão.
-
No IDE de sua escolha, abra o
ui.apps
módulo. -
Navegue até
ui.apps/src/main/content/jcr_root/apps/wknd-spa-angular/components/card
e visualize o.content.xml
arquivo.code language-xml <?xml version="1.0" encoding="UTF-8"?> <jcr:root xmlns:sling="http://sling.apache.org/jcr/sling/1.0" xmlns:cq="http://www.day.com/jcr/cq/1.0" xmlns:jcr="http://www.jcp.org/jcr/1.0" jcr:primaryType="cq:Component" jcr:title="Card" sling:resourceSuperType="wknd-spa-angular/components/image" componentGroup="WKND SPA Angular - Content"/>
A propriedade
sling:resourceSuperType
aponta parawknd-spa-angular/components/image
indicando que aCard
O componente herda a funcionalidade do componente de Imagem SPA WKND. -
Inspect o arquivo
ui.apps/src/main/content/jcr_root/apps/wknd-spa-angular/components/image/.content.xml
:code language-xml <?xml version="1.0" encoding="UTF-8"?> <jcr:root xmlns:sling="http://sling.apache.org/jcr/sling/1.0" xmlns:cq="http://www.day.com/jcr/cq/1.0" xmlns:jcr="http://www.jcp.org/jcr/1.0" jcr:primaryType="cq:Component" jcr:title="Image" sling:resourceSuperType="core/wcm/components/image/v2/image" componentGroup="WKND SPA Angular - Content"/>
Observe que
sling:resourceSuperType
aponta paracore/wcm/components/image/v2/image
. Isso indica que o componente de Imagem SPA WKND herda a funcionalidade da Imagem do componente principal.Também conhecido como Padrão do proxy A herança de recursos do Sling é um padrão de design avançado para permitir que os componentes secundários herdem funcionalidade e estendam/substituam o comportamento quando desejado. A herança do Sling suporta vários níveis de herança, de modo que, em última análise, o novo
Card
O componente herda a funcionalidade da Imagem do componente principal.Muitas equipes de desenvolvimento se esforçam para ser D.R.Y. (não se repita). A herança por Sling torna isso possível com o AEM.
-
Abaixo de
card
, abra o arquivo_cq_dialog/.content.xml
.Este arquivo é a definição da Caixa de diálogo de componente do
Card
componente. Se estiver usando a herança do Sling, é possível usar recursos do Fusão de recursos do Sling para substituir ou estender partes do diálogo. Neste exemplo, uma nova guia foi adicionada à caixa de diálogo para capturar dados adicionais de um autor para preencher o componente Cartão.Propriedades como
sling:orderBefore
permite que um desenvolvedor escolha onde inserir novas guias ou campos de formulário. Neste caso, oText
é inserida antes da guiaasset
guia. Para usar totalmente a Fusão de recursos do Sling, é importante conhecer a estrutura original do nó de diálogo da Caixa de diálogo do componente de imagem. -
Abaixo de
card
, abra o arquivo_cq_editConfig.xml
. Esse arquivo determina o comportamento de arrastar e soltar na interface de criação do AEM. Ao estender o componente de Imagem, é importante que o tipo de recurso corresponda ao próprio componente. Revise o<parameters>
nó:code language-xml <parameters jcr:primaryType="nt:unstructured" sling:resourceType="wknd-spa-angular/components/card" imageCrop="" imageMap="" imageRotate=""/>
A maioria dos componentes não requer um
cq:editConfig
, a Imagem e os descendentes secundários do componente de Imagem são exceções. -
No IDE, alterne para a guia
ui.frontend
módulo, navegar atéui.frontend/src/app/components/card
: -
Inspect o arquivo
card.component.ts
.O componente já foi retirado para mapear para o AEM
Card
Componente que usa o padrãoMapTo
função.code language-js MapTo('wknd-spa-angular/components/card')(CardComponent, CardEditConfig);
Analise os três
@Input
parâmetros na classe parasrc
,alt
, etitle
. Esses são valores JSON esperados do componente AEM que são mapeados para o componente Angular. -
Abra o arquivo
card.component.html
:code language-html <div class="card" *ngIf="hasContent"> <app-image class="card__image" [src]="src" [alt]="alt" [title]="title"></app-image> </div>
Neste exemplo, optamos por reutilizar o componente de Imagem de Angular existente
app-image
simplesmente passando o@Input
parâmetros decard.component.ts
. Posteriormente no tutorial, propriedades adicionais são adicionadas e exibidas.
Atualizar a política do modelo
Com este início Card
implementação revisar a funcionalidade no Editor SPA do AEM. Para ver o Card
componente é necessária uma atualização à política Modelo.
-
Implante o código inicial em uma instância local do AEM, se você ainda não tiver:
code language-shell $ cd aem-guides-wknd-spa $ mvn clean install -PautoInstallSinglePackage
-
Navegue até o modelo de página SPA em http://localhost:4502/editor.html/conf/wknd-spa-angular/settings/wcm/templates/spa-page-template/structure.html.
-
Atualize a política do Contêiner de layout para adicionar o novo
Card
componente como um componente permitido:Salve as alterações na política e observe as
Card
componente como um componente permitido:
Componente Cartão inicial do autor
Em seguida, crie o Card
usando o editor SPA AEM.
-
Navegue até http://localhost:4502/editor.html/content/wknd-spa-angular/us/en/home.html.
-
Entrada
Edit
, adicione oCard
componente para aLayout Container
: -
Arraste e solte uma imagem do Localizador de ativos na
Card
componente: -
Abra o
Card
caixa de diálogo do componente e observe a adição de um Texto Guia. -
Informe os seguintes valores no campo Texto guia:
Caminho do cartão - escolha uma página abaixo da página inicial do SPA.
Texto CTA - "Leia mais"
Título do cartão - deixe em branco
Obter título da página vinculada - marque a caixa de seleção para indicar verdadeiro.
-
Atualize o Metadados do ativo guia para adicionar valores a Texto alternativo e Legenda.
No momento, nenhuma alteração adicional é exibida após a atualização da caixa de diálogo. Para expor os novos campos ao componente de Angular, precisamos atualizar o Modelo do Sling para o
Card
componente. -
Abra uma nova guia e acesse CRXDE-Lite. Inspect nos nós de conteúdo abaixo de
/content/wknd-spa-angular/us/en/home/jcr:content/root/responsivegrid
para encontrar oCard
conteúdo do componente.Observe que as
cardPath
,ctaText
,titleFromPage
são mantidos pela caixa de diálogo.
Atualizar modelo Sling do cartão
Para expor os valores da caixa de diálogo do componente para o componente do Angular, precisamos atualizar o Modelo do Sling que preenche o JSON para o Card
componente. Também temos a oportunidade de implementar duas partes da lógica de negócios:
- Se
titleFromPage
para true, retorna o título da página especificada porcardPath
caso contrário, retorna o valor decardTitle
campo de texto. - Retorna a data da última modificação da página especificada por
cardPath
.
Retorne ao IDE de sua escolha e abra o core
módulo.
-
Abra o arquivo
Card.java
emcore/src/main/java/com/adobe/aem/guides/wknd/spa/angular/core/models/Card.java
.Observe que
Card
a interface atualmente estendecom.adobe.cq.wcm.core.components.models.Image
e, portanto, herda os métodos da variávelImage
interface. A variávelImage
A interface da já estende oComponentExporter
que permite que o Modelo Sling seja exportado como JSON e mapeado pelo editor de SPA. Portanto, não precisamos estender explicitamenteComponentExporter
como fizemos na Capítulo Componente personalizado. -
Adicione os seguintes métodos à interface:
code language-java @ProviderType public interface Card extends Image { /*** * The URL to populate the CTA button as part of the card. * The link should be based on the cardPath property that points to a page. * @return String URL */ public String getCtaLinkURL(); /*** * The text to display on the CTA button of the card. * @return String CTA text */ public String getCtaText(); /*** * The date to be displayed as part of the card. * This is based on the last modified date of the page specified by the cardPath * @return */ public Calendar getCardLastModified(); /** * Return the title of the page specified by cardPath if `titleFromPage` is set to true. * Otherwise return the value of `cardTitle` * @return */ public String getCardTitle(); }
Esses métodos são expostos por meio da API do modelo JSON e passados para o componente Angular.
-
Abertura
CardImpl.java
. Trata-se da implementação doCard.java
interface. Esta implementação foi parcialmente removida para acelerar o tutorial. Observe o uso da variável@Model
e@Exporter
anotações para garantir que o Modelo do Sling possa ser serializado como JSON por meio do Exportador de modelos do Sling.CardImpl.java
também usa o Padrão de delegação para modelos do Sling para evitar a regravação da lógica do Componente principal de imagem. -
Observe as seguintes linhas:
code language-java @Self @Via(type = ResourceSuperType.class) private Image image;
A anotação acima instancia um objeto de Imagem chamado
image
com base nosling:resourceSuperType
herança doCard
componente.code language-java @Override public String getSrc() { return null != image ? image.getSrc() : null; }
É então possível utilizar simplesmente a variável
image
objeto para implementar métodos definidos peloImage
sem ter que escrever a lógica nós mesmos. Essa técnica é usada paragetSrc()
,getAlt()
, egetTitle()
. -
Em seguida, implemente o
initModel()
método para iniciar uma variável privadacardPage
com base no valor decardPath
code language-java @PostConstruct public void initModel() { if(StringUtils.isNotBlank(cardPath) && pageManager != null) { cardPage = pageManager.getPage(this.cardPath); } }
A variável
@PostConstruct initModel()
é chamado quando o modelo Sling é inicializado, portanto, é uma boa oportunidade para inicializar objetos que podem ser usados por outros métodos no modelo. A variávelpageManager
é um dos vários Objetos globais com suporte de Java™ disponibilizado para Modelos do Sling por meio da@ScriptVariable
anotação. A variável getPage O método assume um caminho e retorna um AEM Página objeto ou nulo se o caminho não apontar para uma página válida.Isso inicializa o
cardPage
que é usada pelos outros novos métodos para retornar dados sobre a página vinculada subjacente. -
Revise as variáveis globais já mapeadas para as propriedades JCR salvas na caixa de diálogo do autor. A variável
@ValueMapValue
A anotação é usada para executar o mapeamento automaticamente.code language-java @ValueMapValue private String cardPath; @ValueMapValue private String ctaText; @ValueMapValue private boolean titleFromPage; @ValueMapValue private String cardTitle;
Essas variáveis são usadas para implementar os métodos adicionais para a variável
Card.java
interface. -
Implementar os métodos adicionais definidos no
Card.java
interface:code language-java @Override public String getCtaLinkURL() { if(cardPage != null) { return cardPage.getPath() + ".html"; } return null; } @Override public String getCtaText() { return ctaText; } @Override public Calendar getCardLastModified() { if(cardPage != null) { return cardPage.getLastModified(); } return null; } @Override public String getCardTitle() { if(titleFromPage) { return cardPage != null ? cardPage.getTitle() : null; } return cardTitle; }
note note NOTE É possível exibir a CardImpl.java concluído aqui. -
Abra uma janela de terminal e implante apenas as atualizações no
core
módulo usando o MavenautoInstallBundle
perfil docore
diretório.code language-shell $ cd core/ $ mvn clean install -PautoInstallBundle
Se estiver usando AEM 6.x adicione o
classic
perfil. -
Visualize a resposta do modelo JSON em: http://localhost:4502/content/wknd-spa-angular/us/en.model.json e pesquise por
wknd-spa-angular/components/card
:code language-json "card": { "ctaText": "Read More", "cardTitle": "Page 1", "title": "Woman chillaxing with river views in Australian bushland", "src": "/content/wknd-spa-angular/us/en/home/_jcr_content/root/responsivegrid/card.coreimg.jpeg/1595190732886/adobestock-216674449.jpeg", "alt": "Female sitting on a large rock relaxing in afternoon dappled light the Australian bushland with views over the river", "cardLastModified": 1591360492414, "ctaLinkURL": "/content/wknd-spa-angular/us/en/home/page-1.html", ":type": "wknd-spa-angular/components/card" }
Observe que o modelo JSON é atualizado com pares chave/valor adicionais após atualizar os métodos na
CardImpl
Modelo do Sling.
Atualizar componente do Angular
Agora que o modelo JSON foi preenchido com novas propriedades para ctaLinkURL
, ctaText
, cardTitle
, e cardLastModified
podemos atualizar o componente Angular para exibi-los.
-
Retorne ao IDE e abra o
ui.frontend
módulo. Como opção, inicie o servidor de desenvolvimento do webpack a partir de uma nova janela do terminal para ver as alterações em tempo real:code language-shell $ cd ui.frontend $ npm install $ npm start
-
Abertura
card.component.ts
emui.frontend/src/app/components/card/card.component.ts
. Adicione o adicional@Input
anotações para capturar o novo modelo:code language-diff export class CardComponent implements OnInit { @Input() src: string; @Input() alt: string; @Input() title: string; + @Input() cardTitle: string; + @Input() cardLastModified: number; + @Input() ctaLinkURL: string; + @Input() ctaText: string;
-
Adicione métodos para verificar se a Chamada para ação está pronta e para retornar uma string de data/hora com base na variável
cardLastModified
entrada:code language-js export class CardComponent implements OnInit { ... get hasCTA(): boolean { return this.ctaLinkURL && this.ctaLinkURL.trim().length > 0 && this.ctaText && this.ctaText.trim().length > 0; } get lastModifiedDate(): string { const lastModifiedDate = this.cardLastModified ? new Date(this.cardLastModified) : null; if (lastModifiedDate) { return lastModifiedDate.toLocaleDateString(); } return null; } ... }
-
Abertura
card.component.html
e adicione a seguinte marcação para exibir o título, a chamada para ação e a data da última modificação:code language-html <div class="card" *ngIf="hasContent"> <app-image class="card__image" [src]="src" [alt]="alt" [title]="title"></app-image> <div class="card__content"> <h2 class="card__title"> {{cardTitle}} <span class="card__lastmod" *ngIf="lastModifiedDate">{{lastModifiedDate}}</span> </h2> <div class="card__action-container" *ngIf="hasCTA"> <a [routerLink]="ctaLinkURL" class="card__action-link" [title]="ctaText"> {{ctaText}} </a> </div> </div> </div>
As regras de acesso já foram adicionadas em
card.component.scss
para estilizar o título, o plano de ação e a data da última modificação.note note NOTE Você pode visualizar o concluído Código do componente do cartão de angular aqui. -
Implante as alterações completas no AEM a partir da raiz do projeto usando o Maven:
code language-shell $ cd aem-guides-wknd-spa $ mvn clean install -PautoInstallSinglePackage
-
Navegue até http://localhost:4502/editor.html/content/wknd-spa-angular/us/en/home.html para ver o componente atualizado:
-
Você deve ser capaz de recriar o conteúdo existente para criar uma página semelhante ao seguinte:
Parabéns. congratulations
Parabéns, você aprendeu a estender um componente AEM e como os Modelos e caixas de diálogo do Sling funcionam com o modelo JSON.
Você sempre pode exibir o código concluído em GitHub ou confira o código localmente alternando para a ramificação Angular/extend-component-solution
.