Navegação aprimorada para tags (estruturadas)

Olá a todos,

Estou tentando garantir que as tags tenham uma visibilidade mais estruturada na navegação, especialmente para aqueles de nós que dependem de Pai > Filhos. Temos pouco mais de 40 tags, então uma navegação estruturada para tags (que, aviso de palestrante, são muito subutilizadas por muitos fóruns, e nas quais o Discourse se destaca!) é bastante vital.

Como é ridículo adicionar vários menus acima da navegação nativa do Discourse, minha proposta (acho?) não é nada muito dramático. Fiz um mock-up bem tosco como uma ideia…

Se algo assim já existe, não consigo encontrar. O componente do @Johani é o mais próximo, mas, infelizmente, não é estruturado.

De qualquer forma, adoraria qualquer feedback, mesmo que seja “Isso não faz sentido” ou “Levei 10 segundos para localizar isso no GitHub, novato”.

Obrigado!

2 Curtiram

Com a quantidade de tags parent > child que alguns sites podem ter, elas não caberão todas ali.

Por exemplo: veja as tags do Meta

https://meta.discourse.org/tags

2 Curtiram

Compreendo esse ponto — eu diria que o exemplo do [tip-toeing] meta não é a melhor maneira de usar tags, embora não haja nenhuma prática óbvia e consolidada sobre o assunto. Mas, mesmo como apenas uma opção para aqueles de nós que têm um vocabulário controlado de tags e dependemos muito delas (muito mais do que de categorias), isso pode ser útil. Meu exemplo foi apenas isso… suspeito que outros podem ter uma ideia melhor!

2 Curtiram

Por que não usar simplesmente a página de tags? Você poderia destacar o link para essa página de várias maneiras. A própria página suporta, por padrão, a organização por grupos.

Em seguida, você pode adicionar estilos personalizados, seja para as tags:

Ou estilizar o layout de toda a página para obter uma apresentação mais específica.

2 Curtiram

Sim, adoro a página de tags — e a flexibilidade que ela oferece. É excelente. Mas a página de tags não é onipresente, enquanto um menu proporcionaria uma navegação dinâmica e sempre visível, como acontece com as categorias.

Suspeito que, assim como eu, há alguns de nós que dependem muito mais das tags do que das categorias. Isso pode parecer contra-intuitivo, mas faz sentido em certos contextos. Até o exemplo do carro usado no post Tags se beneficiaria de algo assim. Se for para entusiastas de carros, por exemplo, eles podem preferir alternar entre tags (“Ford vs Ferrari”), em vez de categorias.

Mas, enfim, talvez vocês ainda não estejam prontos para isso. Mas seus filhos vão adorar. :wink:

1 Curtiu

Ficaria feliz se você encontrasse uma solução mais dinâmica! Mas imagino que isso envolveria uma quantidade considerável de codificação, caso você queira algo que não precise ser mantido manualmente. Até lá, eu apenas tornaria o link para a página de tags mais ubíquo :wink:

Screenshot from 2021-10-22 21-57-26

O outro aspecto que torna as tags muito mais amigáveis ao usuário, na minha experiência, são os banners de tags adequados. Criei um componente simples como complemento ao componente de banners de tags, que permite adicionar descrições às tags: https://github.com/nolosb/discourse-tag-banners-descriptions

3 Curtiram

Uma direção um pouco diferente: adaptei a renderização de tags em tópicos e nas listas de tópicos para mostrar a hierarquia no estilo de breadcrumb: “pai > filho” em vez de “filho, pai”.

Minha solução foi um tanto específica do site e bastante hacky, mas o resultado final é agradável.

O maior obstáculo para o que fiz e para o que você quer fazer é que o Discourse não pré-carrega os grupos de tags, então eles não estão disponíveis quando você precisa deles sem fazer uma requisição à API. Acredito que deveria fazer isso, da mesma forma que a estrutura de categorias é pré-carregada.

3 Curtiram

O problema aqui é uma limitação de espaço e não uma limitação técnica.

como observado aqui

Imagine sua experiência como usuário; se você abrir um menu em um site, ele se parece com isto.

Você ficaria sobrecarregado, para dizer o mínimo. Especialmente porque esse menu não tem uma função de pesquisa para ajudar a filtrar os resultados.

Então, vamos tentar encontrar o meio-termo entre o que você quer fazer e o que os usuários querem experimentar. Como fazemos isso? Mostramos um número limitado de grupos de tags e indicamos que há mais para ver. Então, algo assim:

Então, como você faz isso?

Aqui está o código:

<script type="text/discourse-plugin" version="0.8">
const MAX_TAGS_TO_SHOW = 20;
const Category = require("discourse/models/category").default;
const siteSettings = api.container.lookup("site-settings:main");
const tagStyle = siteSettings.tag_style;

const getNumberOfTags = (tags, categoryTagsGroups) => {
  let count = 0;
  count = tags.length;
  for (const categoryTagsGroup of categoryTagsGroups) {
    count = count + categoryTagsGroup.tags.length;
  }
  return count;
};

fetch("/tags.json")
  .then(response => response.json())
  .then(data => {
    try {
      const tags = data.tags;
      const hasCategoryTagGroups = data.extras?.categories;

      if (hasCategoryTagGroups) {
        const categoryTagsGroups = data.extras.categories;
        let moreCount = getNumberOfTags(tags, categoryTagsGroups);
        let visibleCount = 0;

        const content = [];
        for (const categoryTagsGroup of categoryTagsGroups) {
          const category = Category.findById(categoryTagsGroup.id);
          const name = category.name;
          const childTags = categoryTagsGroup.tags;
          const childTagNodes = [];

          childTags.forEach((tag, index) => {
            if (visibleCount <= MAX_TAGS_TO_SHOW) {
              childTagNodes.push(
                api.h(
                  "li.tag-link-item",
                  api.h(
                    `a.discourse-tag.tag-link.${tagStyle}`,
                    { href: `/tag/${tag.text}` },
                    tag.text
                  )
                )
              );
              moreCount--;
              visibleCount++;
            }
          });

          if (childTagNodes.length) {
            content.push([
              api.h("li.heading", api.h("span", name)),
              childTagNodes
            ]);
          }
        }

        api.decorateWidget("menu-links:after", helper => {
          if (helper.attrs.name !== "general-links") return;
          return api.h("div.clearfix", [
            api.h("ul.tag-links", [
              api.h("a.categories-link", { href: "/tags" }, [
                "Tags ",
                moreCount ? `(${moreCount} mais)...` : ""
              ]),
              content
            ]),
            api.h("hr")
          ]);
        });
      }
    } catch (error) {
      console.error("Há um problema no componente do tema de tags do menu hambúrguer");
      console.error(error);
    }
  })
  .catch(console.error);

</script>

Isso vai na aba header do seu tema. Você pode alterar

const MAX_TAGS_TO_SHOW = 20;

no topo para o número de tags que deseja mostrar.

Depois, tudo o que você precisa adicionar é um pouco de CSS para estilizar os links. Aqui está algo básico para começar.

.tag-links {
  .heading {
    padding: 0.25em 0.5em;
  }
  .tag-link-item {
    background-color: transparent;
    display: inline-flex;
    align-items: center;
    padding: 0.25em 0.5em;
    width: 50%;
    box-sizing: border-box;
    .tag-link {
      display: inline-flex;
      width: 100%;
      &:hover {
        color: var(--primary);
      }
    }
  }
}

Note que o JavaScript acima respeitará o estilo de tag definido nas configurações do seu site. Além disso, se o seu site depende muito de tags, provavelmente você não precisa ter as categorias visíveis nesse menu. Ocultá-las ajudaria a reduzir a confusão do usuário.

Também, se você adicionar uma seção expandida de tags, então esse link se torna redundante.

Então, vamos escondê-los com algo assim.

.panel-body {
  .category-links,
  .categories-separator,
  .widget-link[href="/tags"] {
    display: none;
  }
}

Finalmente, como observado aqui:

Esses dados não são passados para o cliente por padrão, a menos que você visite /tags, então o código acima adiciona uma solicitação adicional na página inicial (executa apenas uma vez por visita). O Discourse tenta manter as coisas muito simples, então, a menos que os dados sejam necessários, eles não serão carregados por padrão.

Não vejo isso sendo adicionado ao núcleo do Discourse tão cedo. Portanto, uma solicitação extra é praticamente sua única opção aqui, a menos que você queira escrever um plugin que seja executado no servidor.

7 Curtiram

Obrigado, Joe, isso é fantástico!

Algumas coisas rápidas… Notei que sua resposta original puxou por grupo de tags (em vez de tags filhas). Há algum motivo para isso? Não consegui fazer as tags filhas aparecerem, mas tive sorte com sua resposta inicial usando o grupo de tags.

O único problema é que as tags não são visíveis para usuários deslogados. Estou assumindo que isso seja relacionado à API? Existe alguma solução para isso?

De qualquer forma, isso é uma benção — consigo ver com certeza outras pessoas usando esse código. Muito obrigado!

2 Curtiram

Criei um componente de tema que deve tornar isso um pouco mais fácil. Você pode escolher entre:

  1. grupos de tags aninhados
  2. tags de categoria permitidas aninhadas
  3. tags principais planas

Mais detalhes aqui

1 Curtiu

Indico o Joe como o Santo Padroeiro do Discourse.

1 Curtiu

hahaha, eu também estava ocupado criando um para meu curso de treinamento.

que pena.

obrigado mesmo assim

2 Curtiram