Créer une bannière d'accueil pour les « Catégories en vedette »

J’aimerais créer une section bannière située sous l’en-tête de la page d’accueil, mettant en vedette des boîtes de catégories stylisées. Par exemple :

Je comprends que je puisse utiliser le point de sortie « below-site-header » et suivre les instructions de Comment ajouter du contenu personnalisé qui n’apparaît que sur votre page d’accueil pour afficher mon code HTML.

Idéalement, j’aimerais disposer d’un champ de type énuméré dans les paramètres personnalisés pour sélectionner les catégories mises en avant ici. Est-il possible d’avoir un champ de paramètre personnalisé permettant de rechercher des catégories ?

Je souhaiterais également pouvoir ajouter une image d’arrière-plan personnalisée pour ces cartes, en plus de l’image d’arrière-plan de la catégorie. Est-il possible d’ajouter un autre champ de type « upload de fichier » dans l’onglet Images de la fenêtre modale des paramètres de la catégorie ? Par exemple :

Dans l’ensemble, cela semble-t-il réalisable, et y a-t-il des pièges ou des astuces auxquels je devrais être attentif ?

Envisagez d’utiliser le plugin TLP pour commencer. Il existe déjà une fonctionnalité d’images en vedette qui pointe vers les sujets. Vous pourriez être en mesure de réutiliser une partie du code.

Pourrait-il utiliser cela ?

Étant donné que les catégories sont moins dynamiques, une approche plus statique pourrait avoir du sens :+1:

Je suppose que vous devez décider si vous voulez que cela soit piloté par les données ou non.

Idéalement, je souhaiterais que cela ressemble à une version sophistiquée de la « Boîte de catégorie avec sujets », qui intègre également le logo de la catégorie et l’image d’arrière-plan, ainsi que les derniers sujets de cette catégorie.

Cependant, si cela n’est pas simple à mettre en œuvre en utilisant les mécanismes standard d’extension du thème ou du plugin, cela pourrait ne pas en valoir la peine. Dans ce cas, je procéderai soit de manière statique, soit j’utiliserai la disposition des boîtes de catégorie sur la page d’accueil et les styliserai selon les besoins.

Je pense que deux tests clés sont :

  1. Existe-t-il une méthode standard pour exposer un élément de configuration « Sélectionner une catégorie » ?
  2. Existe-t-il une méthode standard pour ajouter des champs de métadonnées à la fenêtre modale des paramètres de catégorie ?

Sinon, si je peux simplement utiliser les identifiants de catégorie dans la configuration tout en étant capable de récupérer les données de manière programmatique, cela devrait probablement convenir.

En revanche, si l’accès aux données de catégorie de cette manière n’est pas vraiment réalisable, j’utiliserai l’une des autres approches.

Vous pouvez faire n’importe quoi dans un plugin (bien qu’il soit évidemment préférable d’adopter des stratégies qui minimisent le risque que votre plugin cesse de fonctionner après une mise à jour du noyau). Esquissez vos idées, copiez à partir de plugins existants et du noyau de Discourse, puis commencez par une version simple et itérez.

J’ai examiné cet ancien post de Kris et je l’ai directement adapté pour que vous puissiez l’utiliser comme base. Une grande partie de ce qui est abordé ici a été exposée par lui dans son sujet original.
https://meta.discourse.org/t/how-to-add-a-featured-topic-list-to-your-discourse-homepage/132949

Tout le code sera ajouté à la section <head> (head_tag.html) de votre thème.

Cette première section vérifiera si la page sur laquelle vous vous trouvez est la « page d’accueil ».

Nous récupérerons ensuite les catégories du site en utilisant la méthode Category.list() sur la classe Category.

Nous comparerons ensuite ces catégories à celles que vous souhaitez mettre en avant. Elles se trouveront dans le tableau definedFeaturedCategories défini dans le code ci-dessous. Celles que vous autorisez seront définies pour le composant afin d’être transmises à un modèle pour le rendu.

<script type="text/discourse-plugin" version="0.8">
  const Category = require("discourse/models/category").default;
  // nous utiliserons le modèle Category pour récupérer les catégories du site

  api.registerConnectorClass('above-main-container', 'featured-categories', {
    // above-main-container est la sortie du plugin,
    // featured-topics est le nom de votre composant personnalisé

    setupComponent(args, component) {

      api.onPageChange((url, title) => {
        console.log(url,title)
        if ((url === "/") || (url === "/latest") ) {
        // lors du changement de page, vérifier si l'URL correspond
        // si votre page d'accueil n'est pas /latest, modifiez ceci en /categories
        
          $('html').addClass('custom-featured-categories');
          // ajouter une classe à la balise HTML pour un ciblage CSS facile

          let definedFeaturedCategories = ["uncategorized","blog","two"]
          // tableau des catégories que vous souhaitez mettre en avant
          // assurez-vous de mettre les titres des catégories en minuscules

          let featuredCategories = [];

          categories = Category.list();

          for (let cat of categories) {
            if (definedFeaturedCategories.includes(cat.name.toLowerCase())) {
              // ne pousse dans le tableau à rendre que les catégories que vous souhaitez mettre en avant
              featuredCategories.push(cat)
            }
          }

          component.set('featuredCategories', featuredCategories)

        } else {

        // Si la page ne correspond pas aux URLs ci-dessus, faites ceci :
          $('html').removeClass('custom-featured-categories');
          // Supprimer notre classe personnalisée
          component.set('categories',[])
          // définir les catégories sur un tableau vide pour désactiver le rendu
        }
      });
    }
  });
</script>

Cette prochaine section injecte le modèle pour le composant créé ci-dessus dans la sortie du plugin above-main-container. Il appellera le categories-wrapper personnalisé créé à la troisième étape et définira categories comme étant featuredCategories créé ci-dessus.

<script type="text/x-handlebars" data-template-name="/connectors/above-main-container/featured-categories">
      <div class="custom-featured-categories-wrapper">
        {{categories-wrapper categories=featuredCategories}}
          <!-- utiliser le modèle categories-wrapper créé ci-dessous -->
          <!-- définir categories comme étant featuredCategories créé dans le script ci-dessus -->
      </div>
</script>

La troisième section crée le modèle Handlebars personnalisé categories-wrapper pour rendre les catégories mises en avant. Il est directement adapté du modèle categories-only.hbs de Discourse utilisé sur la page des catégories de Discourse.

<script type="text/x-handlebars" data-template-name="components/categories-wrapper">
  <!-- Cela crée un modèle de composant appelé 'categories wrapper' -->
  <!-- Tout ce code de modèle a été adapté du modèle de la page des catégories de Discourse lui-même
   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">
            Sujets
          </span>
          <span class="topics-count">
            {{c.topic_count}}
          </span>
          {{category-unread category=c tagName="div" class="unread-new"}}
        </div>
    {{/each}}
  </div>
</script>

Cela devrait vous aider à commencer à faire ce que vous avez demandé dans votre OP.

Pour styliser la couleur de chaque boîte de catégorie selon ses couleurs définies personnalisées, dans la troisième section, vous pouvez coder en dur les styles en utilisant # + c.color pour accéder au code couleur des catégories.

Autrement, le stylage peut être effectué dans le fichier common.scss.

Wouah ! Merci pour cette réponse détaillée et extrêmement utile, @jordan.vidrine ! Je vais essayer et te dire comment ça se passe :slight_smile:

Cela a très bien fonctionné, @jordan.vidrine :

La seule chose étrange, c’est que les sujets ne se chargent qu’après avoir visité /categories ; sinon, on dirait qu’il n’y a aucun sujet :

Une idée de ce qui se passe ?

Hmm. Désolé, je ne suis pas sûr. Je n’arrive pas à reproduire ce problème.