Creando un banner de página de inicio de "Categorías destacadas"

Me gustaría crear una sección de banner que se sitúe debajo del encabezado en la página de inicio y que destaque algunas cajas de categorías con un estilo más llamativo. Por ejemplo:

Entiendo que puedo utilizar el outlet “below-site-header” y las instrucciones de Cómo agregar contenido personalizado que solo aparezca en tu página de inicio para mostrar mi marcado.

Idealmente, me gustaría tener un campo de tipo enum en la configuración personalizada para seleccionar qué categorías se destacan aquí. ¿Es posible tener un campo de configuración personalizado que permita buscar categorías?

También me gustaría tener una imagen de fondo personalizada para estas tarjetas, además de la imagen de fondo de la categoría. ¿Es posible agregar otro campo de entrada de archivo en la pestaña Imágenes del modal de configuración de categorías? Por ejemplo:

En general, ¿esto parece factible y hay alguna trampa o truco potencial del que deba estar al tanto?

Considere usar el plugin TLP como punto de partida. Ya existe una función de Imágenes destacadas que apunta a los temas. Es posible que pueda reutilizar parte del código.

¿Podría usar esto?

Dado que las categorías son menos dinámicas, podría tener más sentido un enfoque más estático :+1:

Supongo que tendrás que decidir si quieres que esté impulsado por datos o no.

Idealmente, me gustaría que fuera una versión más elaborada del ‘Cuadro de categoría con temas’, que también incluya el logotipo de la categoría y la imagen de fondo, junto con los últimos temas de esa categoría.

Sin embargo, si esto no es sencillo de implementar mediante los mecanismos estándar de extensión de temas o plugins, quizás no valga la pena el esfuerzo. En ese caso, lo haré de forma estática o utilizaré el diseño de cuadros de categoría en la página de inicio y los estilizaré según sea necesario.

Considero que hay dos pruebas clave:

  1. ¿Existe una forma estándar de exponer un elemento de configuración ‘Seleccionar categoría’?
  2. ¿Existe una forma estándar de agregar campos de metadatos al modal de configuración de la categoría?

Alternativamente, si puedo simplemente usar los IDs de categoría en la configuración y aún así poder extraer los datos programáticamente, eso probablemente sea suficiente.

No obstante, si no es realmente factible acceder a los datos de la categoría de esa manera, entonces utilizaré uno de los otros enfoques.

Puedes hacer cualquier cosa que quieras en un plugin (aunque, obviamente, lo mejor es emplear estrategias que minimicen el riesgo de que tu plugin deje de funcionar después de una actualización del núcleo). Escribe un esquema de tus ideas, copia de plugins existentes y del núcleo de Discourse, y luego comienza con una versión simple e itera.

He revisado esta publicación anterior de Kris y la he adaptado directamente a algo que podrías utilizar como base. Gran parte de lo que se trata aquí ya fue expuesto por él en su tema original.
https://meta.discourse.org/t/how-to-add-a-featured-topic-list-to-your-discourse-homepage/132949

Todo el código se agregará a la sección <head> (head_tag.html) de tu tema.

Esta primera sección verificará si la página en la que te encuentras es la “página de inicio”.

Luego, obtendremos las categorías del sitio utilizando el método Category.list() en la clase Category.

Después, compararemos esas categorías con las que deseas destacar. Estas se encontrarán en el array definedFeaturedCategories definido en el código a continuación. Las que permitas se establecerán en el componente para ser pasadas a una plantilla para su renderizado.

<script type="text/discourse-plugin" version="0.8">
  const Category = require("discourse/models/category").default;
  // utilizaremos el modelo Category para recuperar las categorías del sitio

  api.registerConnectorClass('above-main-container', 'featured-categories', {
    // above-main-container es la salida del plugin,
    // featured-topics es el nombre de tu componente personalizado

    setupComponent(args, component) {

      api.onPageChange((url, title) => {
        console.log(url,title)
        if ((url === "/") || (url === "/latest") ) {
        // al cambiar de página, verificar si la URL coincide
        // si tu página de inicio no es /latest, cámbialo a /categories
        
          $('html').addClass('custom-featured-categories');
          // agregar una clase a la etiqueta HTML para facilitar el targeting con CSS

          let definedFeaturedCategories = ["uncategorized","blog","two"]
          // array de categorías que deseas destacar
          // asegúrate de poner los títulos de las categorías en minúsculas

          let featuredCategories = [];

          categories = Category.list();

          for (let cat of categories) {
            if (definedFeaturedCategories.includes(cat.name.toLowerCase())) {
              // solo empuja las categorías que deseas destacar al array para ser renderizado
              featuredCategories.push(cat)
            }
          }

          component.set('featuredCategories', featuredCategories)

        } else {

        // Si la página no coincide con las URLs anteriores, haz esto:
          $('html').removeClass('custom-featured-categories');
          // eliminar nuestra clase personalizada
          component.set('categories',[])
          // establecer las categorías en un array vacío para desactivar el renderizado
        }
      });
    }
  });
</script>

Esta siguiente sección inyecta la plantilla para el componente creado anteriormente en la salida del plugin above-main-container. Llamará al categories-wrapper personalizado creado en el tercer paso y definirá categories como featuredCategories creado anteriormente.

<script type="text/x-handlebars" data-template-name="/connectors/above-main-container/featured-categories">
      <div class="custom-featured-categories-wrapper">
        {{categories-wrapper categories=featuredCategories}}
          <!-- usar la plantilla categories-wrapper creada a continuación -->
          <!-- definir categories como featuredCategories creado en el script anterior -->
      </div>
</script>

La tercera sección crea la plantilla Handlebars personalizada categories-wrapper para renderizar las categorías destacadas. Está adaptada directamente de categories-only.hbs de Discourse utilizada en la página de categorías de Discourse.

<script type="text/x-handlebars" data-template-name="components/categories-wrapper">
  <!-- Esto crea una plantilla de componente llamada 'categories wrapper' -->
  <!-- Todo este código de plantilla fue adaptado de la plantilla de la página de categorías de 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.escription}}
            <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">
            Temas
          </span>
          <span class="topics-count">
            {{c.topic_count}}
          </span>
          {{category-unread category=c tagName="div" class="unread-new"}}
        </div>
    {{/each}}
  </div>
</script>

Esto debería ayudarte a comenzar a hacer lo que solicitaste en tu OP.

Para estilizar el color de cada cuadro de categoría según sus colores definidos personalizados, en la tercera sección, puedes codificar estilos manualmente usando # + c.color para acceder al código de color de la categoría.

Aparte de eso, el estilo se puede realizar en el archivo common.scss.

¡Guau! Gracias por esta respuesta tan detallada y extremadamente útil, @jordan.vidrine. ¡Lo probaré y te contaré cómo me va! :slight_smile:

Eso funcionó muy bien, @jordan.vidrine:

Lo único extraño es que los temas solo se cargan después de visitar /categories; de lo contrario, parece que no hay ningún tema en absoluto:

¿Tienes alguna idea de qué está pasando ahí?

Hmm. Lo siento, no estoy seguro. No puedo reproducir ese problema.