Desenvolver o bloco do Edge Delivery Services

IMPORTANT
O AEM Edge Functions está atualmente na versão beta. Os recursos e a documentação podem mudar. Para receber comentários, contate aemcs-edgecompute-feedback@adobe.com.

Nossa meta é criar um bloco dinâmico do Edge Delivery Services que chame uma Função AEM Edge para buscar dados dinâmicos de uma API de terceiros.

O segundo passo é desenvolver o bloco Edge Delivery Services, que forma um modelo JSON, JavaScript e CSS e o cria no Editor universal. Para obter a sintaxe do modelo de bloco e as noções básicas de estrutura JavaScript e CSS, consulte Criar um bloco e Criar um bloco. Somente as partes específicas deste tutorial são abordadas aqui.

Esta etapa ainda não chama a Função Edge do AEM que compilamos na etapa anterior. O bloco Edge Delivery Services renderiza um resultado de espaço reservado até que Conecte o bloco à AEM Edge Function conecte a busca.

Criar uma ramificação

No projeto do site do Edge Delivery Services, crie uma ramificação para esse recurso.

$ git checkout -b estimated-delivery

Definir o modelo de bloco

Antes de escrever a JavaScript, defina quais campos um autor controla e quais campos o código renderiza por conta própria, para que o modelo de conteúdo permaneça pequeno.

O modelo em _estimated-delivery.json expõe apenas dois campos, o cabeçalho e o rótulo do botão. A lista de produtos, a marcação de formulário e os estados de resultado são renderizados pelo JavaScript do bloco Edge Delivery Services, não pelo conteúdo criado.

// blocks/estimated-delivery/_estimated-delivery.json
{
  "definitions": [
    {
      "title": "Estimated Delivery",
      "id": "estimated-delivery",
      "plugins": {
        "xwalk": {
          "page": {
            "resourceType": "core/franklin/components/block/v1/block",
            "template": {
              "name": "Estimated Delivery",
              "model": "estimated-delivery",
              "title": "When will it arrive?",
              "ctaText": "Check estimated delivery"
            }
          }
        }
      }
    }
  ],
  "models": [
    {
      "id": "estimated-delivery",
      "fields": [
        {
          "component": "text",
          "valueType": "string",
          "name": "title",
          "value": "When will it arrive?",
          "label": "Heading",
          "description": "Main heading shown above the delivery checker form."
        },
        {
          "component": "text",
          "valueType": "string",
          "name": "ctaText",
          "value": "Check estimated delivery",
          "label": "CTA Text",
          "description": "Label for the submit button."
        }
      ]
    }
  ],
  "filters": []
}

Para tipos de campo além de text, siga a sintaxe do modelo em Criar um bloco.

Registrar o bloco para o Editor Universal

O arquivo de modelo de bloco por si só não é suficiente para o Universal Editor oferecer o bloco no seletor de inserção. Dois outros arquivos precisam de uma entrada manual primeiro, pois eles listam os blocos por nome em vez de descobrirem automaticamente.

Adicionar o bloco ao grupo “Blocos” em models/_component-definition.json:

{ "...": "../blocks/estimated-delivery/_*.json#/definitions" }

Se o bloco deve ser inserível dentro de uma seção, também adicione sua id ao filters[0].components de models/_section.json:

"estimated-delivery"

models/_component-models.json não precisa deste tratamento. Ele inclui todos os blocos automaticamente por meio de um curinga, ../blocks/*/_*.json#/models, portanto, o esquema de campo do bloco sozinho é suficiente para alcançar component-models.json. models/_component-definition.json e models/_section.json não usam um curinga para este projeto, portanto, um novo bloco fica invisível no seletor até que seja adicionado a ambos por nome, mesmo que seu modelo seja compilado corretamente.

Compile ambas as edições nos arquivos de agregação do projeto (component-definition.json, component-filters.json e component-models.json), abordados em Criar o projeto JSON.

Implementar o bloco

Arquivos que você adicionará

blocks/estimated-delivery/
├── _estimated-delivery.json   # the block model, shown above
├── estimated-delivery.js      # decorate() renders the form and result states
└── estimated-delivery.css     # form layout and result state styling

Renderizar o formulário e um resultado de espaço reservado

Crie a função decorate() para renderizar uma seleção de produto, uma entrada de código postal, um botão de envio e uma área de resultado vazia. Mantenha o manipulador de envio como um stub por enquanto.

O readBlockContent() lê os dois campos criados no DOM do bloco. O Universal Editor renderiza cada campo de modelo como um filho <div> na ordem do campo, de modo que o cabeçalho seja o texto do primeiro filho e o rótulo do botão seja o do segundo, retornando para um padrão quando um campo estiver vazio:

// blocks/estimated-delivery/estimated-delivery.js
const DEFAULTS = {
  title: 'When will it arrive?',
  ctaText: 'Check estimated delivery',
};

const PRODUCTS = [
  { value: 'house-blend-medium-roast', label: 'House Blend - Medium Roast' },
  { value: 'frescopa-smart-machine', label: 'Fréscopa Smart Machine' },
  { value: 'insulated-travel-thermos', label: 'Insulated Travel Thermos' },
];

const PRODUCT_OPTIONS_HTML = PRODUCTS.map(
  (p) => `<option value="${p.value}">${p.label}</option>`,
).join('');

function getBlockText(el, fallback) {
  const text = el?.textContent?.trim();
  return text || fallback;
}

function readBlockContent(block) {
  const props = [...block.children].map((row) => row.firstElementChild);

  return {
    title: getBlockText(props[0], DEFAULTS.title),
    ctaText: getBlockText(props[1], DEFAULTS.ctaText),
  };
}

export default function decorate(block) {
  const { title, ctaText } = readBlockContent(block);

  block.innerHTML = `
    <div class="estimated-delivery">
      <h3 data-aue-prop="title" data-aue-label="Heading" data-aue-type="text">${title}</h3>
      <form class="estimated-delivery__form">
        <select name="sku">${PRODUCT_OPTIONS_HTML}</select>
        <input name="postcode" type="text" placeholder="e.g. 10001" required />
        <button type="submit" data-aue-prop="ctaText" data-aue-label="CTA Text" data-aue-type="text">${ctaText}</button>
      </form>
      <div class="estimated-delivery__result" aria-live="polite">
        <p>Select a product, enter your postcode, and click the button.</p>
      </div>
    </div>
  `;

  // form submit logic added in the next step
}

Os data-aue-prop, data-aue-label e data-aue-type marcam o cabeçalho e o texto do botão como campos editáveis no Universal Editor, o mesmo padrão usado em Criar um bloco. Este é o suporte, não o arquivo final. A implementação de referência estimated-delivery.js também inclui a lógica de busca de Conectar o bloco à AEM Edge Function, que se vincula ao arquivo completo quando essa lógica estiver em vigor.

NOTE
Alguns scaffolds de blocos começam com um modelo que importa readBlockConfig de scripts/aem.js. Este bloco não o usa. Com apenas dois campos, lê-los posicionalmente com readBlockContent() é mais simples do que o formato de configuração de valor-chave readBlockConfig espera. Remova essa importação se o editor a tiver adicionado.

Estilo do bloco

Adicione CSS para o layout do formulário, o estado do espaço reservado e os estados de resultado que o bloco do Edge Delivery Services é renderizado mais tarde (carregamento, erro, sucesso), após Desenvolver um bloco com CSS e JavaScript. Um trecho representativo de estimated-delivery.css:

/* blocks/estimated-delivery/estimated-delivery.css */
.estimated-delivery__form {
  display: grid;
  gap: var(--spacing-small);
  padding: var(--spacing-medium);
  background: #fff;
  border-radius: 12px;
  box-shadow: 0 4px 12px rgb(0 0 0 / 6%);
}

.estimated-delivery__placeholder {
  display: grid;
  gap: var(--spacing-xsmall);
  align-content: center;
  border: 2px dashed var(--color-neutral-400);
  border-radius: 12px;
  text-align: center;
}

O arquivo completo também estimula o ponteiro de carregamento e as cores de status do cartão de sucesso (in-stock, low-stock, out-of-stock), que o bloco Edge Delivery Services não renderiza até Conectar o bloco à Função Edge do AEM.

Enviar código e criar o bloco

  1. Encaminhe a ramificação para o GitHub.

  2. Faça logon no ambiente de autor do AEM. Na página inicial do AEM, vá para Ferramentas > Serviços na Nuvem > Configuração do Edge Delivery Services.

    Lista de configurações do Edge Delivery Services

  3. Selecione seu site (Frescopa), depois a entrada {Org}/{Repo} e, em seguida, as Propriedades para abrir sua Configuração do Edge Delivery Service. Atualize o campo Ramificação para estimated-delivery e selecione Salvar e Fechar.

    Campo da ramificação de Configuração do Serviço Edge Delivery

  4. No AEM Sites, crie a estrutura de página para esta ramificação, por exemplo /content/frescopa/en/dev/branches/estimated-delivery, seguindo o mesmo padrão de página Ramificações que Criar um bloco.

    Estrutura de página do AEM Sites para a ramificação de entrega estimada

  5. Abra a página no Universal Editor, adicione o bloco Entrega estimada à página e crie o cabeçalho e o texto do botão.

    Bloco de entrega estimado criado no Editor Universal

  6. Publicar para visualização para que o conteúdo fique disponível para o servidor de desenvolvimento local.

Visualizar o bloco localmente

Execute o site do Edge Delivery Services localmente e confirme a renderização do espaço reservado antes de programar a chamada de busca.

$ aem up

Abra a página criada em http://localhost:3000/dev/branches/estimated-delivery e confirme a renderização do texto do cabeçalho, formulário e espaço reservado como de criação. O botão Enviar ainda não faz nada.

Espaço reservado para bloco de entrega estimado no servidor de desenvolvimento local

Próximas etapas

Em Conectar o bloco à Função Edge do AEM, você conecta esse bloco do Edge Delivery Services à Função Edge do AEM que você criou na etapa anterior, substituindo o resultado do espaço reservado por dados em tempo real.

Recursos adicionais

recommendation-more-help
experience-manager-learn-help-cloud-service