pages.json

O arquivo pages.json contém as definições de todas as páginas do site dentro da pasta Pages, na raíz do projeto.
Nela é possível configurar o tipo de página, o arquivo .html dentro de Pages e qual o arquivo .graphql dentro de Queries a ser utilizado, além de customizações.

Estrutura base

A estrutura base é a seguinte:

{
    "type": "search",
    "path": "search.html",
    "query": "search.graphql"
}
AtributoTipoObrigatórioDescrição
typestringsimé o tipo da página. Atualmente existem quatro tipos possíveis:
  • search: para página de busca
  • product: para página de produto
  • hotsite: para página de hotsite
  • not_found: para páginas não encontradas
pathstringsimé o arquivo .html dentro da pasta Pages a ser utilizado.
querystringsimé o arquivo .graphql dentro da pasta Queries a ser utilizado.

Propriedade customs (array)

Existe a possibilidade de customizar a página a ser renderizada de acordo com regras específicas. Basta nomear um array customs e inserir as seguintes regras:

Para o tipo hotsite

Para páginas do tipo hotsite é possível inserir um objeto contendo as propriedades:

AtributoTipoObrigatórioDescrição
urlMatchstringnãoExpressão da URL buscada no navegador que dará match para utilizar a regra especificada. É possível utilizar:
  • Palavra vazia
  • Palavra literal
  • *(asterisk) para qualquer coisa digitada
  • | (pipe) para representar OU
  • Mescla das regras acima
subtypestringnãoPode ser utilizado como regra de match de acordo com subtipo da página de hotsite. Atualmente existem os seguintes subtipos possíveis:
  • category: para categorias
  • brand: para fabricantes
  • portfolio: para portifólios
  • buy_list: para lista de compras
priorityintegernãoPrioridade da regra de match. Se o match ocorrer em duas ou mais regras, o critério de desempate será através da maior prioridade.
content_for_pagenãoDefine quais blocos podem ser usados no Design Studio(CMS) daquela página.

Propriedades opcionais

  • path
  • query

Caso sejam informados, serão os arquivos .html e .graphql a serem renderizados, respectivamente. Caso não sejam informados, serão renderizados os arquivos especificados nas propriedades path e query principais.

🚧

Atenção

Para fazer sentido a utilização de customs, aconselhamos que utilize pelo menos uma das propriedades opcionais.

Exemplo:

{
    "type": "hotsite",
    "path": "hotsite.html",
    "query": "hotsite.graphql",
    "customs": [
        {
            "urlMatch": "",
            "path": "home.html",
            "query": "home.graphql"
        },
        {
            "urlMatch": "listadedesejos",
            "path": "custom/wishlist.html"
        },
        {
            "urlMatch": "*",
            "subtype": "brand",
            "path": "custom/brands.html",
            "priority": 10
        },
        {
            "urlMatch": "*vans*",
            "path": "custom/vans.html",
            "priority": 20
        },
        {
            "urlMatch": "outlet*|black-friday",
            "path": "custom/promo.html"
        },
        {
            "urlMatch": "mycategory",
            "subtype": "category",
            "path": "category.html"
        }
    ]
}

Para o tipo product

Para páginas do tipo product é possível inserir um objeto semelhante ao de hotsite, mas sem a propriedade subtype, pois é exclusiva de páginas desse tipo.
Existem propriedades extras exclusivas para o tipo product:

  • productIds: um array de IDs de produtos que serão utilizados para dar match e utilizar a regra especificada.
  • categoryIds: um array de IDs de categorias que segue o mesmo intuito de productIds, mas para categorias.

As propriedades opcionaispath e query também são válidas e seguem as mesmas regras do tipo hotsite.

Exemplo:

{
    "type": "product",
    "path": "product.html",
    "query": "product.graphql",
    "customs": [
        {
            "urlMatch": "kit-pratico*",
            "path": "custom/custom_product.html",
            "priority": 1
        },
        {
            "productIds": [9, 222],
            "path": "custom/custom_product.html",
            "priority": 2
        },
        {
            "categoryIds": [473],
            "path": "custom/custom_product.html",
            "priority": 10
        }
    ]
}

Pages no Storefront 2.0

Com o lançamento do Storefront 2.0, em que o checkout também é altamente customizável, foi incluído outros tipos de páginas dentro do pages.json as quais podem ser consultadas por meio desta documentação.

Design Studio (CMS)

No contrato atual, cada item de content_for_pageaceita:

  • type: identificador do bloco aceito na página.

Esse valor deve corresponder ao:

  • type declarado no arquivo Blocks/<type>.schema.json
  • nome base do arquivo Blocks/<type>.html
  • nome base do arquivo Blocks/<type>.schema.json

Exemplo:

No exemplo abaixo, a home da loja aceita cinco tipos de blocos no CMS:

{
  "type": "hotsite",
  "path": "hotsite.html",
  "query": "hotsite_with_cursor.graphql",
  "customs": [
    {
      "urlMatch": "",
      "path": "home.html",
      "query": "home.graphql",
      "content_for_page": [
        { "type": "banner_button" },
        { "type": "product_carousel" },
        { "type": "banner_carousel" },
        { "type": "button_carousel" },
        { "type": "image_showcase" }
      ]
    }
  ]
}

Como interpretar

  • content_for_page não cria o bloco por si só. Ele apenas informa quais tipos de bloco a página aceita.
  • Cada type listado deve existir na pasta Blocks.
  • Se um bloco for listado em content_for_page, mas o schema correspondente não existir ou estiver inválido, o salvamento do CMS será rejeitado.

Escopo: em quais customs o content_for_page pode ser declarado

O content_for_page pode ser declarado em qualquer item de customs de uma página do tipo hotsite — não apenas no custom da home.

Isso vale tanto para um custom que atende uma única URL quanto para um custom cujo urlMatch atende várias URLs ao mesmo tempo:

{
  "type": "hotsite",
  "path": "hotsite.html",
  "query": "hotsite.graphql",
  "customs": [
    {
      "urlMatch": "",
      "path": "home.html",
      "query": "home.graphql",
      "content_for_page": [
        { "type": "banner_carousel" },
        { "type": "product_carousel" }
      ]
    },
    {
      "urlMatch": "calca|camiseta|blazer|saias",
      "path": "custom/roupas.html",
      "query": "hotsite.graphql",
      "priority": 10,
      "content_for_page": [
        { "type": "banner_button" },
        { "type": "product_carousel" },
        { "type": "image_showcase" }
      ]
    }
  ]
}

No exemplo acima, /calca, /camiseta, /blazer e /saias são atendidas pelo mesmo custom — portanto pelo mesmo template (custom/roupas.html) — e todas oferecem no Design Studio os mesmos três tipos de bloco.

O urlMatch define o universo de URLs do template

O layout de CMS é salvo por template, e o urlMatch é o que determina quais URLs reais da loja caem naquele template. Por consequência:

  • um urlMatch que casa com muitas URLs cria um template que atende muitas URLs, e o layout salvo nele vale para todas elas;
  • a lista de URLs que o lojista vê no Design Studio para aquele template é montada a partir dos hotsites cadastrados na loja cuja URL casa com esse urlMatch (respeitando também subtype e priority);
  • uma URL cadastrada depois de o layout ter sido salvo passa a herdar o layout do template automaticamente, sem nenhuma ação adicional.

Layout exclusivo por URL

A partir da entrega de layout exclusivo por URL, o lojista pode desvincular uma URL específica do template e dar a ela um layout próprio, sem que isso afete as demais URLs do mesmo urlMatch.

Do lado do tema não há nada a configurar para habilitar isso: basta que o custom tenha content_for_page e que a página renderize wake_content_for_page. A escolha entre "editar o template" e "editar só esta página" é feita pelo lojista no Design Studio.

O que muda é a ordem de resolução do layout na renderização:

  1. layout exclusivo daquela URL, se existir e estiver vigente;
  2. layout do template (vale para todas as URLs do urlMatch);
  3. os fallbacks já existentes.

Especificidade vence recência: se /camiseta tem layout exclusivo, uma publicação nova no template não sobrescreve /camiseta. Ela continua com o layout exclusivo até que alguém a revincule ao template pelo Design Studio.

Detalhes completos do comportamento, do fluxo de desvincular/revincular e dos impactos em histórico e agendamento estão em Design Studio — Layout exclusivo por URL.

Vitrines por audiência

Nada muda no pages.json. Não há propriedade nova, nem sinalização de audiência em content_for_page. A página continua declarando apenas os type de bloco que aceita.

A variação por audiência é declarada no schema do bloco (varyByAudience: true) e configurada pelo lojista no Design Studio, em lojas com o add-on de audiências ativo. Veja Blocks e Design Studio — Vitrines por audiência.

Como usar na página

Além de configurar o content_for_page no pages.json, a página precisa prever o ponto onde os blocos CMS serão renderizados.

O padrão recomendado é:

  • usar wake_has_content_for_page para verificar se existem blocos CMS salvos para aquela renderização

  • usar wake_content_for_page para renderizar os blocos na ordem em que foram salvos.

    O content_for_page pode ser declarado em dois níveis:

    • No item de customs — vale para as URLs atendidas por aquele custom.
    • No nível da página (ex.: no objeto hotsite) — vale para as URLs atendidas pelo template base da página; também é usado como fallback quando o custom correspondente não declara content_for_page próprio.
  • manter um fallback com o conteúdo estático original da página, quando isso fizer sentido para o template

Exemplo prático com Pages/home.html

{{ if wake_has_content_for_page }}
    {{ wake_content_for_page }}
{{ else }}
    {{ banners_carousel id: "banners_top" banners: data.hotsite.banners position: "Topo" }}
    {{ spot_carousel products: data.lancamentos.products.nodes class:"new-release" title:"Lançamentos" }}
    {{ spot_carousel products: data.mais_vendidos.products.nodes class:"best-sellers" title:"Mais Vendidos" }}
    {{ newsletter information_groups: data.newsletter_information_group_fields }}
    {{ brands_carousel brands: data.brands.nodes }}
{{ end }}

O que esse exemplo faz:

  • Se existirem blocos CMS carregados na página, wake_content_for_page renderiza esses blocos.
  • Se não existirem blocos CMS, a página continua exibindo os componentes padrão do template.
  • Esse formato é útil para páginas como a home, em que o template já possui uma composição padrão e a agência quer migrar gradualmente para blocos CMS.

Significado das variáveis

  • wake_has_content_for_page: fica true quando a página possui pelo menos um bloco.
  • wake_content_for_page: percorre os blocos salvos e renderiza o arquivo Blocks/<type>.html correspondente a cada item.

Quando usar fallback
Use o else com conteúdo estático quando:

  • a página já possui uma estrutura legada que deve continuar funcionando sem configuração CMS
  • a agência quer liberar o CMS sem perder a composição atual da página
  • o template precisa funcionar corretamente mesmo antes do primeiro bloco ser cadastrado

Atenção em templates que atendem várias URLs

Quando o mesmo custom atende várias URLs, o wake_content_for_page é resolvido por URL na renderização: cada URL recebe o seu layout exclusivo, se tiver um, ou o layout do template, se não tiver.

Duas consequências práticas para o template:

  • O fallback do else continua sendo importante. URLs sem layout exclusivo e sem layout de template caem no fallback estático. Em um custom que atende dezenas de URLs, é normal que a maior parte delas fique nessa situação por um bom tempo.
  • O que está fora do bloco wake_content_for_page não é afetado. O override por URL age apenas na região de blocos do CMS. SEO, banners vindos da query do hotsite e qualquer markup fixo do template continuam sendo resolvidos como sempre foram — o SEO, inclusive, já é por URL, porque vem do cadastro do hotsite.