Criando um banner de página inicial "Categorias em Destaque"

Gostaria de criar uma seção de banner que fique abaixo do cabeçalho na página inicial e apresente algumas caixas de categoria com um visual mais elaborado. Por exemplo:

Entendo que posso usar o “outlet” abaixo-do-cabeçalho-do-site e as instruções de Como adicionar conteúdo personalizado que aparece apenas na sua página inicial para gerar meu markup.

Idealmente, gostaria de ter um campo de enumeração de configuração personalizada para selecionar quais categorias são destacadas aqui. É possível ter um campo de configuração personalizada que permita pesquisar categorias?

Também gostaria de ter uma imagem de fundo personalizada para esses cartões, além da imagem de fundo da categoria. É possível adicionar outro campo de entrada de arquivo na aba Imagens do modal de configurações da categoria? Por exemplo:

No geral, isso parece viável? Existem alguma armadilhas ou truques dos quais eu deva estar ciente?

Considere usar o plugin TLP como ponto de partida. Já existe um recurso de Imagens em Destaque que aponta para Tópicos. Você pode conseguir reutilizar parte do código.

Ele poderia usar isso?

Considerando que as categorias são menos dinâmicas, uma abordagem mais estática pode fazer sentido :+1:

Acho que você precisa decidir se deseja que seja orientada a dados ou não.

Idealmente, eu gostaria que fosse como uma versão sofisticada do ‘Box de Categoria com Tópicos’, que também carregasse o logotipo da categoria e a imagem de fundo, juntamente com os tópicos mais recentes dessa categoria.

No entanto, se isso não for direto usando os mecanismos padrão de extensão de tema/plugin, pode não valer o esforço. Nesse caso, farei de forma estática ou usarei o layout de caixas de categoria na página inicial e os estilizarei conforme necessário.

Acho que dois testes-chave são:

  1. Existe uma maneira padrão de expor um item de configuração ‘Selecionar Categoria’?
  2. Existe uma maneira padrão de adicionar campos de metadados ao modal de configurações da categoria?

Alternativamente, se eu puder apenas usar IDs de categoria na configuração, mas ainda assim conseguir obter os dados programaticamente, isso provavelmente seria aceitável.

Se, no entanto, não for realmente viável acessar os dados da categoria dessa maneira, usarei uma das outras abordagens.

Você pode fazer qualquer coisa que quiser em um plugin (embora seja obviamente melhor adotar estratégias que minimizem o risco de seu plugin quebrar após uma atualização do núcleo). Esboce suas ideias, copie de plugins existentes e do núcleo do Discourse e, em seguida, comece com uma versão simples e itere.

Eu revisei esta postagem anterior do Kris e a adaptei diretamente para algo que você possa usar como base. Grande parte do que é abordado aqui foi apresentada por ele em seu tópico original.
https://meta.discourse.org/t/how-to-add-a-featured-topic-list-to-your-discourse-homepage/132949

Todo o código será adicionado à seção </head> (head_tag.html) do seu tema.

Esta primeira seção verificará se a página em que você está é a “página inicial”.

Em seguida, obteremos as categorias do site usando o método Category.list() na classe Category.

Depois, compararemos essas categorias com as que você deseja destacar. Elas estarão localizadas no array definedFeaturedCategories definido no código abaixo. As que você permitir serão passadas para o componente, que será enviado a um template para renderização.

<script type="text/discourse-plugin" version="0.8">
  const Category = require("discourse/models/category").default;
  // usaremos o modelo Category para recuperar as categorias do site

  api.registerConnectorClass('above-main-container', 'featured-categories', {
    // above-main-container é a saída do plugin,
    // featured-topics é o nome do seu componente personalizado

    setupComponent(args, component) {

      api.onPageChange((url, title) => {
        console.log(url,title)
        if ((url === "/") || (url === "/latest") ) {
        // ao mudar de página, verifica se a URL corresponde
        // se sua página inicial não for /latest, altere isso para /categories
        
          $('html').addClass('custom-featured-categories');
          // adiciona uma classe à tag HTML para facilitar o direcionamento via CSS

          let definedFeaturedCategories = ["uncategorized","blog","two"]
          // array de categorias que você deseja destacar
          // certifique-se de colocar os títulos das categorias em minúsculas

          let featuredCategories = [];

          categories = Category.list();

          for (let cat of categories) {
            if (definedFeaturedCategories.includes(cat.name.toLowerCase())) {
              // empurra apenas as categorias que você deseja destacar para o array a ser renderizado
              featuredCategories.push(cat)
            }
          }

          component.set('featuredCategories', featuredCategories)

        } else {

        // Se a página não corresponder às URLs acima, faça o seguinte:
          $('html').removeClass('custom-featured-categories');
          // Remove nossa classe personalizada
          component.set('categories',[])
          // define as categorias como um array vazio para desativar a renderização
        }
      });
    }
  });
</script>

Esta próxima seção injeta o template para o componente criado acima na saída do plugin above-main-container. Ela chamará o categories-wrapper personalizado criado na terceira etapa e definirá categories como featuredCategories criado acima.

<script type="text/x-handlebars" data-template-name="/connectors/above-main-container/featured-categories">
      <div class="custom-featured-categories-wrapper">
        {{categories-wrapper categories=featuredCategories}}
          <!-- use o template categories-wrapper criado abaixo -->
          <!-- defina categories como featuredCategories criado no script acima -->
      </div>
</script>

A terceira seção cria o template Handlebars personalizado categories-wrapper para renderizar as categorias destacadas. Ele foi adaptado diretamente do template categories-only.hbs do Discourse usado na página de categorias do Discourse.

<script type="text/x-handlebars" data-template-name="components/categories-wrapper">
  <!-- Isso cria um template de componente chamado 'categories wrapper' -->
  <!-- Todo este código de template foi adaptado do template da própria página de categorias do Discourse
   https://github.com/discourse/discourse/blob/acd1693dac1bff6ff50250d942134bc48a27ff14/app/assets/javascripts/discourse/templates/components/categories-only.hbs -->

  <div class="top-categories-wrapper">
    {{#each categories as |c|}}
        <div class="top-category-column-one">
          {{category-title-link category=c}}
          {{#if c.description}}
            <div class="category-description">
              {{dir-span c.description}}
            </div>
          {{/if}}
          {{#if c.isGrandParent}}
            <table class="category-list subcategories-with-subcategories">
              <tbody>
                {{#each c.subcategories as |subcategory|}}
                  <tr
                    data-category-id={{subcategory.id}}
                    data-notification-level={{subcategory.notificationLevelString
                    }}
                    class="{{if
                        subcategory.description_excerpt
                        "has-description"
                        "no-description"
                      }}
  
                      {{if subcategory.uploaded_logo.url "has-logo" "no-logo"}}"
                  >
                    <td
                      class="category"
                      style={{border-color subcategory.color}}
                    >
                      {{category-title-link tagName="h4" category=subcategory}}
                      {{#if subcategory.description_excerpt}}
                        <div
                          class="category-description subcategory-description"
                        >
                          {{{dir-span subcategory.description_excerpt}}}
                        </div>
                      {{/if}}
                      {{#if subcategory.subcategories}}
                        <div class="subcategories">
                          {{#each subcategory.subcategories as |subsubcategory|
                          }}
                            {{#unless subsubcategory.isMuted}}
                              <span class="subcategory">
                                {{category-title-before category=subsubcategory
                                }}
                                {{category-link subsubcategory hideParent="true"
                                }}
                              </span>
                            {{/unless}}
                          {{/each}}
                        </div>
                      {{else if subcategory.description_excerpt}}
                        <div
                          class="category-description subcategory-description"
                        >
                          {{{dir-span subcategory.description_excerpt}}}
                        </div>
                      {{/if}}
                    </td>
                  </tr>
                {{/each}}
              </tbody>
            </table>
          {{else if c.subcategories}}
            <div class="subcategories">
              {{#each c.subcategories as |subcategory|}}
                {{#unless subcategory.isMuted}}
                  <span class="subcategory">
                    {{category-title-before category=subcategory}}
                    {{category-link subcategory hideParent="true"}}
                    {{category-unread category=subcategory}}
                  </span>
                {{/unless}}
              {{/each}}
            </div>
          {{/if}}
        </div>
        <div class="top-category-column-two">
          <span class="topics-header">
            Tópicos
          </span>
          <span class="topics-count">
            {{c.topic_count}}
          </span>
          {{category-unread category=c tagName="div" class="unread-new"}}
        </div>
    {{/each}}
  </div>
</script>

Isso deve ajudá-lo a começar a fazer o que você solicitou em sua OP.

Para estilizar a cor de cada caixa de categoria de acordo com suas cores personalizadas definidas, na terceira seção, você pode codificar estilos fixos usando # + c.color para acessar o código de cor da categoria.

Além disso, a estilização pode ser feita no arquivo common.scss.

Uau! Obrigado por essa resposta detalhada e extremamente útil, @jordan.vidrine! Vou tentar e te aviso como me saí :slight_smile:

Isso funcionou muito bem, @jordan.vidrine:

A única coisa estranha é que os tópicos só carregam após acessar /categories; caso contrário, parece que não há tópicos algum:

Tem alguma ideia do que está acontecendo aí?

Hmm. Desculpe, não tenho certeza. Não consigo reproduzir esse problema.