<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Beatriz Maciel</title>
    <description>The latest articles on Forem by Beatriz Maciel (@beatrizmaciel).</description>
    <link>https://forem.com/beatrizmaciel</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F692685%2F1668570f-1ef7-40d7-bcf7-ce9f52b219a3.png</url>
      <title>Forem: Beatriz Maciel</title>
      <link>https://forem.com/beatrizmaciel</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/beatrizmaciel"/>
    <language>en</language>
    <item>
      <title>Semi automatização de preenchimento de dialogs no AEM</title>
      <dc:creator>Beatriz Maciel</dc:creator>
      <pubDate>Wed, 13 Sep 2023 13:17:57 +0000</pubDate>
      <link>https://forem.com/beatrizmaciel/semi-automatizacao-de-preenchimento-de-dialogs-no-aem-30i4</link>
      <guid>https://forem.com/beatrizmaciel/semi-automatizacao-de-preenchimento-de-dialogs-no-aem-30i4</guid>
      <description>&lt;p&gt;Autoração de conteúdo de páginas pode ser uma das tarefas mais desestimulantes para desenvolvedores. Neste artigo buscarei explicar um exemplo de semi automatização para facilitar este processo. Devido à particularidades do editor do AEM, uma automatização completa não foi possível, mas esta solução está aberta a contribuições!&lt;br&gt;
Essa solução foi construída em parceria com &lt;a href="//linkedin.com/in/felipe-martins-maria-29041994"&gt;Felipe Martins&lt;/a&gt;.&lt;/p&gt;
&lt;h3&gt;
  
  
  Campos de Preenchimento
&lt;/h3&gt;

&lt;p&gt;Os campos a serem preenchidos estavam dentro de um multifield sem limite de elementos, e cada elemento contava com:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Textfield&lt;/li&gt;
&lt;li&gt;Pathfield&lt;/li&gt;
&lt;li&gt;Menu dropdown com duas opções&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A dialog que usamos de exemplo para preenchimento é a seguinte:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqlh165evr5gvrbtnnun1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqlh165evr5gvrbtnnun1.png" alt="Dialog modelo" width="513" height="367"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Cada campo tem um comportamento diferente para ser preenchido. É importante salientar que o pathfield recebia um path de arquivo do DAM do próprio AEM.&lt;/p&gt;
&lt;h3&gt;
  
  
  Desenvolvimento da solução
&lt;/h3&gt;

&lt;p&gt;Neste caso, precisamos fazer duas listas com as opções a serem completadas. Os elementos precisam ser inseridos um a um, como o exemplo a seguir:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;var links = ["/content/website/language-masters/en/home/arquivo01.pdf",
"/content/website/language-masters/en/home/arquivo02.pdf",
"/content/website/language-masters/en/home/arquivo03.pdf"]

var idsLinks = ["Arquivo 01","Arquivo 02","Arquivo 03"]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Neste exemplo temos três elementos, o primeiro link fará par com o primeiro idLink e assim sucessivamente.&lt;/p&gt;

&lt;h4&gt;
  
  
  ✏️ Textfield
&lt;/h4&gt;

&lt;p&gt;Como o editor do AEM conta com um HTML próprio, vamos utilizar as classes e ids já existentes nessa estrutura para acessar o campo de Textfield. Nesse caso, encontramos a única ocorrência de uma tag "mãe" e vamos acessar a classe correta na hierarquia para modificação.&lt;br&gt;
Foi importante identificar uma classe única para que a função não se perdesse e pudesse encontrar mais de uma opção de modificação. Dessa forma, encontramos a classe &lt;code&gt;coral-Well&lt;/code&gt;, que será a "mãe", enquanto e desceremos algumas tags até encontrarmos o campo de inserção de texto para popular o nosso textfield. Dessa forma:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$(".coral-Well div div.coral-Form-fieldwrapper:eq(0) input")[0].value = idsLinks[i];
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A &lt;a href="https://api.jquery.com/eq/"&gt;função eq()&lt;/a&gt; serve para identificar a posição do elemento. Usamos &lt;code&gt;value&lt;/code&gt; para adicionar o valor do índice correto, buscando-o na nossa lista &lt;code&gt;idsLinks&lt;/code&gt;.&lt;/p&gt;

&lt;h4&gt;
  
  
  ✏️ Pathfield
&lt;/h4&gt;

&lt;p&gt;Para popular o pathfield com conteúdo do DAM do AEM, utilizamos a função &lt;a href="http://api.jquery.com/attr/"&gt;attr()&lt;/a&gt;. É importante que o path esteja completo, desde &lt;code&gt;/content...&lt;/code&gt; até a propriedade do arquivo (no nosso caso, &lt;code&gt;.../arquivo01.pdf&lt;/code&gt;).&lt;br&gt;
O número de índice do &lt;code&gt;eq()&lt;/code&gt; mudou porque os campos da dialog do AEM tem o mesmo nome (&lt;code&gt;.coral-Form-fieldwrapper&lt;/code&gt;), e precisamos especificar qual dessas filhas de &lt;code&gt;.coral-Well&lt;/code&gt; queremos.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$("div.coral-Well div div.coral-Form-fieldwrapper:eq(1) foundation-autocomplete coral-taglist coral-tag").attr("value",links[numeral]);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;⚠️ &lt;em&gt;Atenção&lt;/em&gt; : Essa forma de preenchimento do pathfield não popula o campo de dialog do AEM visualmente, é necessário salvar as alterações para que o path entre corretamente.&lt;/p&gt;

&lt;h4&gt;
  
  
  ✏️ Menu dropdown
&lt;/h4&gt;

&lt;p&gt;Usamos a mesma lógica hierárquica para acessarmos nossa tag e/ou nossa classe desejada. A diferença de um seletor é que usaremos a função &lt;code&gt;click&lt;/code&gt; ao invés de popularmos com algum tipo de texto.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$(".coral-Well div div.coral-Form-fieldwrapper:eq(2) coral-select coral-overlay coral-selectlist coral-selectlist-item")[1].click();
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Também utilizamos a posição &lt;code&gt;[1]&lt;/code&gt; para especificar que queremos selecionar a segunda opção que apareça ao abrir o dropdown.&lt;/p&gt;

&lt;h3&gt;
  
  
  Montando a função
&lt;/h3&gt;

&lt;p&gt;Agora que desmembramos os campos e definimos suas especificidades, devemos aplicar todas essas ações em uma função e aplicar um índice que vai ser sempre modificado, porque a partir do momento que preenchermos um bloco de campos de um elementos, deveremos passar para o próximo. Por isso, vamos abraçar as funcionalidades dentro da função &lt;code&gt;preencheCampos()&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Além disso, precisamos de um índice para iteração, que vamos chamar de &lt;code&gt;numeral&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;⚠️ &lt;em&gt;Atenção&lt;/em&gt; : é importante evitarmos usar índices com letras, como tradicionalmente usamos (&lt;code&gt;i&lt;/code&gt;, &lt;code&gt;z&lt;/code&gt;, entre outros), porque o editor do AEM guarda arquivos minificados que trabalham com variáveis com estes nomes. Então é sempre bom escolher uma variável de nome mais específico, para não ser alterado pelo próprio AEM.&lt;/p&gt;

&lt;p&gt;Este &lt;code&gt;numeral&lt;/code&gt; será importante para posicionarmos os campos, ele funciona na iteração como o tradicional &lt;code&gt;i&lt;/code&gt;, e se certifica que estamos seguindo o array na ordem certa, enquanto o índice for menor do que &lt;code&gt;idsLinks.length&lt;/code&gt; (mas poderia ser menor do que &lt;code&gt;links.length&lt;/code&gt;, também, uma vez que eles têm a mesma quantidade de elementos e fazem duplas entre si).&lt;/p&gt;

&lt;p&gt;Para adicioná-lo, também vamos usar a função &lt;code&gt;eq()&lt;/code&gt; associada à classe única (.coral-Well), dessa forma:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$(".coral-Well:eq(" + numeral + ") div div.coral-Form-fieldwrapper:eq(0) input")[0].value = idsLinks[numeral];
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Também será necessário um segundo índice para o click no botão de &lt;code&gt;Add&lt;/code&gt;, porque o mesmo botão muda de posição de acordo com a quantidade de elementos que inserimos no multifield. Logo, teremos que iterá-lo com + 2 posições, dessa forma:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$(".coral-Form-fieldwrapper coral-multifield button.coral3-Button.coral3-Button--secondary")[numeralAdd].click();
numeralAdd+=2;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Por fim, montando todas essas partes, podemos finalmente construir uma função de preenchimento de campos, lembrando que é necessário atribuirmos o valor de 0 para o índice &lt;code&gt;numeral&lt;/code&gt; e 2 para o índice &lt;code&gt;numeralAdd&lt;/code&gt;, para que caminhe de dois em dois.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;numeral = 0;
numeralAdd = 2;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A função fica assim, então:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function preencheCampos(){
    console.log("Criando link do index " + numeral + ". ID " + idsLinks[numeral]);
    // Popula o textfield
    $(".coral-Well:eq(" + numeral + ") div div.coral-Form-fieldwrapper:eq(0) input")[0].value = idsLinks[numeral];

    // Define o pathfield
    $("div.coral-Well:eq(" + numeral + ") div div.coral-Form-fieldwrapper:eq(1) foundation-autocomplete coral-taglist coral-tag").attr("value",links[numeral]);

    // Seleciona uma opção no menu dropdown
    $(".coral-Well:eq(" + numeral + ") div div.coral-Form-fieldwrapper:eq(2) coral-select coral-overlay coral-selectlist coral-selectlist-item")[1].click();

    numeral++;
    // Clica no botão de add para adicionar um novo elemento
    if(numeral &amp;lt; idsLinks.length)
        $(".coral-Form-fieldwrapper coral-multifield button.coral3-Button.coral3-Button--secondary")[numeralAdd].click();
    else
        alert("Fim");
    numeralAdd+=2;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Por que semi automatizado?
&lt;/h3&gt;

&lt;p&gt;O editor do AEM pode ficar pesado com um loop de preenchimento e as tentativas de funções para automatizar de forma integral não foram bem sucedidas. Deixo esse tópico aberto à contribuições para pensar em formas de preenchimento de dialog de forma totalmente automatizada.&lt;/p&gt;

</description>
      <category>aem</category>
      <category>automation</category>
      <category>javascript</category>
      <category>jquery</category>
    </item>
    <item>
      <title>Content fragments em React no AEM | 🇧🇷</title>
      <dc:creator>Beatriz Maciel</dc:creator>
      <pubDate>Mon, 29 May 2023 18:36:09 +0000</pubDate>
      <link>https://forem.com/beatrizmaciel/content-fragments-em-react-no-aem--ofb</link>
      <guid>https://forem.com/beatrizmaciel/content-fragments-em-react-no-aem--ofb</guid>
      <description>&lt;p&gt;Uma das facilidades do AEM (Adobe Experience Manager) é usar content fragments, que são basicamente pedaços de conteúdo que podem ser reproduzidos em diversas partes do nosso site através de componentes.&lt;br&gt;
Neste artigo, vamos construir um componente react simples que consome os dados de um content fragment e renderiza na tela.&lt;/p&gt;
&lt;h2&gt;
  
  
  Passo a passo ✏️
&lt;/h2&gt;

&lt;p&gt;Primeiro precisamos criar um modelo de content fragment e um (ou mais) content fragment(s) no nosso AEM local. Para saber como criar um modelo de content fragment, acesse a &lt;a href="https://experienceleague.adobe.com/docs/experience-manager-cloud-service/content/assets/content-fragments/content-fragments-models.html?lang=pt-BR"&gt;documentação oficial&lt;/a&gt;. Depois de criar um modelo, é possível criar um content fragment que se utiliza desse padrão. Saiba como fazer isso através da &lt;a href="https://experienceleague.adobe.com/docs/experience-manager-cloud-service/content/assets/content-fragments/content-fragments-managing.html?lang=pt-BR"&gt;documentação oficial&lt;/a&gt; ou deste &lt;a href="https://youtu.be/A7h-iy3g23A"&gt;vídeo explicativo&lt;/a&gt; (em inglês)&lt;/p&gt;
&lt;h4&gt;
  
  
  📌 Modelo
&lt;/h4&gt;

&lt;p&gt;No meu caso construí o seguinte modelo de content fragment:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqrklw0486bjck109jflc.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqrklw0486bjck109jflc.png" alt="Modelo de content fragment" width="800" height="378"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Este modelo contém:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Dois campos de texto simples (título e subtítulo)&lt;/li&gt;
&lt;li&gt;Um campo de caminho (pathfield) para relacionar dois content fragments diferentes&lt;/li&gt;
&lt;li&gt;Um campo de texto rico (descrição)&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;O modelo pode conter muito mais campos e detalhes, mas lembre-se que geralmente o content fragment é utilizado para reproduzir um mesmo conteúdo várias vezes, o que faz com que quanto mais genérico seu modelo, melhor. Entretanto, cada situação pode exigir estruturas diferentes, então fique à vontade para criar.&lt;/p&gt;
&lt;h4&gt;
  
  
  📌 Content Fragment
&lt;/h4&gt;

&lt;p&gt;Uma vez criado o modelo, podemos habilitá-lo na pasta de asset que iremos utilizar para o nosso site. Depois de habilitado, criamos um novo content fragment que terá sempre os mesmos campos.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Foowwyipv17w01ld1u5s3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Foowwyipv17w01ld1u5s3.png" alt="Content fragment" width="800" height="370"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h4&gt;
  
  
  📌 Consumindo dados (AEM)
&lt;/h4&gt;

&lt;p&gt;Para consumir os dados desse content fragment no react vamos ter que criar um endpoint. Para isso acessamos o localhost:4502 &amp;gt; tools &amp;gt; general &amp;gt; graphql (ou apenas acesse &lt;a href="http://localhost:4502/libs/cq/graphql/sites/admin/content/console.html"&gt;http://localhost:4502/libs/cq/graphql/sites/admin/content/console.html&lt;/a&gt;).&lt;br&gt;
Clique no botão "create" e crie um novo endpoint referenciando o projeto desejado.&lt;br&gt;
Depois de criado, entramos novalmente em localhost:4502 &amp;gt; tools &amp;gt; general &amp;gt; graphql editor&lt;br&gt;
Selecionamos o endpoint no dropdown superior direito.&lt;/p&gt;

&lt;p&gt;No modelo que é aberto automaticamente, vamos editar a partir da linha 29, como sinalizado abaixo:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqo09iecko8qxr9v4nquh.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqo09iecko8qxr9v4nquh.png" alt="Graphql editor" width="800" height="683"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Vamos adicionar a estrutura que incluímos no nosso model. No caso do exemplo acima, teremos título, subtítulo e descrição. Lembrando que, uma vez que a descrição é um texto rico, devemos incluir a linguagem de marcação (html, json, etc)&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhedzalu2iy08vytjumyn.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhedzalu2iy08vytjumyn.png" alt="Graphql editor model" width="800" height="373"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Para confirmar se os dados estão retornando corretamente, clicamos no "play" superior para mostrar os dados na tela à direita. Depois disso, salvamos com um novo nome, publicamos (clicando no botão publish) e, ao aparecer na barra lateral esquerda, podemos copiar o url do novo endpoint&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpl5g6jjvhzdhsrxho0e7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpl5g6jjvhzdhsrxho0e7.png" alt="Copiando url do endpoint" width="352" height="292"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h4&gt;
  
  
  📌 Consumindo dados (React)
&lt;/h4&gt;

&lt;p&gt;Para consumir os dados que recebemos neste endpoint no react, criaremos um componente simples. Para que o AEM não se perca, sugiro criar uma dialog (em apps) e um model (em core/bundle), mas a parte principal será no front-end, onde criaremos o componente Content Fragment.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import React, { useEffect, useState } from 'react';

export default function ContentFragment(props) {
    const { title } = props;
    const [items, setItems] = useState([]);

    useEffect(() =&amp;gt; {
        getPosts();
    }, []);

    function getPosts() {
        fetch('/graphql/execute.json/your-project-name/posts', {
            method: 'GET',
            headers: {
                'Accept': 'application/json',
            }
        })
        .then(res =&amp;gt; res.json())
        .then(json =&amp;gt; {
            setItems(json.data.postList.items);
        })
        .catch(error =&amp;gt; {
            console.error('Error:', error);
        });
    }

    return (
        &amp;lt;section&amp;gt;
            &amp;lt;h1&amp;gt;Content Fragment&amp;lt;/h1&amp;gt;
            &amp;lt;p&amp;gt;{title}&amp;lt;/p&amp;gt;

            &amp;lt;ul&amp;gt;
                {items.map((item, index) =&amp;gt; (
                    &amp;lt;div key={index}&amp;gt;
                        &amp;lt;li&amp;gt;{item.title}&amp;lt;/li&amp;gt;
                        &amp;lt;li&amp;gt;{item.subtitle}&amp;lt;/li&amp;gt;
                        &amp;lt;li dangerouslySetInnerHTML={{ __html: item.description.html }} /&amp;gt;
                    &amp;lt;/div&amp;gt;
                ))}
            &amp;lt;/ul&amp;gt;
        &amp;lt;/section&amp;gt;
    );
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;O código acima é um exemplo de como conseguimos consumir os dados do endpoint criado no aem de forma simples.&lt;/p&gt;

&lt;p&gt;O comportamento desse componente é igual a qualquer outro componente react: deve ser importado no arquivo import-components.js, além de receber um MapTo para ser mapeado.&lt;/p&gt;

&lt;p&gt;Pronto! Agora você terá um componente AEM que recebe content fragments! Basta apenas arrastar na sua página de preferência&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbpxybz6244uwyiz0l6le.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbpxybz6244uwyiz0l6le.png" alt="Searching component in AEM" width="601" height="223"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3ai7akccwkd7widu4onf.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3ai7akccwkd7widu4onf.png" alt="Component used" width="800" height="181"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Na imagem acima podemos ver como o componente exemplo renderiza. A partir deste ponto você pode estilizá-lo como quiser, como um componente qualquer.&lt;/p&gt;

&lt;h2&gt;
  
  
  Referências
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://www.youtube.com/watch?v=TTmPSSh3Qqc"&gt;Content Fragment #1 | Content Fragments in aem - AEM GEEKS&lt;/a&gt; 📺&lt;/li&gt;
&lt;li&gt;&lt;a href="https://experienceleague.adobe.com/docs/experience-manager-cloud-service/content/assets/content-fragments/content-fragments.html?lang=en"&gt;Working with Content Fragments - Experience League&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://youtu.be/A7h-iy3g23A"&gt;Content Fragment #3 | Create Content Fragment and use on aem pages using core cf component - AEM GEEKS&lt;/a&gt; 📺&lt;/li&gt;
&lt;li&gt;&lt;a href="https://engineering.icf.com/using-a-content-fragment-api-in-react/"&gt;Using a Content Fragment API in React&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://experienceleague.adobe.com/docs/experience-manager-learn/getting-started-with-aem-headless/graphql/multi-step/explore-graphql-api.html?lang=en#:~:text=From%20the%20AEM%20Start%20screen,to%20Tools%20%3E%20General%20%3E%20GraphQL"&gt;Explore GraphQL APIs | Experience League&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://experienceleague.adobe.com/docs/experience-manager-65/developing/headless/delivery-api/content-fragments-graphql-samples.html?lang=en#sample-names-all-cities"&gt;Learning to use GraphQL with AEM - Sample Content and Queries | Experience League&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>react</category>
      <category>aem</category>
      <category>contentfragment</category>
    </item>
    <item>
      <title>Debug AEM com IntelliJ | 🇧🇷</title>
      <dc:creator>Beatriz Maciel</dc:creator>
      <pubDate>Thu, 19 Jan 2023 17:21:18 +0000</pubDate>
      <link>https://forem.com/beatrizmaciel/debug-aem-com-intellij--3993</link>
      <guid>https://forem.com/beatrizmaciel/debug-aem-com-intellij--3993</guid>
      <description>&lt;p&gt;Para debugar no AEM seguimos os seguintes passos:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Com o AEM desligado (sem inicializar ele), entramos nas pastas crx_quickstart &amp;gt; bin&lt;/li&gt;
&lt;li&gt;Clicamos do lado direito no arquivo start.bat e o abrimos em algum editor de texto&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F44ur6kt91u2lsgxak1yj.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F44ur6kt91u2lsgxak1yj.png" alt="Pasta AEM" width="800" height="321"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Na linha 25, precisamos mudar a configuração &lt;code&gt;set CQ_JVM_OPTS=-Xmx1024m&lt;/code&gt; para &lt;code&gt;set CQ_JVM_OPTS=-Xmx2048m&lt;/code&gt;, alterando o número.&lt;/li&gt;
&lt;li&gt;No final dessa linha também vamos inserir o seguinte comando: &lt;code&gt;-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=5005&lt;/code&gt;, como demonstrado na imagem abaixo.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F959mvrsc5ykp5a07v51w.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F959mvrsc5ykp5a07v51w.png" alt="Print do Arquivo start.bat" width="800" height="339"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  No IntelliJ
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Agora, com o IntelliJ aberto, clicamos no dropdown ao lado do martelo verde, e depois clicamos em &lt;code&gt;Edit Configurations...&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6l3nluzmkh9l20dmykf7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6l3nluzmkh9l20dmykf7.png" alt="Dropbox do IntelliJ" width="501" height="103"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Na janela que abrirá, clique no &lt;code&gt;+&lt;/code&gt; do canto superior esquerdo&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fa16xu5scmv80a68vale2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fa16xu5scmv80a68vale2.png" alt="Clicar em +" width="800" height="377"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Depois, clicamos em &lt;code&gt;Remote JVM Debug&lt;/code&gt; e daremos um nome para esse debugger. Note que, abaixo do campo para inserirmos o nome do nosso debugger, teremos o &lt;code&gt;Command line arguments for remote JVM&lt;/code&gt; que terá exatamente o mesmo código que colocamos no start.bat&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftduzaejint6z0oyz5cez.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftduzaejint6z0oyz5cez.png" alt="Remote JVM Debug" width="328" height="457"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7hwzhnxuw7873ya1em2i.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7hwzhnxuw7873ya1em2i.png" alt="Debugger" width="800" height="522"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Clique em &lt;code&gt;Apply&lt;/code&gt; e depois em &lt;code&gt;Ok&lt;/code&gt;. Agora o seu debugger será mostrado no mesmo checkbox que clicamos para adicioná-lo.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Pronto! 😉 Agora é só debugar seu código normalmente, usando o checkpoint (o marcador vermelho 🔴) e o inseto (bug 🪲) na parte superior da navegação do IntelliJ&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Observação:&lt;/strong&gt; para abrir o AEM em modo debug, utilize o seguinte comando no terminal (bash): &lt;code&gt;java -jar &amp;lt;arquivo jar&amp;gt; -debug 5005&lt;/code&gt;. Não esqueça de botar o nome completo do seu arquivo, por exemplo:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;java -jar aem-sdk-quickstart-2022.9.8630.20220905T184657Z-220800.jar -debug 5005&lt;/code&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Referências
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.mavice.com/blog/debugging-your-aem-6-4-application-in-intellij/"&gt;Debugging Your AEM 6.4 Application in IntelliJ&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>intellij</category>
      <category>tutorial</category>
      <category>aem</category>
      <category>debug</category>
    </item>
    <item>
      <title>Modelos de campos em uma dialog no AEM</title>
      <dc:creator>Beatriz Maciel</dc:creator>
      <pubDate>Tue, 18 Oct 2022 12:29:01 +0000</pubDate>
      <link>https://forem.com/beatrizmaciel/modelos-de-campos-em-uma-dialog-no-aem-2ik2</link>
      <guid>https://forem.com/beatrizmaciel/modelos-de-campos-em-uma-dialog-no-aem-2ik2</guid>
      <description>&lt;p&gt;Existem várias maneiras de construir dialogs nos componentes do AEM e a variedade de opções melhora a experiência do Author na construção da página. &lt;br&gt;
Através da necessidade de um acervo de modelos reutilizáveis e simples para as dialogs AEM, decidi criar este artigo com alguns dos principais tipos de campos utilizados e seus respectivos códigos, facilitando a vida do(a) desenvolvedor(a).&lt;br&gt;
Também vou explicar algumas propriedades dos campos e suas utilizações.&lt;/p&gt;
&lt;h3&gt;
  
  
  📌 Textfield
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;text
    jcr:primaryType="nt:unstructured"
    sling:resourceType="granite/ui/components/coral/foundation/form/textfield"
    fieldDescription="Insira um texto simples, de apenas uma linha"
    fieldLabel="Texto"
    required="{Boolean}true"
    name="./text"/&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Aqui temos um exemplo de textfield com algumas propriedades relevantes. O nome editável para que possamos pegar esse input no Java precisa ser repetido tanto na abertura da tag quanto no campo &lt;code&gt;name=""&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqx9mvgns3yj8dpzeynsd.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqx9mvgns3yj8dpzeynsd.png" alt="Textfield em uma dialog" width="540" height="111"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;1 - &lt;code&gt;required="{Boolean}true"&lt;/code&gt;&lt;br&gt;
2 - &lt;code&gt;fieldLabel="Texto"&lt;/code&gt;&lt;br&gt;
3 - &lt;code&gt;fieldDescription="Insira um texto simples, de apenas uma linha"&lt;/code&gt;&lt;br&gt;
4 - &lt;code&gt;sling:resourceType="granite/ui/components/coral/foundation/form/textfield"&lt;/code&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  📌 Textarea
&lt;/h3&gt;

&lt;p&gt;Tem a mesma propriedade do textfield, mas a área de texto é maior, o que facilidade a visualização do que está sendo digitado.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;constraintMessage
    jcr:primaryType="nt:unstructured"
    sling:resourceType="granite/ui/components/coral/foundation/form/textarea"
    fieldDescription="Escreva uma mensagem"
    fieldLabel="Mensagem simples com campo alargado"
    name="./constraintMessage"/&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcvog3afgm9in55lh0o1o.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcvog3afgm9in55lh0o1o.png" alt="Textarea example in dialog" width="525" height="179"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  📌 Fileupload
&lt;/h3&gt;

&lt;p&gt;Para que um author possa carregar arquivos na dialog de um componente podemos usar o seguinte modelo:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;img
    jcr:primaryType="nt:unstructured"
    sling:resourceType="cq/gui/components/authoring/dialog/fileupload"
    autoStart="{Boolean}true"
    fileNameParameter="./imgName"
    fileReferenceParameter="./img"
    mimeTypes="[image/gif,image/jpeg,image/png,image/webp,image/tiff,image/svg+xml]"
    multiple="{Boolean}false"
    name="./file"
    required="{Boolean}true"
    title="image.title"
    uploadUrl="${suffix.path}"
    allowUpload="{Boolean}false"
    fieldLabel="Imagem"
    useHTML5="{Boolean}true"/&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwlbx2h64ucvrq6zyzigk.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwlbx2h64ucvrq6zyzigk.png" alt="Exemplo de carregamento de imagem em uma dialog" width="541" height="159"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Além de receber um parâmetro de nome na imagem (mas poderia ser no documento, no vídeo, qualquer &lt;em&gt;asset&lt;/em&gt;), precisamos também receber um &lt;code&gt;fileReferenceParameter&lt;/code&gt; para identificá-la. &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;mimeTypes&lt;/code&gt; : limita os tipos de arquivos que podem ser carregados&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;multiple&lt;/code&gt; : limita a quantidade&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;uploadUrl="${suffix.path}"&lt;/code&gt; : captura paths do AEM&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;allowUpload="{Boolean}false"&lt;/code&gt; : é uma recomendação Adobe que os arquivos sejam carregados através do DAM e não diretamente upadas do arquivo do computador. É ideal então é que deixemos esse campo como false, mas pode ser modificado caso necessário&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  📌 Colorfield
&lt;/h3&gt;

&lt;p&gt;Seletor de cores em Hexa ou Rgb/a. O AEM gera cores padrões quando botamos &lt;code&gt;showDefaultColors="{Boolean}true"&lt;/code&gt; e pode começar com um valor já pré estabelecido configurado em &lt;code&gt;value="#000000"&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;color
    jcr:primaryType="nt:unstructured"
    sling:resourceType="granite/ui/components/coral/foundation/form/colorfield"
    fieldLabel="Selecione uma cor do texto"
    showDefaultColors="{Boolean}true"
    showProperties="{Boolean}true"
    showSwatches="{Boolean}true"
    autogenerateColors="off"
    value="#000000"
    name="./color"/&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fg1ql55ybnc95xech2zg1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fg1ql55ybnc95xech2zg1.png" alt="Colorfield fechado" width="529" height="89"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzvl9fudeibg01uw1xirl.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzvl9fudeibg01uw1xirl.png" alt="Colorfield aberto" width="282" height="168"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  📌 Richtext
&lt;/h3&gt;

&lt;p&gt;O richtext dá mais opções de texto, permitindo alterações pré-estabelecidas no código, como negrito, itálico, links, caracteres especiais, quebras de texto, listagens, etc. O código abaixo é um modelo com opções diversas, mas existem outras configurações possíveis (&lt;a href="https://experienceleague.adobe.com/docs/experience-manager-65/administering/operations/rich-text-editor.html?lang=en"&gt;aqui&lt;/a&gt; você pode encontrar algumas delas)&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;text
        jcr:primaryType="nt:unstructured"
        sling:resourceType="cq/gui/components/authoring/dialog/richtext"
        fieldDescription="Insira o texto a ser exibido. Você pode adicionar modificadores de formato."
        fieldLabel="Texto"
        name="./text"
        useFixedInlineToolbar="{Boolean}true"&amp;gt;
    &amp;lt;rtePlugins jcr:primaryType="nt:unstructured"&amp;gt;
        &amp;lt;edit
                jcr:primaryType="nt:unstructured"
                features="*"/&amp;gt;
        &amp;lt;format
                jcr:primaryType="nt:unstructured"
                features="*"/&amp;gt;
        &amp;lt;subsuperscript
                jcr:primaryType="nt:unstructured"
                features="*"/&amp;gt;
        &amp;lt;lists
                jcr:primaryType="nt:unstructured"
                features="*"/&amp;gt;
        &amp;lt;paraformat
                jcr:primaryType="nt:unstructured"
                features="*"&amp;gt;
            &amp;lt;formats jcr:primaryType="cq:WidgetCollection"&amp;gt;
                &amp;lt;heading2
                        jcr:primaryType="nt:unstructured"
                        description="Heading 2"
                        tag="h2"/&amp;gt;
                &amp;lt;heading3
                        jcr:primaryType="nt:unstructured"
                        description="Heading 3"
                        tag="h3"/&amp;gt;
                &amp;lt;myparagraph
                        jcr:primaryType="nt:unstructured"
                        description="Paragraph"
                        tag="p"/&amp;gt;
            &amp;lt;/formats&amp;gt;
        &amp;lt;/paraformat&amp;gt;
        &amp;lt;links
                jcr:primaryType="nt:unstructured"
                features="*"/&amp;gt;
        &amp;lt;misctools
                jcr:primaryType="nt:unstructured"
                features="*"/&amp;gt;
        &amp;lt;fullscreen
                jcr:primaryType="nt:unstructured"
                features="*"/&amp;gt;
        &amp;lt;/rtePlugins&amp;gt;
        &amp;lt;uiSettings jcr:primaryType="nt:unstructured"&amp;gt;
            &amp;lt;cui jcr:primaryType="nt:unstructured"&amp;gt;
                &amp;lt;inline
                    jcr:primaryType="nt:unstructured"
                    toolbar="[format#bold,format#italic,format#underline,subsuperscript#subscript,subsuperscript#superscript,#paraformat,image#imageProps,#justify,#lists,links#modifylink,links#unlink,links#anchor,misctools#specialchars]"&amp;gt;
                &amp;lt;popovers jcr:primaryType="nt:unstructured"&amp;gt;
                    &amp;lt;lists
                            jcr:primaryType="nt:unstructured"
                            items="[lists#unordered,lists#ordered]"
                            ref="lists"/&amp;gt;
                    &amp;lt;paraformat
                            jcr:primaryType="nt:unstructured"
                            items="paraformat:getFormats:paraformat-pulldown"
                            ref="paraformat"/&amp;gt;
                &amp;lt;/popovers&amp;gt;
            &amp;lt;/inline&amp;gt;
        &amp;lt;/cui&amp;gt;
    &amp;lt;/uiSettings&amp;gt;
&amp;lt;/text&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frr940sjkjc6vlzmj9j3c.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frr940sjkjc6vlzmj9j3c.png" alt="Richtext example" width="541" height="348"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  📌 NumberField
&lt;/h3&gt;

&lt;p&gt;Este modelo de numberfield atribui um número mínimo e máximo (&lt;code&gt;max="5"&lt;/code&gt; &lt;code&gt;min="0"&lt;/code&gt;) e um step, que faz com o que o author possa, além de digitar o número desejado, suba um a um utilizando as setas de controle. O Step pode ser em casas decimais e não necessariamente precisa de um mínimo ou máximo para esse campo, ele pode ser estruturado como for melhor.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;number
    jcr:primaryType="nt:unstructured"
    sling:resourceType="granite/ui/components/coral/foundation/form/numberfield"
    fieldLabel="Avaliação"
    fieldDescription="A partir de 1 as estrelas de avaliação aparecem no componente. 0 ou nulo fazem com que a avaliação não apareça."
    max="5"
    min="0"
    name="./number"
    step="1"
    required="{Boolean}false"/&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fi6nq8is948lp0qagk3dx.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fi6nq8is948lp0qagk3dx.png" alt="Numberfield example" width="356" height="82"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  📌 Multifield
&lt;/h3&gt;

&lt;p&gt;Às vezes precisamos de múltiplos campos para que o author escolha a quantidade de componentes a serem inseridos. Isso pode acontecer com imagens em um carrossel, com cards de artigos ou até com listas de links.&lt;br&gt;
É importante ressaltar que, quando temos um multifield, ele precisa ser primeiro chamado enquanto lista na classe Java principal com uma anotação &lt;code&gt;@ChildResource&lt;/code&gt; e, depois, precisa de uma classe própria para que cada elemento tenha suas próprias propriedades. Esses detalhes não serão abordados neste artigo.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;cards
        jcr:primaryType="nt:unstructured"
        sling:resourceType="granite/ui/components/coral/foundation/form/multifield"
        fieldDescription="Clique em '+' para adicionar um novo card"
        fieldLabel="Cards"
        composite="{Boolean}true"&amp;gt;
        &amp;lt;granite:data
                jcr:primaryType="nt:unstructured"
                min-item="1"
                max-item="10"/&amp;gt;
        &amp;lt;field
                granite:class="cmp-teaser__editor-action"
                jcr:primaryType="nt:unstructured"
                sling:resourceType="granite/ui/components/coral/foundation/container"
                name="./cards"&amp;gt;
            &amp;lt;items jcr:primaryType="nt:unstructured"&amp;gt;
                &amp;lt;accordion
                        granite:class="js-cq-IPEPlugin-container"
                        jcr:primaryType="nt:unstructured"
                        sling:resourceType="granite/ui/components/coral/foundation/accordion"
                        variant="quiet"&amp;gt;
                        &amp;lt;granite:data
                                jcr:primaryType="nt:unstructured"
                                accordion-title="./cardTitle"/&amp;gt;
                        &amp;lt;items jcr:primaryType="nt:unstructured"&amp;gt;
                                &amp;lt;cardList
                                        jcr:primaryType="nt:unstructured"
                                        jcr:title="Card"
                                        sling:resourceType="granite/ui/components/coral/foundation/container"
                                        maximized="{Boolean}true"&amp;gt;
                                        &amp;lt;items jcr:primaryType="nt:unstructured"&amp;gt;
                                                &amp;lt;cardTitle
                                                        jcr:primaryType="nt:unstructured"
                                                        sling:resourceType="granite/ui/components/coral/foundation/form/textfield"
                                                        fieldLabel="Título do card"
                                                        emptyText="Título"
                                                        name="./cardTitle"
                                                        required="{Boolean}true"/&amp;gt;
                                                &amp;lt;cardValue
                                                        jcr:primaryType="nt:unstructured"
                                                        sling:resourceType="granite/ui/components/coral/foundation/form/numberfield"
                                                        fieldLabel="Preço"
                                                        required="{Boolean}true"
                                                        step="1"
                                                        name="./cardValue"/&amp;gt;
                                        &amp;lt;/items&amp;gt;
                                &amp;lt;/cardList&amp;gt;
                        &amp;lt;/items&amp;gt;
                &amp;lt;/accordion&amp;gt;
            &amp;lt;/items&amp;gt;
        &amp;lt;/field&amp;gt;
&amp;lt;/cards&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxou6h04zea2sbcejzlqq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxou6h04zea2sbcejzlqq.png" alt="Multifield fechado" width="536" height="141"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Feaw83vl9yvpym0o3hm79.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Feaw83vl9yvpym0o3hm79.png" alt="Multifield aberto" width="530" height="301"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fl33bwkm11zqvujjg97tf.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fl33bwkm11zqvujjg97tf.png" alt="Propriedades de cada campo multifield" width="527" height="377"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;&amp;lt;accordion/&amp;gt;&lt;/code&gt; : a tag accordion se refere aos elementos de dentro dessa lista. Nesse caso, temos um cardList que é abraçado pelo cards. O accordion é a retração das informações de cada um desses elementos.
--&amp;gt; Logo abaixo do accordion temos uma tag  que configura os nomes de cada menu retrátil com o cardTitle.&lt;/li&gt;
&lt;li&gt;O cardList é um tipo de container que vai receber as informações de cada elemento, que nesse caso só tem título (textfield) e preço (numberfield), mas poderia ter quantos elementos fossem possíveis.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  📌 Select
&lt;/h3&gt;

&lt;p&gt;Podemos utilizar quantas opções forem necessárias em um selector e utilizando o seu &lt;code&gt;value&lt;/code&gt; como parâmetro.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;selector
        jcr:primaryType="nt:unstructured"
        sling:resourceType="granite/ui/components/coral/foundation/form/select"
        fieldLabel="Seletor de opções"
        name="./selector"&amp;gt;
        &amp;lt;items jcr:primaryType="nt:unstructured"&amp;gt;
                &amp;lt;red
                        jcr:primaryType="nt:unstructured"
                        text="Vermelho"
                        value="red"/&amp;gt;
                &amp;lt;yellow
                        jcr:primaryType="nt:unstructured"
                        text="Amarelo"
                        value="yellow"/&amp;gt;
        &amp;lt;/items&amp;gt;
&amp;lt;/selector&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fl9b1io16k1ak6nx3jlt7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fl9b1io16k1ak6nx3jlt7.png" alt="Select example in dialog" width="529" height="151"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  📌 Checkbox
&lt;/h3&gt;

&lt;p&gt;Um checkbox pode ser usado para devolver um parâmetro booleano. O campo &lt;code&gt;checked=""&lt;/code&gt; serve para delimitar se o campo por padrão deve vir marcado ou desmarcado.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;checkbox
  jcr:primaryType="nt:unstructured"
  sling:resourceType="granite/ui/components/coral/foundation/form/checkbox"
  fieldDescription="Selecione caso seja verdadeiro"
  name="./checkbox"
  text="Adicionar layout escuro"
  uncheckedValue="false"
  checked="true"
  value="true"/&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fo6yxny2d8hr9e35j0hr2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fo6yxny2d8hr9e35j0hr2.png" alt="Checkbox example in dialog" width="398" height="105"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  📌 Radiogroup
&lt;/h3&gt;

&lt;p&gt;Funciona como um seletor de opções, tal qual o selector.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;size
    jcr:primaryType="nt:unstructured"
    sling:resourceType="granite/ui/components/coral/foundation/form/radiogroup"
    fieldLabel="Selecione um tamanho de card"
    name="./size"
    vertical="{Boolean}true"&amp;gt;
        &amp;lt;items jcr:primaryType="nt:unstructured"&amp;gt;
            &amp;lt;small
                    jcr:primaryType="nt:unstructured"
                    checked="{Boolean}true"
                    text="Pequeno"
                    value="small"/&amp;gt;
            &amp;lt;medium
                    jcr:primaryType="nt:unstructured"
                    text="Médio"
                    value="medium"/&amp;gt;
            &amp;lt;large
                    jcr:primaryType="nt:unstructured"
                    text="Grande"
                    value="large"/&amp;gt;
        &amp;lt;/items&amp;gt;
&amp;lt;/size&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxi529eodhxfxsrxa21q1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxi529eodhxfxsrxa21q1.png" alt="Radiogroup example in dialog" width="407" height="151"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  📌 Datepicker
&lt;/h3&gt;

&lt;p&gt;O datepicker é útil como seletor de datas e pode incluir também horas e minutos. O formato é adaptável através da propriedade &lt;code&gt;displayedFormat=""&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;date
    jcr:primaryType="nt:unstructured"
    sling:resourceType="granite/ui/components/coral/foundation/form/datepicker"
    displayedFormat="DD-MM-YYYY HH:mm"
    fieldLabel="Selecione uma data"
    name="./date"
    type="datetime"
    typeHint="Date"/&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1kpome18dntdir05f55v.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1kpome18dntdir05f55v.png" alt="Datepicker example in dialog" width="526" height="487"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  📌 Pathbrowser &amp;amp; Pathfield
&lt;/h3&gt;

&lt;p&gt;O Pathbrowser serve tanto para redirecionamentos internos quanto externos (como urls). Entretanto, a Adobe sugere que sempre busquemos imagens no próprio banco de dados do AEM (no DAM).&lt;br&gt;
Neste caso o exemplo busca uma imagem, por isso o &lt;code&gt;rootPath=""&lt;/code&gt; é indicando para o &lt;code&gt;/content/dam&lt;/code&gt;. Este rootPath pode ser modificado conforme a necessidade.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;pathBrowser
    jcr:primaryType="nt:unstructured"
    sling:resourceType="granite/ui/components/coral/foundation/form/pathbrowser"
    fieldLabel="Selecione uma imagem"
    name="./pathBrowser"
    required="{Boolean}true"
    rootPath="/content/dam"/&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;pathField
    jcr:primaryType="nt:unstructured"
    sling:resourceType="granite/ui/components/coral/foundation/form/pathfield"
    fieldLabel="Url or path"
    name="./pathField"
    required="{Boolean}false"
    rootPath="/content/dam"/&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2zvtc35plt1ffxrbmanr.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2zvtc35plt1ffxrbmanr.png" alt="Pathbrowser example in dialog" width="523" height="77"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Referências
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://developer.adobe.com/experience-manager/reference-materials/6-5/granite-ui/api/jcr_root/libs/granite/ui/components/coral/foundation/server.html"&gt;Granite UI Foundation Server-side&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://experienceleague.adobe.com/docs/experience-manager-65/administering/operations/rich-text-editor.html?lang=en"&gt;Configure the Rich Text Editor - Experience League&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://gist.github.com/salomao-santos/0cd0240b9824b52a5fdf777ab712cfe2"&gt;Adobe Experience Manager (AEM) - Coral 3 – Granite UI components - Salomão Santos&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>adobeexperiencemanager</category>
      <category>aem</category>
      <category>beginners</category>
      <category>xml</category>
    </item>
    <item>
      <title>Guia SEO para desenvolvedores 2022</title>
      <dc:creator>Beatriz Maciel</dc:creator>
      <pubDate>Mon, 18 Jul 2022 01:05:38 +0000</pubDate>
      <link>https://forem.com/beatrizmaciel/guia-seo-para-desenvolvedores-2022-1log</link>
      <guid>https://forem.com/beatrizmaciel/guia-seo-para-desenvolvedores-2022-1log</guid>
      <description>&lt;h3&gt;
  
  
  O que é SEO?
&lt;/h3&gt;

&lt;p&gt;O Search Engine Optimization (SEO) significa, em tradução livre, "otimização do motor de busca" e tem como objetivo rankear websites nas pesquisas de sites como Google, Bing e Yahoo. É claro que hoje em dia focamos nossos esforços na pesquisa do Google, que tem sido a mais forte ferramenta de pesquisa online, mas as práticas de SEO são úteis para além dele.&lt;/p&gt;

&lt;p&gt;Os sites de busca têm robôs que são configurados para ler as páginas da web, identificando se o conteúdo que está ali é interessante para o usuário que faz a pesquisa. Ao entendermos como esses robôs funcionam, podemos deixar nosso site em evidência&lt;/p&gt;

&lt;h3&gt;
  
  
  📌 HTML5
&lt;/h3&gt;

&lt;p&gt;Existe muito conteúdo sobre SEO, mas no desenvolvimento vamos focar na estrutura HTML e, mais especificamente, nas convenções estabelecidas no &lt;a href="https://html.spec.whatwg.org/"&gt;HTML5&lt;/a&gt; e as tags que ele introduziu. No geral, um(a) programador(a) trabalha em conjunto quando pensamos em boas práticas de SEO e existem especialistas no assunto. Entretanto, em algumas situações podemos ter que fazer não só a parte de desenvolvimento como também de rankeamento do site. Para isso deixarei algumas referências no final do texto que são mais teóricas e conceituais. O foco aqui é entendermos a hierarquia e a relevância da programação nesse processo.&lt;/p&gt;

&lt;h4&gt;
  
  
  Tags
&lt;/h4&gt;

&lt;p&gt;Para nós, desenvolvedores, grande parte do trabalho de SEO consiste na organização das tags HTML de forma que os sites de pesquisa possam fazer o crawling (o "mapeamento" ou o "escaneamento") de forma correta.&lt;/p&gt;

&lt;p&gt;⚠️ &lt;em&gt;Importante:&lt;/em&gt; As tags que introduzimos no HTML são semânticas e não interferem no nosso layout, elas servem realmente para organizar o código e para que os robôs as leiam e as categorizem.&lt;/p&gt;

&lt;h5&gt;
  
  
  Estrutura
&lt;/h5&gt;

&lt;p&gt;Já conhecemos a estrutura do HTML: &lt;code&gt;&amp;lt;header&amp;gt;&amp;lt;/header&amp;gt;&lt;/code&gt; para as configurações da página e &lt;code&gt;&amp;lt;body&amp;gt;&amp;lt;/body&amp;gt;&lt;/code&gt; para o conteúdo que fica visível. O taggeamento mais importante que faremos ficará dentro da tag body, e falaremos dele a seguir.&lt;/p&gt;

&lt;h6&gt;
  
  
  Cabeçalho
&lt;/h6&gt;

&lt;p&gt;Para o cabecalho é importante usarmos a tag &lt;code&gt;&amp;lt;header&amp;gt;&amp;lt;/header&amp;gt;&lt;/code&gt;, especificando onde começa e onde termina nosso cabeçalho. Podemos ter mais de um cabeçalho.&lt;/p&gt;

&lt;h6&gt;
  
  
  Rodapé
&lt;/h6&gt;

&lt;p&gt;Usamos a tag &lt;code&gt;&amp;lt;footer&amp;gt;&amp;lt;/footer&amp;gt;&lt;/code&gt; para o rodapé. Podemos ter mais de um rodapés na página, como mostra a imagem a seguir:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fn1mtd6cqw5o8li2lyip0.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fn1mtd6cqw5o8li2lyip0.jpg" alt="Estrutura tags HTML para SEO" width="800" height="1000"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h6&gt;
  
  
  Seções
&lt;/h6&gt;

&lt;p&gt;A tag &lt;code&gt;&amp;lt;section&amp;gt;&amp;lt;/section&amp;gt;&lt;/code&gt; serve para delimitar o escopo de um componente ou conteúdo. Podemos ter várias sessões no nosso site e dentro delas provavelmente usaremos as tags &lt;code&gt;h (h1, h2, h3, h4, h5, h6)&lt;/code&gt;, &lt;code&gt;p&lt;/code&gt;, além de imagens e tantas outras coisas.&lt;/p&gt;

&lt;p&gt;⚠️ &lt;em&gt;Importante:&lt;/em&gt; Podemos usar a tag &lt;code&gt;&amp;lt;div&amp;gt;&amp;lt;/div&amp;gt;&lt;/code&gt;, mas ela é mais genérica e, portanto, menos rankeável. Antes de usar uma div se certifique se realmente não existe a possibilidade de deixar o elemento mais específico através de uma tag. Se tiver dúvidas, olhe sempre na &lt;a href="https://html.spec.whatwg.org/"&gt;documentação oficial do HTML5&lt;/a&gt;.&lt;/p&gt;

&lt;h6&gt;
  
  
  Imagens
&lt;/h6&gt;

&lt;p&gt;As imagens são muito importantes no rankeamento do nosso site. Vamos analisar essa estrutura de imagem, que está perfeitamente enquadrada semanticamente:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;figure&amp;gt;
    &amp;lt;img src="pasta/tema/nome.jpg" alt="Descição da Imagem" title="Titulo da Imagem"&amp;gt;
    &amp;lt;figcaption&amp;gt;Descição da Imagem&amp;lt;/figcaption&amp;gt;
&amp;lt;/figure&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Utilizamos a tag &lt;code&gt;&amp;lt;figure&amp;gt;&lt;/code&gt; para especificarmos o escopo da imagem. Nesse caso usamos duas tags internas: &lt;code&gt;&amp;lt;img&amp;gt;&lt;/code&gt; e &lt;code&gt;&amp;lt;figcaption&amp;gt;&amp;lt;/figcaption&amp;gt;&lt;/code&gt;, então faz sentido "abraçarmos" as duas com a tag &lt;code&gt;&amp;lt;figure&amp;gt;&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;A tag &lt;code&gt;&amp;lt;img&amp;gt;&lt;/code&gt; é bastante relevante para o SEO. Dentro dela é &lt;strong&gt;importantíssimo&lt;/strong&gt; usarmos &lt;code&gt;title&lt;/code&gt; e &lt;code&gt;alt&lt;/code&gt;. O &lt;code&gt;title&lt;/code&gt; serve para quando descansamos o mouse em cima da imagem e uma descrição aparece. Já o &lt;code&gt;alt&lt;/code&gt; serve para acessibilidade e não é visível quando a imagem carrega, somente no modo de visualização de acessibilidade. Essas duas especificações são essenciais para imagens e não podem ser esquecidas.&lt;/li&gt;
&lt;li&gt;Já a tag &lt;code&gt;&amp;lt;figcaption&amp;gt;&lt;/code&gt; serve para especificar a descrição da imagem, que pode ser mais extensa e detalhada.&lt;/li&gt;
&lt;/ol&gt;

&lt;h6&gt;
  
  
  Títulos e subtítulos
&lt;/h6&gt;

&lt;p&gt;A hierarquia é muito importante na semântica SEO, então quando falamos de títulos não seria diferente. Você pode ter quantos títulos e subtítulos quiser, mas é importante que respeite a hierarquia entre eles e sempre deixe títulos menores dentro de títulos maiores.&lt;br&gt;
Há quem defenda que cada página só deveria ter um &lt;code&gt;h1&lt;/code&gt;, mas isto não está escrito em pedra. Pela dúvida, mantenha o h1 com o mesmo título do seu site, exatamente o que deverá estar em evidência no motor de busca.&lt;/p&gt;

&lt;p&gt;⚠️ &lt;em&gt;Importante:&lt;/em&gt; o conteúdo das tags de título (&lt;code&gt;&amp;lt;title&amp;gt;&amp;lt;/title&amp;gt;&lt;/code&gt;) devem ter entre 50 e 60 caracteres. Não ultrapasse esse limite! Além disso, é aqui que deve estar as palavras chaves de busca do seu website, sendo as mais relevantes à esquerda.&lt;/p&gt;
&lt;h6&gt;
  
  
  Descrição
&lt;/h6&gt;

&lt;p&gt;Quando fazemos uma busca os sites costumam ser elencados através de seus títulos (que geralmente é o link clicável) e uma descrição. Os buscadores adicionam uma descrição automática por padrão, mas podemos também configurar a descrição usando palavras chave e chamando para a ação, de forma que o usuário se sinta impelido em clicar.&lt;br&gt;
A forma correta de fazer a descrição no HTML5 é a seguinte, dentro do &lt;code&gt;&amp;lt;header&amp;gt;&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;meta name="description" content="Insira uma descrição aqui"&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Geralmente a descrição fica abaixo da tag &lt;code&gt;&amp;lt;title&amp;gt;&lt;/code&gt; e deve ter menos de 156 caracteres. A descrição também deve ser única e deve conter a palavra-chave primária do website.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fz5gd2ib8cluy4ztmtwhe.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fz5gd2ib8cluy4ztmtwhe.png" alt="Exemplo de anúncio no Google" width="670" height="160"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;No exemplo acima vemos um anúncio de aspirador de pó. A descrição contém a "chamada para ação", que é o: "clique e confira as melhores ofertas". Uma descrição boa é sucinta, chama o usuário para ação e traz palavras-chaves relevantes.&lt;/p&gt;

&lt;h6&gt;
  
  
  Meta tags
&lt;/h6&gt;

&lt;p&gt;Você deve ter reparado que usamos uma tag &lt;code&gt;&amp;lt;meta&amp;gt;&lt;/code&gt; para escrevermos a descrição. As tags meta podem nos auxiliar se quisermos adicionar novas informações, como as palavras-chave, viewport, charset e o autor da página.&lt;/p&gt;

&lt;p&gt;Exemplos:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;!--- META KEYWORDS ---&amp;gt;
&amp;lt;meta name="keywords" content="HTML, CSS, Javascript"&amp;gt;

&amp;lt;!--- META CHARSET ---&amp;gt;
&amp;lt;meta charset="UTF-8"&amp;gt;

&amp;lt;!--- META EDGE ---&amp;gt;
&amp;lt;meta http-equiv="X-UA-Compatible" content="ie=edge"&amp;gt;

&amp;lt;!--- META AUTHOR ---&amp;gt;
&amp;lt;meta name="author" content="Sonia Guimarães"&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h6&gt;
  
  
  Canonical
&lt;/h6&gt;

&lt;p&gt;Uma URL canônica é a "principal" rota do site a ser mapeada pelo crawling. Se não definirmos isso no código, os robôs assumirão uma página a partir de suas métricas e algoritmos, por isso é importante descrevermos a URL principal do nosso site.&lt;br&gt;
⚠️ &lt;em&gt;Importante:&lt;/em&gt; Algumas vezes temos a mesma URL com pequenas diferenças, por exemplo:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;www.meusite.com
http://meusite.com
https://meusite.com
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Este caso pode confundir os crawlers, por isso é importante salientarmos qual é o link principal. Lembre-se: páginas https têm mais peso para as buscas, porque seguem um protocolo mais seguro.&lt;/p&gt;

&lt;p&gt;A sintaxe da URL canônica é a seguinte:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;link rel="canonical" href="https://example.com/dresses/green-dresses" /&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Você pode saber mais sobre URLs canônicas &lt;a href="https://developers.google.com/search/docs/advanced/crawling/consolidate-duplicate-urls"&gt;aqui&lt;/a&gt;.&lt;/p&gt;

&lt;h6&gt;
  
  
  Outras tags
&lt;/h6&gt;

&lt;p&gt;Como dito anteriormente, o HTML5 conta com diversas tags e seria impossível destacar todas aqui. Se você está em dúvida, pesquise na &lt;a href="https://html.spec.whatwg.org/"&gt;documentação oficial&lt;/a&gt; e confira se já não existe uma tag para o que você precisa. Algumas tags relevantes, além das que vimos anteriormente: &lt;code&gt;&amp;lt;article&amp;gt;&lt;/code&gt;, &lt;code&gt;&amp;lt;aside&amp;gt;&lt;/code&gt;, &lt;code&gt;&amp;lt;nav&amp;gt;&lt;/code&gt;, &lt;code&gt;&amp;lt;main&amp;gt;&lt;/code&gt;, &lt;code&gt;&amp;lt;button&amp;gt;&lt;/code&gt;, &lt;code&gt;&amp;lt;link&amp;gt;&lt;/code&gt;, &lt;code&gt;&amp;lt;address&amp;gt;&lt;/code&gt; e tantas outras.&lt;/p&gt;

&lt;h3&gt;
  
  
  📌 URL
&lt;/h3&gt;

&lt;p&gt;Outro detalhe importante para o rankeamento são as URLs amigáveis, ou seja, URLs que sejam facilmente legíveis pelos usuários. Evite usar códigos, números, letras e caracteres especiais e tente usar mais nomes separados por hífens e barras.&lt;/p&gt;

&lt;p&gt;Exemplo:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;http://www.meusite.com/produtos/perfumes&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;E evite coisas como:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;http://www.meusite.com/conteudo/produtos/uh6Djvf81/perfumes_0232&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;As URLs também devem ter menos de 115 caracteres, mas quanto menor, melhor.&lt;/p&gt;

&lt;h3&gt;
  
  
  📌 Crawling
&lt;/h3&gt;

&lt;p&gt;Crawling é o mapeamento que os robôs fazem em um website. Para guiar a facilitar o trabalho desses robôs existem dois tipos de arquivos importantes:&lt;/p&gt;

&lt;h4&gt;
  
  
  Robots.txt
&lt;/h4&gt;

&lt;p&gt;O robots.txt funciona como um arquivo de instruções para os robôs de motores de busca. Se o seu site tem poucas páginas não é necessário mexer necessariamente nesse arquivo. Aqui dizemos mais quais são as páginas que não queremos que os robôs façam a varredura.&lt;/p&gt;

&lt;p&gt;Um exemplo da sintaxe utilizada no arquivo é a seguinte:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;User-agent: Googlebot-news
Allow: /

User-agent: *
Disallow: /
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Aqui estamos permitindo que apenas o Googlebot mapeie o que está depois da barra (/) e estamos desautorizando os outros user-agents (outros robôs) a mapearam o que está depois da barra (/). Quando utilizamos o asterisco ( * ) queremos dizer &lt;em&gt;todos&lt;/em&gt;. Para saber mais sobre a sintaxe do robots.txt, &lt;a href="https://developers.google.com/search/docs/advanced/robots/create-robots-txt"&gt;clique aqui&lt;/a&gt;.&lt;/p&gt;

&lt;h4&gt;
  
  
  Sitemap.xml
&lt;/h4&gt;

&lt;p&gt;Como escrito no nome, este arquivo serve como Mapa do Site. Nele você deve listar as páginas do seu site que você quer que o site de buscas rastreie, guiando-o para seus conteúdos e páginas.&lt;br&gt;
É importante ressaltar, entretanto, que é "mais importante ter um site facilmente rastreável pelos robôs do que usar o sitemap.xml para contornar falhas na arquitetura do site" (&lt;a href="https://www.seomarketing.com.br/tutorial-seo/sitemap-xml-como-criar-e-configura-lo/"&gt;SEOMarketing&lt;/a&gt;).&lt;br&gt;
Podemos inserir até 50.000 URLs no arquivo sitemap.xml, sendo recomendação do próprio Google. O arquivo também pode ser criado de forma manual ou através de ferramentas.&lt;br&gt;
Um exemplo da sintaxe do sitemap.xml é a seguinte:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;urlset xmlns="https://www.sitemaps.org/schemas/sitemap/0.9"&amp;gt;
   &amp;lt;url&amp;gt;
      &amp;lt;loc&amp;gt;https://www.seusite.com.br&amp;lt;/loc&amp;gt;
      &amp;lt;lastmod&amp;gt;22-07-11&amp;lt;/lastmod&amp;gt;
      &amp;lt;changefreq&amp;gt;monthly&amp;lt;/changefreq&amp;gt;
      &amp;lt;priority&amp;gt;0.9&amp;lt;/priority&amp;gt;
   &amp;lt;/url&amp;gt;
&amp;lt;/urlset&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Para saber mais sobre o sitemap.xml, acesse &lt;a href="https://www.seomarketing.com.br/tutorial-seo/sitemap-xml-como-criar-e-configura-lo/"&gt;este arquivo completo&lt;/a&gt; do SEOMarketing.&lt;/p&gt;

&lt;h3&gt;
  
  
  📌 Favicon
&lt;/h3&gt;

&lt;p&gt;É bastante nítido, neste ponto do artigo, que SEO tem tudo a ver com a experiência do usuário e em como o usuário pode navegar de forma mais confortável e intuitiva pelo nosso website. Neste sentido, um favicon é muito importante, porque deixa claro em qual aba está o seu website.&lt;br&gt;
Para adicionar um favicon lembre-se de seguir a seguinte semântica:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;link rel="shortcut icon" type="image/ico" href="http://meusite/favicon.png"&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;O &lt;code&gt;rel=""&lt;/code&gt; serve para acessibilidade enquanto o &lt;code&gt;type=""&lt;/code&gt; serve para mostrar qual é o tipo de conteúdo que será anexado.&lt;/p&gt;

&lt;h3&gt;
  
  
  📌 Velocidade e carregamento
&lt;/h3&gt;

&lt;p&gt;Uma das coisas que elencam negativamente um website é a velocidade de carregamento. No Google Chrome podemos fazer uma varredura simples e eficiente ao inspecionarmos um site, através da aba &lt;em&gt;Lighthouse&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9nu8zt4k5c81cy199626.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9nu8zt4k5c81cy199626.png" alt="Lighthouse no Google Chrome" width="800" height="365"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Ao apertar no botão "Analyze Page Load", o navegador gera um relatório do carregamento do site.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmk4taih97znk952t4jiy.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmk4taih97znk952t4jiy.png" alt="Relatório Lighthouse do Google" width="800" height="277"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Como pode ser visto neste exemplo, a versão mobile do site do Google tem nota 60 de performance, 80 de acessibilidade, 100 de boas práticas e 85 de SEO. Se passarmos a barra de rolagem perceberemos que o Lighthouse detalha quais pontos estão bons e quais podem ser melhorados. Podemos salvar isso num pdf ou em formato json para analisar de forma minuciosa o que pode ser melhorado no nosso site. Saiba mais sobre como interpretar o relatório do Lighthouse &lt;a href="https://perf.reviews/tools/1.2-Interpretando-Lighthouse-Performance/"&gt;aqui&lt;/a&gt;.&lt;/p&gt;

&lt;h4&gt;
  
  
  Imagens
&lt;/h4&gt;

&lt;p&gt;O tópico de imagens aparece neste artigo dentro da seção de &lt;strong&gt;Tags&lt;/strong&gt; e dentro da seção de &lt;strong&gt;Velocidade e Carregamento&lt;/strong&gt; porque de fato é um elemento essencial na qualidade do SEO. Já falamos sobre a semântica das imagens ao introduzí-las no HTML, mas devemos falar também sobre o seu tamanho.&lt;br&gt;
Uma das coisas que mais pesa o carregamento de um site é o tamanho das imagens e é muito importante carregar imagens o mais leves possíveis para as devidas finalidades. Se a imagem ocupa a tela inteira, se ocupa um tamanho de 200x200 pixels, tudo precisa ser levado em consideração para que nosso site não fique mais pesado do que o necessário.&lt;br&gt;
O &lt;a href="https://squoosh.app/"&gt;squoosh.app&lt;/a&gt; e o &lt;a href="//compressjpeg.com"&gt;compressjpeg.com&lt;/a&gt; são ótimas opçãos para comprimir imagens. É importante salientar também que mobile e desktop precisam ter imagens de tamanhos diferentes, porque têm necessidades diferentes. Dica de ouro: use jpeg para imagens sem transparência, png para com transparência e SVGs para ícones, sempre que for possível. Demarque com clareza o que é ícone e o que é imagem, porque essa diferenciação é uma das que mais conta pontos no SEO dos robôs de motor de busca.&lt;/p&gt;

&lt;h3&gt;
  
  
  📌 Server Side Rendering (SSR)
&lt;/h3&gt;

&lt;p&gt;O Server Side Rendering (SSR) é a habilidade de renderização de uma página através do servidor ao invés do browser. É o oposto the Client Side Rendering, que carrega a aplicação do lado do cliente, ou seja, no navegador do usuário.&lt;br&gt;
Geralmente os frameworks the usamos, tais como o React.js e o Angular, são renderizados do lado do usuário e isso pode fazer com que o carregamento do site seja mais lento. Para lidar com esse problema podemos fazer a implementação do Next.js (no caso do React.js) e o Angular Universal (no caso de Angular). No geral, existem prós e contras em utilizarmos SSR ou CSR, mas quando estamos falando de SEO geralmente a indicação é que carreguemos a página do lado do servidor e não no do cliente.&lt;br&gt;
Entretanto, recentemente parece que os crawlers (os robôs que fazem as varreduras dos motores de busca) estão aceitando e lendo JavaScript com mais facilidade, até porque as aplicações que usam frameworks como React, Angular e Vue estão cada vez mais populares.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F83tejtxvaydq0iori6wx.png" alt="Server side rendering flow" width="785" height="268"&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;em&gt;Imagem retirada do canal &lt;a href="https://www.youtube.com/watch?v=tpxz_MT3Z6Q"&gt;Duomly&lt;/a&gt;&lt;/em&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;No Server Side Rendering, em ordem:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;O usuário faz requisições para o website&lt;/li&gt;
&lt;li&gt;O servidor cria arquivos HTML prontos&lt;/li&gt;
&lt;li&gt;O navegador renderiza o HTML de forma não interativa&lt;/li&gt;
&lt;li&gt;O navegador faz o download do JavaScript&lt;/li&gt;
&lt;li&gt;O navegador executa o JavaScript&lt;/li&gt;
&lt;li&gt;O website fica interativo&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fyb8ntu903g1xpj6gg0dy.png" alt="Client side rendering flow" width="780" height="268"&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;em&gt;Imagem retirada do canal &lt;a href="https://www.youtube.com/watch?v=tpxz_MT3Z6Q"&gt;Duomly&lt;/a&gt;&lt;/em&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;No Cliente Side Rendering, em ordem:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;O usuário faz requisições para o website&lt;/li&gt;
&lt;li&gt;O servidor envia o arquivo HTML com os links JavaScript&lt;/li&gt;
&lt;li&gt;O navegador faz o download do HTML&lt;/li&gt;
&lt;li&gt;O navegador faz o download do CSS e do JavaScript&lt;/li&gt;
&lt;li&gt;O navegador executa o framework ou a biblioteca&lt;/li&gt;
&lt;li&gt;O navegador carrega o website&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  🎯 Conclusões
&lt;/h3&gt;

&lt;p&gt;Em síntese, vimos neste artigo quais práticas um(a) desenvolvedor(a) deve seguir para melhorar as métricas de SEO. Muitas das coisas descritas aqui são também boas práticas para o cotidiano, como o taggeamento correto no HTML5, o uso de imagens no tamanho ideal e o cuidado no encurtamento das URLs. Pensar no SEO é também pensar em usabilidade e acessibilidade, além de desenvolver habilidades a fim de facilitar a navegação e os objetivos dos usuários.&lt;br&gt;
Muitos dos assuntos tratados neste artigo foram feitos de forma superficial, então te convido a conferir o material de referência especificado abaixo. Aqui você encontrará uma curadoria no assunto de SEO para desenvolvedores em diversos âmbitos, se tornando um(a) programador(a) melhor e mais capacitado(a).&lt;/p&gt;

&lt;h2&gt;
  
  
  Referências
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://html.spec.whatwg.org/"&gt;HTML5 - Documentação&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.youtube.com/watch?v=-q_o6esIgbc"&gt;SEO - Curso em Vídeo&lt;/a&gt; 📺&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.youtube.com/watch?v=v8LWhWVW9Ek"&gt;Guia SEO Completo para Desenvolvedor - Rafael Perozin&lt;/a&gt; 📺&lt;/li&gt;
&lt;li&gt;&lt;a href="https://drcode.com.br/blog/html/dicas-seo-para-programadores-front-end/"&gt;Dicas SEO para Programadores - Dr/code&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.youtube.com/watch?v=JSm4aQl4w_U"&gt;SEO for Developers | 2020 SEO Tutorial - JavaScript Mastery&lt;/a&gt; 📺&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.instagram.com/p/Cdy07b8NixC/"&gt;Semântica HTML - IuriCode&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.w3c.br/pub/Agenda/PalestraSenacRibeiraoHTML5WebSemantica/W3C_HTML5_WebSem.pdf"&gt;O Futuro da Web, HTML5 e Web Semântica - Vagner Diniz, Carlinhos Cecconi&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://perf.reviews/tools/1.2-Interpretando-Lighthouse-Performance/"&gt;Cómo interpretar los informes de performance de Lighthouse - Joan León y José M. Pérez&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://developers.google.com/search/docs/advanced/robots/create-robots-txt"&gt;Criar um arquivo robots.txt - Google&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.seomarketing.com.br/tutorial-seo/sitemap-xml-como-criar-e-configura-lo/"&gt;Sitemap.xml: como criar e configurá-lo - SEOMarketing&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.youtube.com/playlist?list=PL-u8JWLN6xau0QpzuOTeTI954SsIGEsVA"&gt;HTML5 - CSS3 - Referência em Vídeo da Hcode&lt;/a&gt; 📺&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.youtube.com/watch?v=tpxz_MT3Z6Q"&gt;Server Side Rendering vs Client Side Rendering vs Pre-rendering - Duomly&lt;/a&gt; 📺&lt;/li&gt;
&lt;li&gt;&lt;a href="https://developers.google.com/search/docs/advanced/crawling/consolidate-duplicate-urls"&gt;Como ajudar o Google a escolher o URL canônico correto para as páginas duplicadas - Google&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>seo</category>
      <category>beginners</category>
      <category>frontend</category>
      <category>html</category>
    </item>
    <item>
      <title>Git para iniciantes 🇧🇷</title>
      <dc:creator>Beatriz Maciel</dc:creator>
      <pubDate>Fri, 01 Jul 2022 21:01:25 +0000</pubDate>
      <link>https://forem.com/beatrizmaciel/git-para-iniciantes-1i68</link>
      <guid>https://forem.com/beatrizmaciel/git-para-iniciantes-1i68</guid>
      <description>&lt;h2&gt;
  
  
  O que é o Git?
&lt;/h2&gt;

&lt;p&gt;É um sistema de versionamento de controle para rastrear mudanças em arquivos do computador coordenando o trabalho feito nestes arquivos entre uma ou múltiplas pessoas.&lt;/p&gt;

&lt;h3&gt;
  
  
  Download
&lt;/h3&gt;

&lt;p&gt;Baixar o Git é fácil! Basta entrar em &lt;a href="https://git-scm.com/downloads"&gt;git-scm.com&lt;/a&gt;, baixar a última versão e seguir os passos para a instalação. Bem intuitivo.&lt;/p&gt;

&lt;h3&gt;
  
  
  Configuração
&lt;/h3&gt;

&lt;p&gt;A primeira coisa que devemos fazer é configurar nosso git. Se você tem dúvidas, use o seguinte comando:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight batchfile"&gt;&lt;code&gt;&lt;span class="kd"&gt;git&lt;/span&gt; &lt;span class="nb"&gt;help&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Usando esse comando você encontra uma série de utilizações do git. Para começar, vamos colocar nosso nome de usuário (o que vai aparecer quando publicarmos uma versão de código) e nosso e-mail, que ajuda na identificação e nas permissões.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight batchfile"&gt;&lt;code&gt;&lt;span class="kd"&gt;git&lt;/span&gt; &lt;span class="kd"&gt;config&lt;/span&gt; &lt;span class="na"&gt;--global &lt;/span&gt;&lt;span class="kd"&gt;user&lt;/span&gt;.name &lt;span class="s2"&gt;"Nina Silva"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight batchfile"&gt;&lt;code&gt;&lt;span class="kd"&gt;git&lt;/span&gt; &lt;span class="kd"&gt;config&lt;/span&gt; &lt;span class="na"&gt;--global &lt;/span&gt;&lt;span class="kd"&gt;user&lt;/span&gt;.email &lt;span class="s2"&gt;"nina@learning-git.com"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Nesse caso usamos "--global" para que a identificação seja global (em todo o sistema), mas podemos também definir identificações para repositórios específicos, substituindo o --global por --local, dessa forma:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight batchfile"&gt;&lt;code&gt;&lt;span class="kd"&gt;git&lt;/span&gt; &lt;span class="kd"&gt;config&lt;/span&gt; &lt;span class="na"&gt;--local &lt;/span&gt;&lt;span class="kd"&gt;user&lt;/span&gt;.name &lt;span class="s2"&gt;"Grace Hooper"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Comandos
&lt;/h3&gt;

&lt;h4&gt;
  
  
  ✏️ Inicializando um repositório
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight batchfile"&gt;&lt;code&gt;&lt;span class="kd"&gt;git&lt;/span&gt; &lt;span class="kd"&gt;init&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Para inicializar do zero.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight batchfile"&gt;&lt;code&gt;&lt;span class="kd"&gt;git&lt;/span&gt; &lt;span class="kd"&gt;clone&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Para clonar algum repositório. É preciso especificar qual repositório será clonado depois da palavra "clone"&lt;/p&gt;

&lt;h4&gt;
  
  
  ✏️ Puxando atualizações de um repositório
&lt;/h4&gt;

&lt;p&gt;Muitas vezes, quando estamos compartilhando código com outras pessoas, é importante "puxar" todas as atualizações feitas remotamente para o nosso local. Para isso utilizamos o seguinte comando:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight batchfile"&gt;&lt;code&gt;&lt;span class="kd"&gt;git&lt;/span&gt; &lt;span class="kd"&gt;pull&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Pull em inglês é "puxar", não se confunda! 😉&lt;/p&gt;

&lt;h4&gt;
  
  
  ✏️ Fazendo atualizações
&lt;/h4&gt;

&lt;p&gt;Agora chegou a hora de entregarmos nossas modificações para o repositório remoto. Geralmente quando trabalhamos em equipe trabalhamos em branches, que significa ramos ou ramificações. Geralmente um repositório tem um branch master, que concentra todo o código que já foi revisado e está correto, enquanto os desenvolvedores trabalham em branches separadamente.&lt;br&gt;
Quando fazemos um clone de um repositório e atualizamos ele (pull), ficamos geralmente na branch master. Para fazermos uma ramificação, que será nosso ambiente de trabalho, usamos o seguinte comando:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight batchfile"&gt;&lt;code&gt;&lt;span class="kd"&gt;git&lt;/span&gt; &lt;span class="kd"&gt;checkout&lt;/span&gt; &lt;span class="na"&gt;-b &lt;/span&gt;&lt;span class="kd"&gt;minha&lt;/span&gt;&lt;span class="na"&gt;-branch
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;O &lt;code&gt;git checkout&lt;/code&gt; serve para sairmos de uma branch e entrarmos em outra, mas quando utilizamos o comando &lt;code&gt;-b&lt;/code&gt; criamos uma nova branch! Nesse caso o nome da branch é "minha-branch", mas poderia ser "bananinha", "componente-banner" ou qualquer outra coisa.&lt;/p&gt;

&lt;p&gt;❗ Importante! Usamos um padrão para criarmos novas branches. Geralmente usamos &lt;code&gt;feature/&lt;/code&gt; , &lt;code&gt;bug/&lt;/code&gt; ou &lt;code&gt;hotfix/&lt;/code&gt; antes do nome da nossa branch e esses acordos precisam ser feitos a priori com o time. Cada equipe se organiza de uma forma diferente, mas tenha em mente que quando criamos um novo componente ou versão usamos &lt;code&gt;feature/minha-branch&lt;/code&gt;. Se estamos consertando um bug, &lt;code&gt;bug/minha-branch&lt;/code&gt; e se é um hot fix, ou seja, uma melhoria urgente, usamos &lt;code&gt;hotfix/minha-branch&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Depois de criarmos nossa branch vamos fazer as modificações necessárias em cada arquivo. Uma vez que terminamos de fazer as atualizações podemos adicionar nossa nova versão de código na nossa branch. Para isso, abrimos o terminal git bash e conferimos quais arquivos foram modificados com o seguinte comando:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight batchfile"&gt;&lt;code&gt;&lt;span class="kd"&gt;git&lt;/span&gt; &lt;span class="kd"&gt;status&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;O git status nos ajuda a ver arquivos que foram mapeados pelo git. Nesse caso vamos adicioná-los usando o seguinte comando:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight batchfile"&gt;&lt;code&gt;&lt;span class="kd"&gt;git&lt;/span&gt; &lt;span class="kd"&gt;add&lt;/span&gt; &lt;span class="s2"&gt;"nome do arquivo"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Ao usarmos o git status depois de adicionar um arquivo, vemos que sua cor muda de vermelho para verde e isso significa que as mudanças estão prontas para serem atualizadas. Para criar uma versão desse arquivo usamos o comando:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight batchfile"&gt;&lt;code&gt;&lt;span class="kd"&gt;git&lt;/span&gt; &lt;span class="kd"&gt;commit&lt;/span&gt; &lt;span class="na"&gt;-m &lt;/span&gt;&lt;span class="s2"&gt;"escreva uma mensagem aqui"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;É importante escrevermos uma mensagem descrevendo o que fizemos na alteração do código. Precisamos ser sucintos e objetivos, porque se for preciso um dia voltar a esse commit sabemos exatamente o que foi feito. Exemplos de mensagens de commits: "criando os estilos do componente", "atualizando o serviço de mensageria", "adicionando versão mobile", "passando testes unitários" e por aí vai.&lt;br&gt;
Uma coisa muito legal de usar nas mensagens de commits é o &lt;a href="https://gitmoji.dev/"&gt;gitmoji.dev&lt;/a&gt;! Ele deixa os commits mais visuais!&lt;/p&gt;

&lt;p&gt;Depois de ter feito o commit das suas modificações (não economize nos commits! Faça sempre que achar necessário) é preciso "empurrar" essas modificações para a sua branch (sim, ainda estamos trabalhando na nossa branch: minha-branch). Para isso usamos o seguinte comando:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight batchfile"&gt;&lt;code&gt;&lt;span class="kd"&gt;git&lt;/span&gt; &lt;span class="kd"&gt;push&lt;/span&gt; &lt;span class="kd"&gt;origin&lt;/span&gt; &lt;span class="kd"&gt;minha&lt;/span&gt;&lt;span class="na"&gt;-branch
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;É importante usarmos o origin antes da nossa branch, porque algumas vezes vamos trabalhar com branches de mesmo nome, sendo uma em cloud e outra a origin. É bom se acostumar a sempre especificar qual branch você quer puxar ou empurrar conteúdos.&lt;/p&gt;

&lt;h4&gt;
  
  
  ✏️ Conferindo as mudanças
&lt;/h4&gt;

&lt;p&gt;Pronto! Agora suas atualizações podem ser acessadas por qualquer desenvolvedor. Para verificarmos se o nosso commit foi realmente efetuado usamos o seguinte comando:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight batchfile"&gt;&lt;code&gt;&lt;span class="kd"&gt;git&lt;/span&gt; &lt;span class="kd"&gt;log&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;O git log nos ajuda a ver todo o histórico de commits da branch, desde o seu "nascimento" na master. Também podemos ver os commits em outras plataformas, como Github, o Gitlab e o Bitbucket, mas quando não tivermos essas plataformas para nos ajudarmos é bom usar o git log e conferir se está tudo certinho.&lt;/p&gt;

&lt;h4&gt;
  
  
  ✏️ Mesclando branches
&lt;/h4&gt;

&lt;p&gt;Trabalho concluído e agora é hora de fazer o merge da sua branch na branch master! O merge é quando mesclamos uma branch na outra, levando todas as nossas atualizações para outra branch.&lt;/p&gt;

&lt;p&gt;❗ Importante! Fazer o merge com outra branch pode ser um pouco complicado nas primeiras vezes, então é importante avisar os colegas que você fará esse movimento. Muitas vezes também precisamos resolver conflitos entre a nossa branch e a branch master (ou qualquer outra branch que vamos mesclar). É preciso ficar atento para não deixar bugs e erros passarem nesse momento. Faça tudo com orientação das primeiras vezes&lt;/p&gt;

&lt;p&gt;Vamos pensar numa situação imaginária: pense que você quer levar todas as atualizações da minha-branch para a branch master. Para fazer isso nós vamos fazer &lt;code&gt;git checkout master&lt;/code&gt;, onde vamos mudar para a branch master. Depois disso, rodaremos o seguinte comando:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight batchfile"&gt;&lt;code&gt;&lt;span class="kd"&gt;git&lt;/span&gt; &lt;span class="kd"&gt;merge&lt;/span&gt; &lt;span class="kd"&gt;minha&lt;/span&gt;&lt;span class="na"&gt;-branch
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Dessa forma estaremos mesclando a nossa branch (minha-branch) dentro da branch master e teremos todas as atualizações!&lt;/p&gt;

&lt;h4&gt;
  
  
  ✏️ Salvando alterações sem fazer commit
&lt;/h4&gt;

&lt;p&gt;Agora que já entendemos o que são commits e sabemos que temos um histórico deles quando rodamos o comando &lt;code&gt;git log&lt;/code&gt;, surge uma nova dúvida: o que fazer quando estamos trabalhando em uma atualização, mas ainda não terminamos e precisamos resolver algo em outra branch rapidamente? Se você já foi interrompido(a) fazendo alterações em uma branch sabe que o git não permite que mudemos de uma branch para outro com atualização "a commitar", ou seja, pendentes.&lt;br&gt;
Para que nós não perdamos essas modificações, podemos usar o seguinte comando:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;git stash
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;O git stash serve para salvarmos em uma fração da memória do computador nossas alterações sem commitar elas. Esse comando é bem útil quando estamos escrevendo algo que ainda não traz nenhum benefício para o nosso código, mas não queremos perder o que começamos. Para aplicar o que estava em stash usamos o comando &lt;code&gt;git stash apply&lt;/code&gt;. Também é possível listar quantos stashs foram feitos através do &lt;code&gt;git stash list&lt;/code&gt; ou limpar os stashs com &lt;code&gt;git stash clear&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;✨&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Este treinamento de Git foi feito para o evento da FIEC em parceria com a Vilt. O intuito é aprender comandos básicos de versionamento de código, utilizados no dia a dia de um(a) programador(a).&lt;/em&gt;&lt;br&gt;
&lt;em&gt;O repositório oficial, de mesma autoria, pode ser encontrado &lt;a href="https://github.com/beatrizmaciel/treinamento-vilt"&gt;aqui&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

</description>
      <category>git</category>
      <category>github</category>
      <category>beginners</category>
    </item>
    <item>
      <title>HackerRank #30 | Map | 🇧🇷</title>
      <dc:creator>Beatriz Maciel</dc:creator>
      <pubDate>Sat, 30 Apr 2022 14:32:38 +0000</pubDate>
      <link>https://forem.com/beatrizmaciel/hackerrank-30-map--5fd6</link>
      <guid>https://forem.com/beatrizmaciel/hackerrank-30-map--5fd6</guid>
      <description>&lt;p&gt;&lt;a href="https://www.hackerrank.com/challenges/phone-book/problem?h_r=profile"&gt;Este problema&lt;/a&gt; pede para que, a partir de uma lista telefônica, seja inserido um número e retorne a mesma quantidade de contatos relativo à esse número.&lt;/p&gt;

&lt;p&gt;O código começa assim:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;//Complete this code or write your own from scratch
import java.util.*;
import java.io.*;

class Solution{
    public static void main(String []argh)
    {
        Scanner in = new Scanner(System.in);
        int n=in.nextInt();
        in.nextLine();
        for(int i=0;i&amp;lt;n;i++)
        {
            String name=in.nextLine();
            int phone=in.nextInt();
            in.nextLine();
        }
        while(in.hasNext())
        {
            String s=in.nextLine();
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;=========&lt;/p&gt;

&lt;p&gt;O resultado final é:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;package com.possible.map;

import java.util.*;
import java.io.*;

public class Solution {
    public static void main(String[] args) throws FileNotFoundException {
        Scanner in = new Scanner(new File("input.txt"));
        int n = in.nextInt(); // quantidade de contatos que vc quer
        in.nextLine();
        HashMap&amp;lt;String,Integer&amp;gt; listaTelefonica = new HashMap&amp;lt;&amp;gt;();

        for (int i = 0; i &amp;lt; n; i++) {
            String name = in.nextLine(); // pega o nome
            int phone = in.nextInt(); // pega o telefone
            listaTelefonica.put(name, phone);
            in.nextLine();
        }

        while (in.hasNext()) {
            String s = in.nextLine();
            if(listaTelefonica.containsKey(s)) // se existir
                System.out.println(s + "=" + listaTelefonica.get(s));
            else
                System.out.println("Not found");
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;=========&lt;/p&gt;

&lt;h4&gt;
  
  
  Referências
&lt;/h4&gt;

&lt;p&gt;&lt;a href="https://docs.oracle.com/javase/8/docs/api/java/util/Map.html"&gt;Map&lt;/a&gt; : Oracle&lt;br&gt;
&lt;a href="https://docs.oracle.com/javase/8/docs/api/java/util/HashMap.html"&gt;HashMap&lt;/a&gt; : Oracle&lt;br&gt;
&lt;a href="https://www.devmedia.com.br/conhecendo-a-interface-map-do-java/37463"&gt;Map&lt;/a&gt; : DevMedia&lt;/p&gt;

</description>
      <category>java</category>
      <category>map</category>
    </item>
    <item>
      <title>HackerRank #40 | Java Dequeue | 🇧🇷</title>
      <dc:creator>Beatriz Maciel</dc:creator>
      <pubDate>Mon, 22 Nov 2021 20:35:53 +0000</pubDate>
      <link>https://forem.com/beatrizmaciel/hackerrank-40-java-dequeue--497h</link>
      <guid>https://forem.com/beatrizmaciel/hackerrank-40-java-dequeue--497h</guid>
      <description>&lt;p&gt;&lt;a href="https://www.hackerrank.com/challenges/java-dequeue/problem"&gt;Esse exercício&lt;/a&gt; recebe dois inputs iniciais: um &lt;code&gt;integer&lt;/code&gt; N, relativo à quantidade de números em um array, e um &lt;code&gt;integer&lt;/code&gt; M, relativo a um subarray deslocável que fará a "varredura" dentro do array principal.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F622ln99nqilnyx4ludyb.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F622ln99nqilnyx4ludyb.png" alt="HackerRank Dequeue Imagem" width="185" height="102"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;N = quantidade de números do array&lt;br&gt;
M = tamanho do subarray que varrerá o array principal&lt;/p&gt;

&lt;p&gt;Dessa forma, os arrays estruturados com M = 3 serão:&lt;/p&gt;

&lt;p&gt;[5, 3, 5]&lt;br&gt;
 . . . [3, 5, 2]&lt;br&gt;
  . . . . . [5, 2, 3]&lt;br&gt;
  .  . . . . . . [2, 3, 2]&lt;/p&gt;

&lt;p&gt;Como todos os subarrays precisam ter M números, nesse caso esses serão os subarrays possíveis.&lt;/p&gt;

&lt;p&gt;Depois disso, precisamos que o programa contabilize qual é o máximo de números únicos existentes em um subarray de tamanho M.&lt;/p&gt;

&lt;p&gt;[5, 3, 5] = 2 números únicos&lt;br&gt;
[3, 5, 2] = 3 números únicos&lt;br&gt;
[5, 2, 3] = 3 números únicos&lt;br&gt;
[2, 3, 2] = 2 números únicos&lt;/p&gt;

&lt;p&gt;Sendo assim, o máximo de números únicos em um subarray será 3. Esse precisa ser o output.&lt;/p&gt;

&lt;p&gt;Vamos para a solução, dividida em partes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Primeiro declaramos um Array de Integers de nome deque.&lt;/li&gt;
&lt;li&gt;Declaramos também um Hashset de Integers de nome hashset. Lembrando que um &lt;a href="https://dev.to/beatrizmaciel/hackerrank-39-hashset-3jb3"&gt;Hashset não repete números&lt;/a&gt;, e isso vai ser útil para que possamos contabilizar números únicos.&lt;/li&gt;
&lt;li&gt;Depois escaneamos os ints &lt;code&gt;N&lt;/code&gt;, &lt;code&gt;M&lt;/code&gt; e &lt;code&gt;maxUniqueIntegers&lt;/code&gt; (nossa resposta final)&lt;/li&gt;
&lt;li&gt;Dentro de uma iteração, pegaremos, através de um input, os números do array. Lembrando: a quantidade de números do array é delimitada por N, mas será inserida pelo usuário.&lt;/li&gt;
&lt;li&gt;Vamos adicionar todos os números do input no &lt;code&gt;Array deque&lt;/code&gt; e no &lt;code&gt;Hashset hashset&lt;/code&gt; através do &lt;code&gt;.add&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Faremos uma condicional que diz que nosso Array deque, tendo o mesmo tamanho de M, fará com que o hashset receba o maxUniqueIntegers para ir contabilizando as entradas de números únicos. Como o hashset só permite números únicos, o maxUniqueIntegers também só receberá a quantidade de números únicos.&lt;/li&gt;
&lt;li&gt;Depois, declararemos uma variável firstQueueNumber que fará a remoção do primeiro número do nosso array deque. A propriedade .remove sempre remove o primeiro elemento, ou o elemento que tem a menor posição i (leia mais sobre isso nas referências)&lt;/li&gt;
&lt;li&gt;Por fim, imprimimos o maxUniqueNumbers, com a quantidade de números únicos.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;O código final fica assim:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        Deque&amp;lt;Integer&amp;gt; deque = new ArrayDeque&amp;lt;&amp;gt;();
        HashSet&amp;lt;Integer&amp;gt; hashset = new HashSet&amp;lt;&amp;gt;();

        int n = in.nextInt();
        int m = in.nextInt();
        int maxUniqueIntegers = 0;

        for (int i = 0; i &amp;lt; n; i++) {
            int num = in.nextInt();

            deque.add(num);
            hashset.add(num);

            if (deque.size() == m) {
                if (hashset.size() &amp;gt; maxUniqueIntegers) {
                    maxUniqueIntegers = hashset.size();
                }
                int firstQueueNumber = deque.remove();
                if (!deque.contains(firstQueueNumber)) {
                    hashset.remove(firstQueueNumber);
                } 
            }
        }

        System.out.println(maxUniqueIntegers);
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;=======&lt;/p&gt;

&lt;h4&gt;
  
  
  Referências:
&lt;/h4&gt;

&lt;p&gt;&lt;a href="https://docs.oracle.com/javase/8/docs/api/java/util/ArrayList.html#remove-int-"&gt;ArrayList&lt;/a&gt; : Oracle&lt;/p&gt;

&lt;p&gt;============&lt;/p&gt;

&lt;p&gt;Essa publicação faz parte de uma série de exercícios resolvidos em Java no HackerRank. Acesse a série completa:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://dev.to/beatrizmaciel/hackerrank-6-scanner-e-endoffile-462c"&gt;HackerRank #6 | Scanner e End-of-file&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/beatrizmaciel/hackerrank-7-int-em-string-e-vice-versa-4n1e"&gt;HackerRank #7 | Int to String / String to Int&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/beatrizmaciel/hackerrank-8-date-and-time-1f78"&gt;HackerRank #8 | Date and Time&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/beatrizmaciel/hackerrank-9-static-initializer-block-48ha"&gt;HackerRank #9 | Static Initializer Block&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/beatrizmaciel/hackerrank-10-currency-formatter-22oj"&gt;HackerRank #10 | Currency Formatter&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/beatrizmaciel/hackerrank-11-datatypes-2e9h"&gt;HackerRank #11 | DataTypes&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/beatrizmaciel/hackerrank-12-strings-introduction-2d1n"&gt;HackerRank #12 | Strings Introduction&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/beatrizmaciel/hackerrank-13-substring-comparisons-57ha"&gt;HackerRank #13 | Substring Comparisons&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/beatrizmaciel/hackerrank-14-abstract-class-3h5d"&gt;HackerRank #14 | Abstract Class&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/beatrizmaciel/hackerrank-18-biginteger-4jad"&gt;HackerRank #18 | BigInteger&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/beatrizmaciel/hackerrank-19-loops-ii-385n"&gt;HackerRank #19 | Loops II&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/beatrizmaciel/hackerrank-20-string-reverse-nec"&gt;HackerRank #20 | String Reverse&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/beatrizmaciel/hackerrank-23-instanceof-keyword-3lh6"&gt;HackerRank #23 | Instanceof keyword&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/beatrizmaciel/hackerrank-26-generics-55p8"&gt;HackerRank #26 | Generics&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/beatrizmaciel/hackerrank-27-1d-array-5f80"&gt;HackerRank #27 | 1D Array&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/beatrizmaciel/hackerrank-28-anagrams-boi"&gt;HackerRank #28 | Anagrams&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/beatrizmaciel/hackerrank-33-arraylist-2lj1"&gt;HackerRank #33 | Arraylist&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/beatrizmaciel/hackerrank-34-exception-handling-try-catch-144f"&gt;HackerRank #34 | Exception Handling Try / Catch&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/beatrizmaciel/hackerrank-35-exception-handling-44e"&gt;HackerRank #36 | Exception Handling&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/beatrizmaciel/hackerrank-37-list-4gmj"&gt;HackerRank #37 | List&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/beatrizmaciel/hackerrank-38-subarray-1693"&gt;HackerRank #38 | SubArray&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/beatrizmaciel/hackerrank-39-hashset-3jb3"&gt;HackerRank #39 | HashSet&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;HackerRank #40 | Java Dequeue&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>java</category>
      <category>hackerrank</category>
      <category>queue</category>
    </item>
    <item>
      <title>Desenvolvendo um SPA editável no AEM</title>
      <dc:creator>Beatriz Maciel</dc:creator>
      <pubDate>Thu, 04 Nov 2021 12:39:36 +0000</pubDate>
      <link>https://forem.com/beatrizmaciel/desenvolvendo-um-spa-editavel-no-aem-b38</link>
      <guid>https://forem.com/beatrizmaciel/desenvolvendo-um-spa-editavel-no-aem-b38</guid>
      <description>&lt;h2&gt;
  
  
  SPA: Technical Overview of SPA (Single Page App) Editor
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Editor AEM SPA&lt;/strong&gt; &lt;/p&gt;

&lt;p&gt;O Editor do AEM SPA permite que os desenvolvedores front-end a criar SPAs que podem ser integrados em um site AEM, permitindo que os autores de conteúdo a editar o conteúdo SPA tão facilmente quanto qualquer outro conteúdo AEM. &lt;/p&gt;

&lt;p&gt;Com o Editor SPA, autores podem fazer: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Edição de conteúdo in-context pelo AEM &lt;/li&gt;
&lt;li&gt;Configuração in-context dos componentes do lado do cliente &lt;/li&gt;
&lt;li&gt;Administração de layout (grid-based) in-context dos componentes do lado do cliente &lt;/li&gt;
&lt;li&gt;Composição in-context com os componentes do lado do cliente &lt;/li&gt;
&lt;li&gt;Criação/edição de template in-context para estados de app&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fi0km2r5eqotzsko3q6n7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fi0km2r5eqotzsko3q6n7.png" alt="AEM SPA Editor" width="800" height="399"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;SPA: Using aem-clientlib-generator&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;O aem-clientlib-generator é um node plugin que transforma CSS compilado e arquivos JS do seu SPA em uma AEM Client Library &lt;/li&gt;
&lt;li&gt;Precisa do clientlib.config.js, que define parâmetros como: 
-- Source path dos arquivos .css e .js 
-- Export path 
-- Categorias da clientlibrary&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;SPA: Fazendo o Deploy de um Project no AEM&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvohz989uix249b71dzho.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvohz989uix249b71dzho.png" alt="Deployinh a project to AEM" width="800" height="277"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;É necessário criar uma tag  que inclua o react em um arquivo pom.xml na pasta do react-app. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Templates in SPA&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Você pode criar templates para o SPA usando o Template Editor, que define os componentes permitidos e as policies (regras) de conteúdo &lt;/li&gt;
&lt;li&gt;O primeiro lançamento do editor SPA tem funcionalidades de edição de template limitadas &lt;/li&gt;
&lt;li&gt;A funcionalidade de edição completa é esperada para futuros lançamentos do SPA Editor &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Criando Page Components&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Como os Page Components trabalham: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Um page component no AEM não dispõe de elementos HTML de seus componentes "filhos" (child components) &lt;/li&gt;
&lt;li&gt;Um Sling Model busca a representação dos componentes filhos no formato de JSON na estrutura de dados &lt;/li&gt;
&lt;li&gt;O app React adiciona componentes SPA para a página AEM de acordo com o modelo JSON disponibilizado &lt;/li&gt;
&lt;li&gt;A Client Library chamada cq.authoring.pagemodel.messaging deve ser adicionada para permitir a comunicação entre o SPA e o editor de página &lt;/li&gt;
&lt;li&gt;O PageModelManager permite administrar a representação do modelo das páginas AEM que compõem o SPA&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Flybi07oa6nvbwemyevrr.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Flybi07oa6nvbwemyevrr.png" alt="Creating Page Components" width="566" height="355"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Criando uma Página Editável&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fl8c6lyytniw9gwh1osrw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fl8c6lyytniw9gwh1osrw.png" alt="Creating Editable Page" width="365" height="206"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Workflow de Editor de Página&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;cq.authoring.pagemodel.messaging manda uma mensagem para o Page Editor para estabelecer uma comunicação com o JSON data type. &lt;/li&gt;
&lt;li&gt;Quando a comunicação do data type está pronta no JSON, as requisições GET (GET requests) vão se comunicar com os end-points do Sling Model de um componente. &lt;/li&gt;
&lt;li&gt;Depois que a atualização acontece no Page Editor, a representação do JSON do componente atualizado é mandada para o Page Model library.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fksa7fusr996b7sfvxfyc.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fksa7fusr996b7sfvxfyc.png" alt="Page Editing Workflow" width="365" height="206"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Componentes no SPA Editor&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A funcionalidade dos componentes AEM é dividida no cq:component no AEM e no componente React respectivo &lt;/li&gt;
&lt;li&gt;Um componente em um projeto AEM, ou cq:component, disponibiliza funcionalidades como arrastar e soltar uma dialog para o componente AEM &lt;/li&gt;
&lt;li&gt;O componente definido no React-app disponibiliza funcionalidades para o componente &lt;/li&gt;
&lt;li&gt;O componente React mapeia o cq:component ou o resourceType no AEM através da função MapTo()&lt;/li&gt;
&lt;li&gt;Os core components sustentaram o export do JSON desde o lançamento 1.1.0 &lt;/li&gt;
&lt;li&gt;A interface do component model deve implementar uma classe ComponentExporter &lt;/li&gt;
&lt;li&gt;Isso garante que seu componente pode ser exportado por conta própria, usando o seletor .model e a extensão .json.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;SPA Routing in AEM&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A página model data structure expõe a URL do recurso subjacente (underlying resource) &lt;/li&gt;
&lt;li&gt;A página model data structure expõe a URL de todas as páginas "filhas" subjugadas ao nodo JSON &lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>aem</category>
      <category>adobe</category>
      <category>spa</category>
    </item>
    <item>
      <title>Desenvolvimento Back-end em AEM - Parte II</title>
      <dc:creator>Beatriz Maciel</dc:creator>
      <pubDate>Fri, 29 Oct 2021 16:12:18 +0000</pubDate>
      <link>https://forem.com/beatrizmaciel/desenvolvimento-back-end-em-aem-parte-ii-20fb</link>
      <guid>https://forem.com/beatrizmaciel/desenvolvimento-back-end-em-aem-parte-ii-20fb</guid>
      <description>&lt;h2&gt;
  
  
  Back-end Coding Practices
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Escrevendo Sling Servlets&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Arquitetura orientada à objetos&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Tudo é um recurso &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Pedaços de informação, novas entradas, descrições de produtos, fotos e outros &lt;/li&gt;
&lt;li&gt;Recursos são identificados por suas URLs únicas &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Stateless &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A requisição para um recurso contém toda a informação relevante &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Interação restrita com os recursos &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Eles usam métodos HTTP (GET, POST) para operações&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;em&gt;Sling Servlets&lt;/em&gt; &lt;/p&gt;

&lt;p&gt;O Sling Servlet API extende o HTTPServelet class. Ele define uma execução adicional de path (caminho) com a ajuda do Apache Sling Servlet/Script Resolver e Error Handler. O diretório default do Servlet Execution é o /bin. &lt;/p&gt;

&lt;p&gt;Aqui estão algumas instâncias que você pode evitar usando o @slingServlet: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Use @Component (service = Servlet.class) &lt;/li&gt;
&lt;li&gt;Evite @Component (service = Servlet.class,property={"sling.servlet.paths=/bin/servletdata"}) &lt;/li&gt;
&lt;li&gt;Use o atributo resourceType para conectar o Sling Servlets a um componente e.g. @Component (service = Servlet.class, property = {"sling.servlet.resourceTypes=project/components/component"}) &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Configuring the LoginService&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;O LoginService não trabalha junto com o usuário admin padrão. Para que ele trabalhe, é necessário: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Criar um usuário do sistema &lt;/p&gt;

&lt;p&gt;-- O username não é importante; pode ser qualquer coisa &lt;/p&gt;

&lt;p&gt;-- A única forma de criar um usuário do sistema é pelo explorar do CRX usando o System User &lt;/p&gt;

&lt;p&gt;-- Depois que você criar o usuário, os detalhes aparecem no Adobe Experience Manager Users and Groups &lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Garanta que você deu TODAS as permissões ao novo usuário do sistema &lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;em&gt;Event Admin&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Especificação OSGi para lidar com o event: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Publish/Subscribe baseado nos tópicos de hierarquia &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Acoplamento frágil de serviços &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Whiteboard pattern (padrão de quadro branco), onde um ouvinte registra a si mesmo no registro de serviços como comparado a um Listener Pattern (por exemplo, no AWT), onde um ouviten registra a si mesmo em um assunto de event-generating (WHAT?!) &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Eventos pré-definidos &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Eventos de framework &lt;/li&gt;
&lt;li&gt;Eventos de configuração &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;em&gt;Receiving Events&lt;/em&gt; &lt;/p&gt;

&lt;p&gt;Implementando a interface EventHandler &lt;/p&gt;

&lt;p&gt;Se inscrever no registro de serviço &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Whiteboard pattern (quadro branco padrão?!) &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Seleção do Evento com as propriedades do serviço&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
@Component( 
Immediate = true, 
service = EventHandler.class, 
property = { 
EventConstantsEVENT_FILTER+"=(path=/content/*)", 
// …. 
})

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;Use Java Content Repository Observation&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Existem 3 tipos diferentes de interpretações de eventos: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;NODE_ADDED &lt;/li&gt;
&lt;li&gt;NODE_REMOVED &lt;/li&gt;
&lt;li&gt;NODE_MOVED &lt;/li&gt;
&lt;li&gt;PROPERTY_ADDED &lt;/li&gt;
&lt;li&gt;PROPERTY_REMOVED &lt;/li&gt;
&lt;li&gt;PROPERTY_CHANGED &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;em&gt;Listener Registration&lt;/em&gt; &lt;/p&gt;

&lt;p&gt;O Listernet Registration acontece quando o objeto ObservationManager chama o addEventListener &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Ele é especificado por um path para o novo onde os eventos devem ser recebidos &lt;/li&gt;
&lt;li&gt;Ele especifica quando eventos são profundamente ou superficialmente recebidos (whole subtree) &lt;/li&gt;
&lt;li&gt;Ele pode escolher receber eventos para nodos de um certo tipo ao invés de um path &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;em&gt;Sling Events vs JCR Observation Listeners&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Os tópicos de evento Sling usados no nível CQ5 (CQ5-level) incluem Replication e PageEvents. Por exemplo: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;com.day.cq.wcm.api.PageEvent &lt;/li&gt;
&lt;li&gt;com.day.cq.replication.ReplicationAction &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Observation Listeners tem eventos mais sofisticados. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Sling Models&lt;/strong&gt; &lt;/p&gt;

&lt;p&gt;Aqui o que os Slings Models fazem: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Eles disponibilizam o framework para desenvolvimento &lt;/li&gt;
&lt;li&gt;Eles deixam você usar orientado por anotações. Objetos Java simples e antigos (POJOs) &lt;/li&gt;
&lt;li&gt;Eles são adaptáveis para vários objetos, incluindo Recursos e SlingServletRequest. &lt;/li&gt;
&lt;li&gt;Anotações em Sling models asseguram os inputs &lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Fora da caixa, Sling models trabalham com: &lt;/p&gt;

&lt;p&gt;-- Sling bindings &lt;/p&gt;

&lt;p&gt;-- Serviços OSGi &lt;/p&gt;

&lt;p&gt;-- Atributos de requisição &lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Sling Model Enhancements&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Sobre o Sling Dynamic Include: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Substitui componentes gerados dinamicamente com tag inclusivas no server-side &lt;/li&gt;
&lt;li&gt;É instalado através de um bundle OSGi &lt;/li&gt;
&lt;li&gt;Pode trabalhar com CDNs para performar Edge-Side Include &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Você não precisa modificar os componentes para usar esse módulo &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Sling Model Exporter&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;O framework Sling Model Exporter te permite adicionar novas anotações nos Sling Models &lt;/li&gt;
&lt;li&gt;A anotação @Exporter define como o Model pode ser exportado como um objeto Java diferente ou, mais usualmente, serializado em um formato diferente, como o JSON. &lt;/li&gt;
&lt;li&gt;O Apache Slings disponibiliza um Jackson JSON exporter para cobrir os casos mais comuns, exportando os Sling Models como objetos JSON. &lt;/li&gt;
&lt;li&gt;O Sling Model Exporter é perfeito para aproveitar Sling Models que já contém lógica de negócio que suportam renderizações HTML através do HTL &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Sling Model Exporter&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;O Sling Model Exporter suporta passar por opções per-model Exporter para a implementação Exporter. Isso leva à como o Sling Model e finalmente exportado. &lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Opções per-model Exporter geralmente são aplicadas globalmente para como o Sling Model é exportado. Considerando que para cada data point podem ser aplicadas anotações inline do tipo: &lt;/p&gt;

&lt;p&gt;-- Opções Jackson Exporter incluem: &lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;gt; Opções Mapper Feature 

&amp;gt; Opções Serialization Feature
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fehc28ou907wttt9qk7qr.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fehc28ou907wttt9qk7qr.png" alt="Sling Model Exporter AEM" width="800" height="564"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Usando Workflows&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Modelos de workflow no AEM representam e implementam processos de negócios &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Modelos de workflow atuam nas páginas ou assets para alcançar um resultado específico - essas páginas ou assets são conhecidas como workflows payload. &lt;/li&gt;
&lt;li&gt;Os modelos de workflows incluem uma séria de passos que performam tarefas específicas &lt;/li&gt;
&lt;li&gt;O Workflow payload passa por cada passo enquanto o workflow progride. &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Uma instância do workflow é criada e está em andamento. &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;O primeiro passo do workflow model é executado &lt;/li&gt;
&lt;li&gt;A engenharia do workflow usa o modelo para determinar o próximo passo para executar &lt;/li&gt;
&lt;li&gt;Os passos subsequentes no workflow são executados &lt;/li&gt;
&lt;li&gt;A instância do workflow termina e é arquivada &lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;em&gt;Passos do workflow&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Quando os passos do workflow são executados eles são associados a uma instância do workflow. A história de uma instância do workflow inclui informação sobre cada passo que foi executado para a instância. Essa informação é útil para investigar problemas que ocorrem durante a execução. &lt;/p&gt;

&lt;p&gt;Tanto um usuário quanto um serviço podem fazer os passos do workflow, dependendo do tipo de passo: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Quando um usuário faz um passo, ele se responsabiliza por um item de trabalho que fica localizado no seu Inbox. O usuário é responsável por completar manualmente o passo para que a instância do workflow progrida. &lt;/li&gt;
&lt;li&gt;Quando um serviço faz um passo e completa uma instância do workflow isso faz com que o próximo passo progrida automaticamente. &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Modificando Usuários e Grupos&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Aspectos básicos do Access Control (Acesso de Controle)&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;O Access Control acontece em um nível de repositório &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Permite que usuários e grupos sejam arquivados no repositório &lt;/li&gt;
&lt;li&gt;Permite que permissões sejam arquivadas como nodos. &lt;/li&gt;
&lt;li&gt;Oferece direitos de acesso de acordo com a Autenticação Java e Autorização de de Serviço (JAAS) &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;O Access Control consiste em: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Principals: uma conta de usuário ou de grupo &lt;/li&gt;
&lt;li&gt;Subjects: os direitos atribuídos a um usuário ou grupo &lt;/li&gt;
&lt;li&gt;Controle de Acesso e Autorização &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;em&gt;Evaluation of a Subject&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Evaluation é um processo de comparar as permissões do sujeito com aquelas necessárias para acessar um recurso. &lt;br&gt;
Enquanto estamos avaliando, Oak olha para o ancestral mais próximo, permitindo ou negando uma ação e indo nesta decisão &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Usando APIs Autorizáveis&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Os três tipos de APIs autorizáveis são: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;UserManager API: &lt;/p&gt;

&lt;p&gt;-- Te permite acesso e mantém objetos autorizáveis como Users e Groups &lt;br&gt;
-- Está atrelado a uma sessão particular de um usuário &lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Principal API &lt;/p&gt;

&lt;p&gt;-- Representa a noção abstrata de um principal que pode ser usado para representar qualquer entidade, como um indivíduo, uma coorporação, ou um id de login &lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;User interface &lt;/p&gt;

&lt;p&gt;-- É uma API autorizável que pode ser autenticada (usando credenciais) e despersonalizada.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;========&lt;/p&gt;

&lt;h2&gt;
  
  
  Questões Finais
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Back-End Coding Practices&lt;/strong&gt; &lt;/p&gt;

&lt;p&gt;1 – O que ajuda a inicializar o observationManager object?&lt;br&gt;
Session.getWorkspace().getObervationManager() &lt;/p&gt;

&lt;p&gt;2 – Qual das opções são acessos a objetos do Java Content Repository? &lt;br&gt;
Repository e Session &lt;/p&gt;

&lt;p&gt;3 – O que acontece quando você faz um "deploy a servlet on a path"? &lt;br&gt;
Ele sobrescreve os parâmetros existentes. &lt;/p&gt;

&lt;p&gt;4 – Qual a forma que o sling models recupera as informações que mudou nessa versão do AEM? &lt;br&gt;
Ele agora usa o "exporter framework" &lt;/p&gt;

&lt;p&gt;5 – Qual o caminho das pastas dos arquivos JUnits? &lt;br&gt;
Src/test folder &lt;/p&gt;

&lt;p&gt;6 – Complete a lacuna: &lt;br&gt;
To download Java docs and source files, you run the _______ command. &lt;br&gt;
Mvn eclipse:eclipse &lt;/p&gt;

&lt;p&gt;7 – Como você pode criar um system user? &lt;br&gt;
No CRX explorer usando system user. &lt;/p&gt;

&lt;p&gt;8 – O que voce precisa recupar para enviar um trabalho para o servidor? &lt;br&gt;
Job manager interface &lt;/p&gt;

&lt;p&gt;9 – Qual é a função de usar o Sling scheduler? &lt;br&gt;
Ele permite fácil marcação (scheduling) do trabalho dentro da sua aplicação. &lt;/p&gt;

&lt;p&gt;10 – Como você substitui os componentes gerados dinamicamente por tags de inclusão do lado do servidor? &lt;br&gt;
Usando Sling Dynamic Include &lt;/p&gt;

&lt;p&gt;11 – Complete a lacuna: &lt;br&gt;
Sling resources map to the ______. &lt;br&gt;
JCR node. &lt;br&gt;
Back-end Advanced Features&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Back-end Advanced Features&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;1 – O que são Workflow payloads? &lt;br&gt;
Páginas ou recursos nos quais os fluxos de trabalho atuam. &lt;/p&gt;

&lt;p&gt;2 – Complete a lacuna: &lt;br&gt;
Access control happens on a ________ level. &lt;br&gt;
Repository &lt;/p&gt;

&lt;p&gt;3 – Access Control List (ACL) são armazenados em grupos de usuários autorizáveis. &lt;br&gt;
False&lt;/p&gt;

&lt;p&gt;4 – Qual API autorizavel providencia o acesso e mantém o User e Groups? &lt;br&gt;
UserManager API &lt;/p&gt;

&lt;p&gt;5 - Criar muitos launchers fará com que o processo de avaliação seja executado mais lentamente &lt;br&gt;
Verdadeiro &lt;/p&gt;

&lt;p&gt;6 – Complete a lacuna: &lt;br&gt;
Workflow models in AEM represent and implement ______________. &lt;br&gt;
Business processes &lt;/p&gt;

&lt;p&gt;7 - Onde você pode encontrar informações que o ajudarão a investigar problemas que acontecem durante a execução de um &lt;br&gt;
No historico do Workflow instance &lt;/p&gt;

</description>
      <category>aem</category>
      <category>adobe</category>
      <category>backend</category>
      <category>cms</category>
    </item>
    <item>
      <title>Desenvolvimento Back-end em AEM - Parte I</title>
      <dc:creator>Beatriz Maciel</dc:creator>
      <pubDate>Thu, 28 Oct 2021 13:40:18 +0000</pubDate>
      <link>https://forem.com/beatrizmaciel/desenvolvimento-back-end-em-aem-parte-i-3lfg</link>
      <guid>https://forem.com/beatrizmaciel/desenvolvimento-back-end-em-aem-parte-i-3lfg</guid>
      <description>&lt;p&gt;O nome original dessa aula é: &lt;a href="https://solutionpartners.adobe.com/training/learning_program/learningProgram52530.html"&gt;Back-end Development for Developer&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Eclipse
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Installing and Configuring Eclipse&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Sobre o &lt;a href="https://dev.to/beatrizmaciel/maven-e-suas-funcionalidades-5hak"&gt;Maven&lt;/a&gt;: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Simplifica e disponibiliza processos uniformes &lt;/li&gt;
&lt;li&gt;Faz uso do project object model (POM) 
-- O pom.xml define a informação do projeto, constrói um ambiente de configurações e relacionamentos 
-- O Maven Archetypes/Lazybones é um template de projeto&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjmjwv6ernf1dxgvlcjvi.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjmjwv6ernf1dxgvlcjvi.png" alt="Image description" width="656" height="232"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Ferramentas AEM para o Eclipse&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;O AEM Developer Tools para o Eclipse é um plug-in baseado no Apache Sling lançado pela licença 2 do Apache. Ele oferece várias features que podem fazer o desenvolvimento AEM mais simples: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Integração desacoplada com as instâncias AEM através do Eclipse Server Connector &lt;/li&gt;
&lt;li&gt;Sincronização para ambos os conteúdos e OSGI bundles &lt;/li&gt;
&lt;li&gt;Suporte de debbug com capacidade de código hot-swapping &lt;/li&gt;
&lt;li&gt;Bootstrap simples de projetos AEM através de um Projeto Creation Wizard específico &lt;/li&gt;
&lt;li&gt;Fácil edição de propriedades do Java Content Repository (JCR)&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Use Pacotes e Run Modes customizados
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Usando FileVault (VLT)&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;O FileVault tool (VLT) é uma ferramenta desenvolvida pela Adobe que mapeia o conteúdo de uma instância CRX/CQ para um arquivo de programa &lt;/li&gt;
&lt;li&gt;O VLT tool tem funcionalidades similiares àquelas do source control system do cliente &lt;/li&gt;
&lt;li&gt;O FileVault disponibiliza check-in normal, checkout e administração de operações, além de opções de configuração para representação flexível do conteúdo do projeto &lt;/li&gt;
&lt;li&gt;FileVault está localizada no diretório ../crx-quickstart/opt/helpers &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Usando Pacotes&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Um pacote (package) é um arquivo zip que guarda conteúdo de repositório no formato de uma serialização file-system (também conhecida como serialização vault). Isso possibilita uma utilização facilitada e a representação editável de arquivos e pastas. &lt;br&gt;
Packages incluem conteúdo, conteúdo de ambas as páginas e conteúdo relacionado ao projeto, selecionado usando filtros. &lt;br&gt;
Packages também contém meta informação vault, incluindo as definições de filtro e a importação de informações de configuração. As propriedades adicionais de conteúdo (que não são usadas para a extração do package) podem ser incluídas no package, como descrição, uma imagem visual ou um ícone. Essas propriedades são somente para o consumidor de conteúdos do pacote e têm apenas o objetivo de informar. &lt;/p&gt;

&lt;p&gt;Packages te permitem importar e exportar o conteúdo de um repositório. Por exemplo, você pode usar packages para instalar uma nova funcionalidade, transferir conteúdo entre as instâncias e fazer o backup de conteúdo do repositório. &lt;/p&gt;

&lt;p&gt;Você pode acessar ou mantem packages a partir das seguintes páginas: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Package Manager, o qual você usa para administrar os pacotes na sua instância AEM local &lt;/li&gt;
&lt;li&gt;Package Share, um servidor centralizado que contém tanto pacotes de publicidade disponível quanto os pacotes privados da sua empresa – os pacotes públicos podem conter hotfixes, novas funcionalidades, documentação e outros &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Você pode transferir packages entre o Package Manager, Package Share e o seu sistema de arquivos&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Passo a passo:&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Tools &amp;gt; Deployment &amp;gt; Packages &lt;br&gt;
Create Package &amp;gt; nomear &lt;br&gt;
Edit &amp;gt; escolher os diretórios que esse package se aplica &amp;gt; clicar no link de download &lt;br&gt;
Upload package &amp;gt; Force upload (se for duplicado) &amp;gt; Install&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Use Custom Run Modes&lt;/strong&gt; &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Run modes te permitem equalizar a instância AEM para um propósito específico. Você pode usar para autorar ou publicar, testar, desenvolver ou usar a intranet &lt;/li&gt;
&lt;li&gt;Você pode: 
-- Definir coleções de parâmetros de configuração para cada run mode (um set básico de parâmetros de configurações é aplicado para todos os run modes e você pode equalizar sets adicionais para alcançar o propósito do seu ambiente específico) 
-- Definir bundles adicionais para serem instalados para um modo particular &lt;/li&gt;
&lt;li&gt;Todas as configurações e definições são guardadas em um repositório e ativadas quando configuramos o run mode. &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;=======&lt;/p&gt;

&lt;h2&gt;
  
  
  Questões Finais
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Eclipse&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;1 – Para importar o projeto lazubones para o servidor AEM você pode rodar Mavens diferentes do prompt de comando ou adicionar um novo servidos e performar o deploy do código. &lt;br&gt;
Verdadeiro&lt;/p&gt;

&lt;p&gt;2 – O template lazybones te permite usar o bootstrap no projeto AEM com uma estrutura apropriada. &lt;br&gt;
Verdadeiro &lt;/p&gt;

&lt;p&gt;3 – Qual é a sequência correta para preparar o ambiente de desenvolvimento? &lt;br&gt;
AEM login &amp;gt; ir para a janela do terminal &amp;gt; entrar o comando &amp;gt; gerar os arquivos de projeto do Eclipse &amp;gt; Ir para File &amp;gt; Selecionar Import no menu &amp;gt; Procurar &amp;gt; Terminar&lt;/p&gt;

&lt;p&gt;4 – Qual arquivo te permite iniciar o servidor AEM? &lt;br&gt;
.bat &lt;/p&gt;

&lt;p&gt;5 – Qual das opção são verdadeiras no que diz respeito ao Maven projects? &lt;br&gt;
Maven simplifica e fornece um processo de buid uniforme; &lt;br&gt;
Maven faz uso do Project Object Model (POM). &lt;/p&gt;

&lt;p&gt;6 – Qual a sequencia correta para criar um projeto Maven? &lt;br&gt;
File &amp;gt; New &amp;gt; Project &amp;gt; Select a project &amp;gt; next &amp;gt; select an archetype &amp;gt; generate a project using command line &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Use Packages and Custom Run Modes&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;1 – Qual é a função do filter.xml? &lt;br&gt;
Controlar o conteúdo upado para o servidor AEM pelo FileVault tool &lt;/p&gt;

&lt;p&gt;2 - Você pode acessar o Package Share somente através do menu Deployment na seção Tools na instância de AEM local. &lt;br&gt;
Falso &lt;/p&gt;

&lt;p&gt;3 - Você pode usar run modes customizados para diferenciar entre instâncias AEM.&lt;br&gt;
Verdadeiro &lt;/p&gt;

&lt;p&gt;4 – Qual desses te ajuda a importar e exportar o conteúdo do repositório?&lt;br&gt;
Package &lt;/p&gt;

&lt;p&gt;5 – Qual feature AEM te permite equalizar a instância AEM para um propósito específico? &lt;br&gt;
Run modes &lt;/p&gt;

&lt;p&gt;6 – O que os filtros no Packages map fazem? &lt;br&gt;
O content path em um repositório &lt;/p&gt;

&lt;p&gt;7 – As configurações e definições dos run modes estão guardadas em vários repositórios. &lt;br&gt;
Falso &lt;/p&gt;

&lt;p&gt;8 - Você pode fazer o download dos feature packs do Package Share e salver eles somente em uma instância local do AEM. &lt;br&gt;
Falso &lt;/p&gt;

&lt;p&gt;9 – Quantos tipoes de run modes você pode instanciar no AEM? &lt;br&gt;
Três &lt;/p&gt;

&lt;p&gt;10 – Onde o FileVault está localizado? &lt;br&gt;
No diretório CRX quickstart&lt;/p&gt;

</description>
      <category>aem</category>
      <category>adobe</category>
      <category>backend</category>
      <category>cms</category>
    </item>
    <item>
      <title>Maven e suas funcionalidades</title>
      <dc:creator>Beatriz Maciel</dc:creator>
      <pubDate>Fri, 08 Oct 2021 20:48:55 +0000</pubDate>
      <link>https://forem.com/beatrizmaciel/maven-e-suas-funcionalidades-5hak</link>
      <guid>https://forem.com/beatrizmaciel/maven-e-suas-funcionalidades-5hak</guid>
      <description>&lt;h2&gt;
  
  
  O que é o Maven?
&lt;/h2&gt;

&lt;p&gt;O Apache Maven é uma excelente ferramenta de apoio a qualquer equipe que trabalhe com projetos Java (outras tecnologias também são suportadas), fornecendo aos desenvolvedores uma forma de automatizar e padronizar a construção e publicação de suas aplicações. (fonte: &lt;a href="https://www.devmedia.com.br/introducao-ao-maven/25128"&gt;DevMedia&lt;/a&gt;)&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;´groupId´ ➟ organização / compania&lt;/li&gt;
&lt;li&gt;´artifactId´ ➟ o que está implementando &lt;/li&gt;
&lt;li&gt;´build´ ➟ onde adiciona os executáveis] &lt;/li&gt;
&lt;li&gt;´plugin´ ➟ no aem precisamos de um plug-in pra fazer o deploy dentro do AEM &lt;/li&gt;
&lt;li&gt;´bnd´ ➟ empacotador de bundles, transformar o .jar em uma estrutura de bundle OSGi &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Lifecycle do Maven&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkrcpzhlysqka9eemgbcg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkrcpzhlysqka9eemgbcg.png" alt="Lifecycle do Maven" width="572" height="510"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Ordem de execução&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Processa primeiro recursos (preparando os arquivos, fazendo as cópias para uma pasta específica) &lt;/li&gt;
&lt;li&gt;Compila as classes Java &lt;/li&gt;
&lt;li&gt;Processamento das classes &lt;/li&gt;
&lt;li&gt;Repete os três primeiros processos, mas com processamento focado nos testes. Ele compila e roda os testes. &lt;/li&gt;
&lt;li&gt;Empacotamento jar.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fg86kzglhjodmehnuinma.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fg86kzglhjodmehnuinma.png" alt="Lifecycle do Maven II" width="650" height="407"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;No integration test, roda-se os testes de integração. Como o pacote jar já estará criado ou até mesmo em execução, esse momento serve para executar testes de integração, como testes de workflow ou de performance. Isso só é possível porque outras funcionalidades já terão sido testadas no nível de teste superior. &lt;/li&gt;
&lt;li&gt;O Verify executa todos os passos até o dado momento e verifica se a compilação e o teste está apropriado. &lt;/li&gt;
&lt;li&gt;A Instalação acontece pegando o jar que foi compilado e guardando dentro da pasta .m2* e instalando localmente ou &lt;/li&gt;
&lt;li&gt;O Deploy (é paralelo ao deploy, não consecutivo) serve para instalar em um repositório remoto (Nexus – no maven central).&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;======= &lt;/p&gt;

&lt;p&gt;Em um projeto Maven, o esquema padrão de pastas é o seguinte:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmz0j9g42rzxcxcyog7h6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmz0j9g42rzxcxcyog7h6.png" alt="Pastas do Projeto Maven" width="107" height="148"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Acessamos src e, dentro dele, temos as pastas main e test. Main compila e processa classes e test compila e processa testes. Ambos contam com arquivos java e properties. &lt;/p&gt;

&lt;p&gt;A pasta target é o destino de toda a compilação do maven. Tudo o que for feito é encaminhado para esta pasta. &lt;/p&gt;

&lt;p&gt;======= &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;.m2 é a pasta para instalação &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;☆ Atenção: Install e Deploy não são executados ao mesmo tempo, são independentes e finais no ciclo de vida do Maven. &lt;/p&gt;

</description>
      <category>maven</category>
      <category>beginners</category>
    </item>
  </channel>
</rss>
