Os componentes são o núcleo da criação de uma experiência no AEM. A variável Componentes principais e a variável Arquétipo de projeto AEM simplificar a introdução a um conjunto de ferramentas de componentes robustos e prontos. A variável Tutorial do WKND orienta o desenvolvedor sobre como usar essas ferramentas e como criar componentes personalizados para criar um site de AEM.
Antes de fazer referência a este documento, verifique se você concluiu a Tutorial do WKND e, por conseguinte, estão familiarizados com a Componentes principais e a variável Arquétipo de projeto AEM.
Como o Tutorial WKND aborda a maioria dos casos de uso, este documento serve apenas como um complemento para esses recursos. Ele fornece especificações técnicas detalhadas sobre como os componentes são estruturados e configurados no AEM e não tem a intenção de ser um guia de introdução.
Esta seção aborda os principais conceitos e problemas como uma introdução aos detalhes necessários ao desenvolver seus próprios componentes.
Antes de começar a realmente configurar ou codificar seu componente, você deve perguntar:
Antes de investir tempo na criação de um componente totalmente novo, considere personalizar ou estender componentes existentes. Os Componentes principais oferecem um conjunto de componentes flexíveis, robustos e bem testados, prontos para produção.
Os Componentes principais também oferecem limpar padrões de personalização que você pode usar para adaptá-los às necessidades do seu próprio projeto.
Os componentes também podem ser redefinidos com uma sobreposição com base na lógica do caminho de pesquisa. No entanto, nesse caso, a Fusão de recursos do Sling não será acionado e /apps
deve definir toda a sobreposição.
Também é possível substituir uma caixa de diálogo de componente usando o Sling Resource Merger e definindo a propriedade sling:resourceSuperType
.
Isso significa que você só precisa redefinir as diferenças necessárias, em vez de redefinir toda a caixa de diálogo.
Seu componente é renderizado com HTML. Seu componente deve definir o HTML necessário para obter o conteúdo necessário e, em seguida, renderizá-lo conforme necessário nos ambientes do autor e de publicação.
É recomendável manter o código responsável pela marcação e renderização separado do código que controla a lógica usada para selecionar o conteúdo do componente.
Essa filosofia é apoiada pela HTL, uma linguagem de modelo que é propositalmente limitada para garantir que uma linguagem de programação real seja usada para definir a lógica de negócios subjacente. Esse mecanismo destaca o código chamado para uma determinada exibição e, se necessário, permite uma lógica específica para diferentes exibições do mesmo componente.
Essa lógica (opcional) pode ser implementada de diferentes maneiras e é invocada do HTL com comandos específicos:
A estrutura de um componente AEM é poderosa e flexível. As principais partes são:
Um elemento-chave da estrutura é o tipo de recurso.
Essa é uma abstração que ajuda a garantir que, mesmo quando a aparência muda com o tempo, a intenção permanece no tempo.
A definição de um componente pode ser dividida da seguinte forma:
/libs/core/wcm/components
./apps/<myApp>/components
.cq:Component
e têm os seguintes elementos-chave:
cq:Component
definição.<mycomponent> (cq:Component)
- Nó hierárquico do componente.jcr:title
- Título do componente; por exemplo, usado como um rótulo quando o componente é listado no Navegador de componentes e Console de componentesjcr:description
- Descrição do componente; usado como dica de passar o mouse sobre o navegador de componentes e console Componentescq:editConfig (cq:EditConfig)
- Define as propriedades de edição do componente e permite que o componente seja exibido no Navegador de componentes
cq:childEditConfig (cq:EditConfig)
- Controla os aspectos da interface do usuário do autor para componentes secundários que não definem seus próprios cq:editConfig
.cq:dialog (nt:unstructured)
- Caixa de diálogo para este componente. Define a interface que permite ao usuário configurar o componente e/ou editar conteúdo.cq:design_dialog (nt:unstructured)
- Edição de design para este componenteO ícone ou a abreviação do componente é definido por meio das propriedades JCR do componente quando ele é criado pelo desenvolvedor. Essas propriedades são avaliadas na seguinte ordem e a primeira propriedade válida encontrada é usada.
cq:icon
- Propriedade de string que aponta para um ícone padrão no Biblioteca da interface de usuário Coral para exibir no navegador de componentes
abbreviation
- Propriedade de string para personalizar a abreviação do nome do componente no navegador de componentes
jcr:title
propriedade.
abbreviation_commentI18n
que é usada como dica de tradução.cq:icon.png
ou cq:icon.svg
- Ícone para este componente, que é mostrado no Navegador de componentes
.png
e .svg
arquivos são suportados._cq_icon.png
ou _cq_icon.svg
por exemplo..png
tem precedência sobre .svg
se ambos estiverem presentes.Se nenhuma das propriedades acima (cq:icon
, abbreviation
, cq:icon.png
ou cq:icon.svg
) são encontrados no componente:
sling:resourceSuperType
propriedade.jcr:title
propriedade do componente atual.Para cancelar a herança de ícones de supercomponentes, defina um valor vazio abbreviation
no componente reverterá para o comportamento padrão.
A variável Console de componentes mostra como o ícone de um componente específico é definido.
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "https://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" id="Layer_1" xmlns="https://www.w3.org/2000/svg" xmlns:xlink="https://www.w3.org/1999/xlink" x="0px" y="0px"
width="20px" height="20px" viewBox="0 0 20 20" enable-background="new 0 0 20 20" xml:space="preserve">
<ellipse cx="5" cy="5" rx="3" ry="3" fill="#707070"/>
<ellipse cx="15" cy="5" rx="4" ry="4" fill="#707070"/>
<ellipse cx="5" cy="15" rx="5" ry="5" fill="#707070"/>
<ellipse cx="15" cy="15" rx="4" ry="4" fill="#707070"/>
</svg>
Muitos nós/propriedades necessários para definir um componente são comuns a ambas as interfaces do usuário, com diferenças permanecendo independentes para que seu componente possa funcionar em ambos os ambientes.
Um componente é um nó do tipo cq:Component
e tem as seguintes propriedades e nós filhos:
Nome | Tipo | Descrição |
---|---|---|
. |
cq:Component |
Representa o componente atual. Um componente é do tipo de nó cq:Component . |
componentGroup |
String |
Representa o grupo sob o qual o componente pode ser selecionado na Navegador de componentes. Um valor que começa com . é usado para componentes que não estão disponíveis para seleção na interface do usuário, como componentes básicos dos quais outros componentes herdam. |
cq:isContainer |
Boolean |
Isso indica se o componente é um componente de contêiner e, portanto, pode conter outros componentes, como um sistema de parágrafo. |
cq:dialog |
nt:unstructured |
Essa é a definição da caixa de diálogo de edição do componente. |
cq:design_dialog |
nt:unstructured |
Esta é a definição da caixa de diálogo de design do componente. |
cq:editConfig |
cq:EditConfig |
Isso define o editar configuração do componente. |
cq:htmlTag |
nt:unstructured |
Isso retorna atributos de tag adicionais que são adicionados à tag HTML ao redor. Permite a adição de atributos aos divs gerados automaticamente. |
cq:noDecoration |
Boolean |
Se true, o componente não será renderizado com as classes div e css geradas automaticamente. |
cq:template |
nt:unstructured |
Se encontrado, esse nó será usado como um template de conteúdo quando o componente for adicionado do Navegador de componentes. |
jcr:created |
Date |
Esta é a data de criação do componente. |
jcr:description |
String |
Esta é a descrição do componente. |
jcr:title |
String |
Este é o título do componente. |
sling:resourceSuperType |
String |
Quando definido, o componente herda deste componente. |
component.html |
nt:file |
Esse é o arquivo de script HTL do componente. |
cq:icon |
String |
Esse valor aponta para a variável ícone do componente e aparece no Navegador de componentes. |
Se você observar o Texto é possível ver vários destes elementos:
As propriedades de particular interesse incluem:
jcr:title
- Este é o título do componente usado para identificá-lo no Navegador de componentes.jcr:description
- Esta é a descrição do componente.sling:resourceSuperType
- Indica o caminho da herança ao estender um componente (substituindo uma definição).Os nós filhos de interesse específico incluem:
cq:editConfig
- Controla os aspectos visuais do componente durante a edição.cq:dialog
- Isso define a caixa de diálogo para editar o conteúdo desse componente.cq:design_dialog
- Especifica as opções de edição de design para este componente.As caixas de diálogo são um elemento essencial do componente, pois fornecem uma interface para os autores configurarem o componente em uma página de conteúdo e fornecem entrada para esse componente. Consulte a documentação de criação para obter detalhes sobre como os autores de conteúdo interagem com os componentes.
Dependendo da complexidade do componente, sua caixa de diálogo pode precisar de uma ou mais guias.
Caixas de diálogo para componentes do AEM:
cq:dialog
nós do tipo nt:unstructured
.cq:Component
nós e ao lado de suas definições de componente.sling:resourceType
propriedade.nt:unstructured
com o necessário sling:resourceType
propriedade.Na caixa de diálogo, os campos individuais são definidos:
As caixas de diálogo de design são semelhantes às caixas de diálogo usadas para editar e configurar conteúdo, mas fornecem a interface para que os autores de modelo pré-configurem e forneçam detalhes de design para esse componente em um modelo de página. Os modelos de página são usados pelos autores de conteúdo para criar páginas de conteúdo. Consulte a documentação do modelo para obter detalhes sobre como os modelos são criados.
As caixas de diálogo de design são usadas ao editar um modelo de página, embora eles não sejam necessários para todos os componentes. Por exemplo, a variável Título e Componentes da imagem ambos têm diálogos de design, enquanto o Mídias sociais que compartilham o componente não.
A interface do Coral e a interface do Granite definem a aparência do AEM.
A interface do usuário do Granite fornece uma grande variedade de widgets básicos necessários para criar sua caixa de diálogo no ambiente de criação. Quando necessário, é possível estender essa seleção e criar seu próprio widget.
Para obter detalhes adicionais, consulte os seguintes recursos:
Para criar um widget para uso em uma caixa de diálogo de componente, é necessário criar um componente de campo da interface do Granite.
Se você considerar sua caixa de diálogo como um contêiner simples para um elemento de formulário, também poderá ver o conteúdo principal do seu conteúdo da caixa de diálogo como campos de formulário. A criação de um novo campo de formulário requer a criação de um tipo de recurso; isso é equivalente à criação de um componente. Para ajudá-lo nessa tarefa, a interface do usuário do Granite oferece um componente de campo genérico do qual herdar (usando sling:resourceSuperType
):
/libs/granite/ui/components/coral/foundation/form/field
Mais especificamente, a interface do usuário do Granite fornece uma variedade de componentes de campo adequados para uso em diálogos ou, de modo mais geral, no formulários.
Depois de criar o tipo de recurso, é possível instanciar o campo adicionando um novo nó na caixa de diálogo, com a propriedade sling:resourceType
referindo-se ao tipo de recurso que acabou de introduzir.
Também é possível usar as condições de renderização (rendercondition
) para controlar quem tem acesso a guias/campos específicos na caixa de diálogo; por exemplo:
+ mybutton
- sling:resourceType = granite/ui/components/coral/foundation/button
+ rendercondition
- sling:resourceType = myapp/components/renderconditions/group
- groups = ["administrators"]
Depois de criar um componente, você deve ativá-lo para usá-lo. Seu uso mostra como a estrutura do componente está relacionada à estrutura do conteúdo resultante no repositório.
Depois que um componente é definido, ele deve ser disponibilizado para uso. Para disponibilizar um componente para uso em um modelo, você deve ativar o componente na política do contêiner de layout do modelo.
Consulte a documentação do modelo para obter detalhes sobre como os modelos são criados.
Se criarmos e configurarmos uma instância do Título na página: /content/wknd/language-masters/en/adventures/extreme-ironing.html
Assim, podemos ver a estrutura do conteúdo criado no repositório:
Em particular, se você observar o texto real de um Componente de Título:
jcr:title
propriedade que contém o texto real do título inserido pelo autor.sling:resourceType
referência à definição do componente.As propriedades definidas dependem das definições individuais. Embora possam ser mais complexas do que as anteriores, seguem ainda os mesmos princípios básicos.
Os componentes dentro do AEM estão sujeitos à Hierarquia de tipo de recurso. Isso é usado para estender componentes usando a propriedade sling:resourceSuperType
. Isso permite que o componente herde de outro componente.
Consulte a seção Reutilizar componentes para obter mais informações.
Esta seção explica como configurar o comportamento de edição de um componente. Isso inclui atributos como ações disponíveis para o componente, características do editor in.place e os ouvintes relacionados aos eventos no componente.
O comportamento de edição de um componente é configurado adicionando um cq:editConfig
nó do tipo cq:EditConfig
abaixo do nó do componente (do tipo cq:Component
) e adicionando propriedades específicas e nós filhos. As seguintes propriedades e nós filhos estão disponíveis:
cq:editConfig
propriedades do nócq:editConfig
nós filhos:
cq:dropTargets
(tipo de nó nt:unstructured
): define uma lista de destinos de lançamento que podem aceitar um lançamento de um ativo do localizador de conteúdo (um único destino de lançamento é permitido)cq:inplaceEditing
(tipo de nó cq:InplaceEditingConfig
): define uma configuração de edição no local para o componentecq:listeners
(tipo de nó cq:EditListenersConfig
): define o que acontece antes ou depois de uma ação ocorrer no componenteHá muitas configurações existentes no AEM. Você pode pesquisar facilmente por propriedades específicas ou nós secundários usando a ferramenta Query no CRXDE Lite.
Os componentes sempre devem renderizar algum HTML que esteja visível para o autor, mesmo quando o componente não tiver conteúdo. Caso contrário, ela pode desaparecer visualmente da interface do editor, tornando-se tecnicamente presente, mas invisível na página e no editor. Nesse caso, os autores não poderão selecionar e interagir com o componente vazio.
Por esse motivo, os componentes devem renderizar um espaço reservado, desde que não renderizem nenhuma saída visível quando a página for renderizada no editor de páginas (quando o modo WCM for edit
ou preview
).
A marcação de HTML típica de um espaço reservado é a seguinte:
<div class="cq-placeholder" data-emptytext="Component Name"></div>
O script HTL típico que renderiza o HTML de espaço reservado acima é o seguinte:
<div class="cq-placeholder" data-emptytext="${component.properties.jcr:title}"
data-sly-test="${(wcmmode.edit || wcmmode.preview) && isEmpty}"></div>
No exemplo anterior, isEmpty
é uma variável que é verdadeira somente quando o componente não tem conteúdo e está invisível para o autor.
Para evitar repetição, a Adobe recomenda que os implementadores de componentes usem um modelo HTL para esses espaços reservados, como o fornecido pelos Componentes principais.
O uso do modelo no link anterior é feito com a seguinte linha de HTL:
<sly data-sly-use.template="core/wcm/components/commons/v1/templates.html"
data-sly-call="${template.placeholder @ isEmpty=!model.text}"></sly>
No exemplo anterior, model.text
é a variável verdadeira somente quando o conteúdo tem conteúdo e está visível.
Um exemplo de uso desse modelo pode ser visto nos Componentes principais, como no componente de Título.
A variável cq:dropTargets
nó (tipo de nó nt:unstructured
) define o alvo que pode aceitar a ação de soltar de um ativo arrastado do localizador de conteúdo. É um nó do tipo cq:DropTargetConfig
.
O nó filho do tipo cq:DropTargetConfig
define um alvo de soltar no componente.
Um editor local permite que o usuário edite o conteúdo diretamente no fluxo de conteúdo, sem a necessidade de abrir uma caixa de diálogo. Por exemplo, o padrão Texto e Título ambos os componentes têm um editor no local.
Um editor local não é necessário/significativo para cada tipo de componente.
A variável cq:inplaceEditing
nó (tipo de nó cq:InplaceEditingConfig
) define uma configuração de edição no local para o componente. Ele pode ter as seguintes propriedades:
Nome da Propriedade | Tipo de propriedade | Valor da propriedade |
---|---|---|
active |
Boolean |
true para ativar a edição no local do componente. |
configPath |
String |
Caminho da configuração do editor, que pode ser especificado por um nó de configuração |
editorType |
String |
Os tipos disponíveis são: plaintext para conteúdo não-HTML, title converte títulos gráficos em um texto sem formatação antes de iniciar a edição e text usa o Editor de Rich Text |
A configuração a seguir permite a edição no local do componente e define plaintext
conforme o tipo do editor:
<cq:inplaceEditing
jcr:primaryType="cq:InplaceEditingConfig"
active="{Boolean}true"
editorType="plaintext"/>
O método de manipulação de eventos em campos de diálogo é feito com ouvintes em um biblioteca do cliente.
Para inserir lógica no campo, você deve:
Para fazer isso, você precisa saber sobre a biblioteca de widgets subjacente com a qual deseja interagir. Consulte a documentação da interface do Coral para identificar a qual evento você deseja reagir.
A variável cq:listeners
nó (tipo de nó cq:EditListenersConfig
) define o que acontece antes ou depois de uma ação no componente. A tabela a seguir define suas possíveis propriedades.
Nome da Propriedade | Valor da propriedade |
---|---|
beforedelete |
O manipulador é acionado antes da remoção do componente. |
beforeedit |
O manipulador é acionado antes que o componente seja editado. |
beforecopy |
O manipulador é acionado antes que o componente seja copiado. |
beforeremove |
O manipulador é acionado antes que o componente seja movido. |
beforeinsert |
O manipulador é acionado antes da inserção do componente. |
beforechildinsert |
O manipulador é acionado antes que o componente seja inserido dentro de outro componente (somente contêineres). |
afterdelete |
O manipulador é acionado após a remoção do componente. |
afteredit |
O manipulador é acionado depois que o componente é editado. |
aftercopy |
O manipulador é acionado depois que o componente é copiado. |
afterinsert |
O manipulador é acionado após a inserção do componente. |
aftermove |
O manipulador é acionado depois que o componente é movido. |
afterchildinsert |
O manipulador é acionado depois que o componente é inserido dentro de outro componente (somente contêineres). |
No caso de componentes aninhados, há certas restrições nas ações definidas como propriedades na cq:listeners
nó. Para componentes aninhados, os valores das seguintes propriedades deve ser REFRESH_PAGE
:
aftermove
aftercopy
O manipulador de eventos pode ser implementado com uma implementação personalizada. Por exemplo, (onde project.customerAction
é um método estático):
afteredit = "project.customerAction"
O exemplo a seguir é equivalente ao REFRESH_INSERTED
configuração:
afterinsert="function(path, definition) { this.refreshCreated(path, definition); }"
Com a seguinte configuração, a página é atualizada depois que o componente é excluído, editado, inserido ou movido:
<cq:listeners
jcr:primaryType="cq:EditListenersConfig"
afterdelete="REFRESH_PAGE"
afteredit="REFRESH_PAGE"
afterinsert="REFRESH_PAGE"
afterMove="REFRESH_PAGE"/>
A validação de campo na interface do Granite e nos widgets da interface do Granite é feita usando o foundation-validation
API. Consulte a foundation-valdiation
Documentação do Granite para obter detalhes.
Se você tiver um JavaScript personalizado que deve ser executado somente quando a caixa de diálogo estiver disponível e pronta, você deve ouvir o dialog-ready
evento.
Esse evento é acionado sempre que a caixa de diálogo é carregada (ou recarregada) e está pronta para uso, o que significa que sempre que há uma alteração (criar/atualizar) no DOM da caixa de diálogo.
dialog-ready
O pode ser usado para conectar o código personalizado JavaScript que executa personalizações nos campos dentro de uma caixa de diálogo ou tarefas semelhantes.
A variável Modo WCM O cookie do é definido ao alternar para o modo de Visualização, mesmo quando a página não é atualizada.
Para componentes com uma renderização sensível ao Modo WCM, eles precisam ser definidos para se atualizarem especificamente e, em seguida, confiar no valor do cookie.
Como desenvolvedor, você deseja obter acesso fácil à documentação dos componentes para que possa entender rapidamente o seguinte:
Por isso, é muito fácil criar qualquer marcação de documentação existente disponível no próprio componente.
Tudo o que você precisa fazer é colocar um README.md
na estrutura do componente.
Essa marcação será exibida no campo Console de componentes.
A marcação compatível é a mesma para Fragmentos de conteúdo.