Índice dinâmico no Webflow CMS – A maneira mais fácil

Publicados: 2022-03-22
Recentemente, tornamos possível adicionar estados ativos a um índice fixo – consulte o final do artigo para obter instruções!

Fundo

Na Flowrite, recentemente começamos a escrever peças de conteúdo mais longas e queríamos tornar nossos blogs mais legíveis, começando pelo elemento mais básico – sumário.

Estamos usando o Webflow e adoramos, mas descobri que criar ToCs escaláveis ​​para itens de CMS não era tão simples. Todas as soluções existentes dependem da configuração de IDs e links manualmente ou do uso de plugins de terceiros.

Queríamos um sistema simples que gerasse automaticamente ToCs com base nos títulos de nossos blogs. Foi isso que construímos, e veja como você pode fazer o mesmo!

Como funciona?

  1. Projete seus itens de ToC. Faça-os da maneira que quiser - crie estados de foco, animações etc.
  2. Crie um div para o ToC com um id específico em qualquer lugar da sua página do CMS.
  3. Insira um pedaço de código no final da tag <body> em sua página do CMS.
  4. Os ToCs são gerados automaticamente para cada item do CMS.

Criando seu índice dinâmico

Projete seus itens de ToC

Dê uma classe ao seu item de ToC (usamos "tocitem") e estilize-o da maneira que desejar.

Minha recomendação é usar uma página separada e privada para projetar esses elementos. Dessa forma, você pode modificar facilmente o design posteriormente, se necessário.

Adoramos a simplicidade dos elementos do Índice do Notion, então usamos isso como referência.


Se você quiser incluir mais de um tipo de título, certifique-se de dar a eles uma classe adicional ("toc-h2", "toc-h3", etc.)

Crie o elemento para seu ToC

Adicione um div onde quiser que seu ToC esteja e dê a ele um id "toc". Novamente, você pode estilizar esse elemento da maneira que desejar.

Se você quiser ter seu ToC dentro de seu elemento rich text, consulte o final deste artigo para obter mais detalhes.

Por último, dê ao elemento Rich Text um id "conteúdo". Isso será necessário mais tarde para garantir que usamos os títulos corretos no ToC.

Escolha entre duas opções

Como os ToCs serão gerados automaticamente, precisamos indicar quais títulos queremos incluir neles. Neste post, abordamos duas opções:

  1. Gerando ToCs com base em apenas um único tipo de título estático, por exemplo H2s.
  2. Gerando ToCs com base em vários títulos de sua escolha – por exemplo, H2s e H3s para uma postagem de blog e H2s e H4s para outra.

Opção 1: ToCs de título único

Nesta opção, os ToCs serão sempre gerados com base no mesmo título.

Insira o seguinte código no final da sua tag <body> nas páginas de sua coleção. Veja os comentários no final de cada linha se quiser entender como funciona.

  <script> document.getElementById("content").querySelectorAll("h2").forEach(function(heading, i) { // runs a function for all h2 elements inside your rich text element heading.setAttribute("id", "toc-" + i); // gives each h2 a unique id let str = heading.innerHTML; // adds section titles to slugs str = str.replace(/\s+/g, '-').replace(/[°&\/\\#,+()$~%.'":;*?<>{}]/g, "").toLowerCase(); // replaces spaces with hyphens, removes special characters and extra spaces from the headings, and applies lowercase in slugs heading.setAttribute("id", str); // gives each heading a unique id const item = document.createElement("a"); // creates an anchor element called "item" for each h2 item.innerHTML = heading.innerHTML // gives each item the text of the corresponding heading item.setAttribute("class", "tocitem"); // gives each item the correct class item.setAttribute("href", "#" + str); // gives each item the correct anchor link document.querySelector("#toc").appendChild(item); // places each item inside the Table of Contents div }); </script>
<script> document.getElementById("content").querySelectorAll("h2").forEach(function(heading, i) { // runs a function for all h2 elements inside your rich text element heading.setAttribute("id", "toc-" + i); // gives each h2 a unique id let str = heading.innerHTML; // adds section titles to slugs str = str.replace(/\s+/g, '-').replace(/[°&\/\\#,+()$~%.'":;*?<>{}]/g, "").toLowerCase(); // replaces spaces with hyphens, removes special characters and extra spaces from the headings, and applies lowercase in slugs heading.setAttribute("id", str); // gives each heading a unique id const item = document.createElement("a"); // creates an anchor element called "item" for each h2 item.innerHTML = heading.innerHTML // gives each item the text of the corresponding heading item.setAttribute("class", "tocitem"); // gives each item the correct class item.setAttribute("href", "#" + str); // gives each item the correct anchor link document.querySelector("#toc").appendChild(item); // places each item inside the Table of Contents div }); </script>

Publique o site e pronto

Opção 2: ToCs de vários títulos

Esta opção lhe dá a chance de determinar caso a caso quais títulos serão usados ​​para gerar os ToCs.

Vamos começar criando um novo campo de texto em sua coleção. Nós o chamamos de "TOC baseado em...". É aqui que você especifica os títulos que serão usados ​​no ToC de cada item do CMS. Separe com uma vírgula e não inclua espaços.


Agora, insira o seguinte código no final da sua tag <body> em suas páginas de coleção. Veja os comentários no final de cada linha se quiser entender como funciona.

  <script> document.getElementById("content").querySelectorAll("[HEADINGS]").forEach(function(heading, i) { // runs a function for all headings inside your rich text element let str = heading.innerHTML; // adds section titles to slugs str = str.replace(/\s+/g, '-').replace(/[°&\/\\#,+()$~%.'":;*?<>{}]/g, "").toLowerCase(); // replaces spaces with hyphens, removes special characters and extra spaces from the headings, and applies lowercase in slugs heading.setAttribute("id", str); // gives each heading a unique id const item = document.createElement("a"); // creates an anchor element called "item" for each heading item.innerHTML = heading.innerHTML; // gives each item the text of the corresponding heading ("[HEADINGS]").split(",").forEach(function(x) { // runs a function for each item in your headings list if (heading.tagName.toLowerCase()==x) { item.classList.add("tocitem", "toc-" + x); // gives each item the correct class } }); item.setAttribute("href", "#" + str); // gives each item the correct anchor link document.querySelector("#toc").appendChild(item); // places each item inside the Table of Contents div }); </script>
<script> document.getElementById("content").querySelectorAll("[HEADINGS]").forEach(function(heading, i) { // runs a function for all headings inside your rich text element let str = heading.innerHTML; // adds section titles to slugs str = str.replace(/\s+/g, '-').replace(/[°&\/\\#,+()$~%.'":;*?<>{}]/g, "").toLowerCase(); // replaces spaces with hyphens, removes special characters and extra spaces from the headings, and applies lowercase in slugs heading.setAttribute("id", str); // gives each heading a unique id const item = document.createElement("a"); // creates an anchor element called "item" for each heading item.innerHTML = heading.innerHTML; // gives each item the text of the corresponding heading ("[HEADINGS]").split(",").forEach(function(x) { // runs a function for each item in your headings list if (heading.tagName.toLowerCase()==x) { item.classList.add("tocitem", "toc-" + x); // gives each item the correct class } }); item.setAttribute("href", "#" + str); // gives each item the correct anchor link document.querySelector("#toc").appendChild(item); // places each item inside the Table of Contents div }); </script>

Por fim, certifique-se de substituir [HEADINGS] pelo valor do seu campo "ToC based on..." CMS.


É isso, você está pronto para publicar.

Costumização

Estados ativos em um índice fixo

Inspirados pela postagem de Chris Coyier sobre CSS-Tricks, criamos uma maneira de adicionar estados ativos a itens de ToC visíveis – um ótimo recurso para ToCs fixos.

Em primeiro lugar, adicione "observer.observe(heading);" no início do código que você implementou anteriormente. Veja a captura de tela para o local correto.

Em seguida, adicione o seguinte trecho de código em cima de todo o código de ToC existente:

  <script> const observer = new IntersectionObserver(entries => { entries.forEach(entry => { const id = entry.target.getAttribute("id"); if (entry.isIntersecting) { document.querySelectorAll(".active").forEach((z) => { z.classList.remove("active") }); document.querySelector(`a[href="#${id}"]`).classList.add("active"); } }); }, { rootMargin: '0px 0px -75% 0px' }); </script>
<script> const observer = new IntersectionObserver(entries => { entries.forEach(entry => { const id = entry.target.getAttribute("id"); if (entry.isIntersecting) { document.querySelectorAll(".active").forEach((z) => { z.classList.remove("active") }); document.querySelector(`a[href="#${id}"]`).classList.add("active"); } }); }, { rootMargin: '0px 0px -75% 0px' }); </script>

O código adiciona uma classe chamada "ativa" a um tocitem visível e remove a classe quando um novo tocitem aparece.

Por último, certifique-se de estilizar a classe "active" dando-lhe uma cor de fundo diferente, por exemplo.

Exibir ToCs em apenas alguns dos itens do CMS

Se você não quiser que um ToC apareça em alguns de seus itens do CMS, conclua as etapas a seguir:

‍ 1. Deixe o campo "ToC based on.." vazio.
Se você estiver usando a Opção 1, adicione um switch em sua coleção de CMS para indicar se o ToC deve aparecer ou não.

2. Torne a visibilidade do seu ToC div condicional com base no seletor na etapa 1.

3. Crie uma instrução if no início do trecho de código do ToC para evitar a execução da função se o campo estiver vazio. Lembre-se de fechar com "}".

ToC dentro do seu elemento Rich Text

Se você deseja colocar seu ToC dentro de seu elemento Rich Text, você pode replicar o elemento ToC div com um código de incorporação.

Crie um elemento de código personalizado dentro de seu Rich Text e copie e cole "<div id="toc" class="toc"></div>" no campo de código.


Se você deseja ter um ToC embutido em apenas alguns dos itens do CMS e um ToC "normal" em outros, você precisa fazer alguns truques adicionais:

1. Crie um seletor de opções com apenas uma opção: ".getElementById('content'). Selecione-o nos itens do CMS onde você deseja ter um ToC dentro do Rich Text.

2. Exiba o ToC "normal" somente se o seletor não estiver definido.


3. Adicione o valor do seletor à parte seguinte do código. Agora, se o seletor tiver sido selecionado, o código anexará os itens de ToC dentro da div de ToC correta.

Evite a sobreposição da barra de navegação na rolagem

Você pode notar que, ao clicar em um link de ToC, a página rola para baixo até o cabeçalho correto, mas é bloqueada pela barra de navegação.

Para corrigir isso:

  1. Certifique-se de que a posição do seu elemento nav esteja definida como "fixa"
  2. Altere a tag do elemento nav para "Header"

É isso! Caso você tenha algum problema ao longo do caminho, não hesite em me enviar um e-mail ou entrar em contato via Twitter / LinkedIn.

Eu adoraria saber também se você acaba usando este sistema, então, por favor, me envie um ping se você fez e compartilhe o post com outra pessoa que possa se beneficiar com isso ️