Garrafas ao mar

Caixa de comentários no Bear

Olá, queridos!

Como havia prometido, venho explicar como colocar no seu blog uma caixa de comentários semelhante a que estou usando por aqui. O próprio Herman indica o uso dessa ferramenta, está na documentação do Bear. Mas tive uma certa dificuldade de deixar como eu queria, por isso venho passar pra frente um código pronto pra uso que vai facilitar bastante a sua vida.

Como quem de fato fez o código pra mim foi a IA, não vou me furtar de aproveitar o serviço e, portanto, pedi para que montasse o tutorial completo abaixo. Mas fiquem tranquilos, antes de postar eu me dei ao trabalho de criar um blog novo só pra testar se todo o processo funcionava certinho e agora já posso dormir tranquila, pois sei que vai ficar lindo no blog de vocês que queiram usar.

O Cusdis é uma alternativa leve, de código aberto e focada em privacidade. Este guia mostra como integrá-lo de forma limpa ao seu Bear Blog, fazendo com que o widget converse diretamente com a tipografia e as cores nativas do seu tema.

1. Criar a conta no Cusdis

  1. Acesse cusdis.com e crie uma conta gratuita.
  2. Crie um novo projeto com o nome do seu blog.
  3. Copie o seu App ID (um código em formato UUID, como 7621edcc-...).

2. Inserir a estrutura no Template de Post

Para que a caixa de comentários apareça automaticamente ao final de todos os textos publicados sem que você precise colar códigos manualmente a cada post, adicione a estrutura diretamente no template de posts do seu blog.

No painel do Bear Blog, vá em Posts > Edit template e insira o código a seguir:

<div id="cusdis_thread"
  data-host="https://cusdis.com"
  data-app-id="SEU_APP_ID_AQUI"
  data-page-id=""
  data-page-url=""
  data-page-title="{{ PAGE_TITLE }}"
></div>

<script async defer src="https://cusdis.com/js/cusdis.es.js"></script>
<script>
  // Preenche dinamicamente o ID e a URL com base no post atual para isolar os comentários
  document.getElementById('cusdis_thread').setAttribute('data-page-id', window.location.pathname);
  document.getElementById('cusdis_thread').setAttribute('data-page-url', window.location.href);
</script>

(Lembre-se de substituir SEU_APP_ID_AQUI pelo identificador gerado na sua conta do Cusdis).

3. Estilizar e herdar as fontes do tema via CSS

Como o Cusdis é renderizado dentro de um iframe isolado, os elementos internos dele não puxam a tipografia do site automaticamente por padrão. Para ajustar o espaçamento e preparar o terreno para a herança visual, adicione estas regras no CSS do seu blog:

/* Espaçamento do container do Cusdis */
#cusdis_thread {
  width: 100%;
  margin-top: 3rem;
  margin-bottom: 2rem;
}

/* Ajustes estruturais do iframe */
#cusdis_thread iframe {
  width: 100% !important;
  min-height: 350px;
  background: transparent !important;
  border: none !important;
}

4. Traduzir e herdar a tipografia nativa via JavaScript

Para garantir que os campos de texto, botões e rótulos de dentro do Cusdis assumam exatamente a mesma fonte e herdem as variáveis visuais configuradas no tema do seu blog (além de traduzir a interface para o português), adicione este script no rodapé global do site (Footer directive):

<script>
  (function() {
    'use strict';

    function styleAndTranslateCusdis() {
      const iframe = document.querySelector('#cusdis_thread iframe');
      if (!iframe) return;

      try {
        const iframeDoc = iframe.contentDocument || iframe.contentWindow.document;
        if (!iframeDoc) return;

  // Captura as propriedades visuais de forma genérica para qualquer tema do Bear Blog
        const rootStyle = window.getComputedStyle(document.documentElement);
        const computedBody = window.getComputedStyle(document.body);
        
        const fontFamily = computedBody.fontFamily || rootStyle.getPropertyValue('--font-secondary') || rootStyle.getPropertyValue('--font-main') || 'sans-serif';
        const textColor = computedBody.color || rootStyle.getPropertyValue('--text-color') || '#333333';
        const bgColor = computedBody.backgroundColor || rootStyle.getPropertyValue('--background-color') || '#ffffff';
        const linkColor = rootStyle.getPropertyValue('--link-color') || computedBody.color || '#0066cc';

        // Injeta estilos, herança de fontes, cores e o travamento do overflow interno
        if (!iframeDoc.getElementById('theme-sync-style')) {
          const themeStyle = iframeDoc.createElement('style');
          themeStyle.id = 'theme-sync-style';
          themeStyle.innerHTML = `
            body, html {
              font-family: ${fontFamily} !important;
              color: ${textColor} !important;
              background-color: transparent !important;
              overflow: hidden !important;
            }
            input, textarea, button {
              font-family: ${fontFamily} !important;
              background-color: color-mix(in srgb, ${textColor} 8%, ${bgColor}) !important;
              color: ${textColor} !important;
              border: 1px solid ${linkColor} !important;
              border-radius: 4px !important;
            }
            button {
              background-color: ${linkColor} !important;
              color: ${bgColor} !important;
              font-weight: bold;
              cursor: pointer;
            }
            a {
              color: ${linkColor} !important;
            }
          `;
          iframeDoc.head.appendChild(themeStyle);
        }

        // Recálculo imediato da altura baseado no scrollHeight interno
        const contentHeight = iframeDoc.body.scrollHeight;
        if (contentHeight && contentHeight > 50) {
          iframe.style.width = '100%';
          iframe.style.height = (contentHeight + 30) + 'px';
          iframe.style.border = 'none';
        }

        // Traduções
        const translations = {
          'Nickname': 'Nome',
          'Email (optional)': 'E-mail (opcional)',
          'Reply...': 'Escreva uma resposta...',
          'Comment': 'Comentar',
          'Reply': 'Responder'
        };

        const walker = document.createTreeWalker(iframeDoc.body, NodeFilter.SHOW_TEXT, null, false);
        let node;
        while (node = walker.nextNode()) {
          let text = node.nodeValue.trim();
          if (translations[text]) {
            node.nodeValue = translations[text];
          }
          if (text.includes('Your comment has been sent') || text.includes('wait for approval')) {
            node.nodeValue = 'Obrigada! Seu comentário foi enviado e aguarda moderação.';
          }
        }

        iframeDoc.querySelectorAll('input, textarea, button').forEach(el => {
          if (el.placeholder && translations[el.placeholder]) {
            el.placeholder = translations[el.placeholder];
          }
          if (el.value && translations[el.value]) {
            el.value = translations[el.value];
          }
          if (el.innerText && translations[el.innerText.trim()]) {
            el.innerText = translations[el.innerText.trim()];
          }
        });
      } catch (e) {}
    }

    // Ouvinte de mensagens do Cusdis para redimensionamento contínuo
    window.addEventListener('message', (e) => {
      if (e.origin === 'https://cusdis.com') {
        try {
          const data = JSON.parse(e.data);
          if (data.event === 'resize') {
            const iframe = document.querySelector('#cusdis_thread iframe');
            if (iframe && data.data && data.data.height) {
              iframe.style.width = '100%';
              iframe.style.height = (data.data.height + 30) + 'px';
              iframe.style.border = 'none';
            }
          }
        } catch (err) {}
        setTimeout(styleAndTranslateCusdis, 50);
      }
    });

    // Gatilhos de carregamento inicial
    setTimeout(styleAndTranslateCusdis, 500);
    setTimeout(styleAndTranslateCusdis, 1500);
    setTimeout(styleAndTranslateCusdis, 3000);
  })();
</script>

Com essa estrutura, a caixa de comentários será injetada de forma limpa e automática ao final de cada post, com os textos traduzidos e integrados à identidade tipográfica do blog.

Fim! 😊

Quer comentar algo?

Envie uma mensagem no próprio post, no livro de visitas ou, melhor ainda, me escreva um e-mail. Será um prazer ler o que você tem a dizer!