Creare un banner homepage "Categorie in evidenza"

Vorrei creare una sezione banner posizionata sotto l’intestazione nella homepage, che mostri alcune caselle di categoria stilizzate. Ad esempio:

So che posso utilizzare l’outlet “below-site-header” e le istruzioni di Come aggiungere contenuto personalizzato che appare solo nella homepage per generare il mio markup.

Idealmente, vorrei avere un campo enum nelle impostazioni personalizzate per selezionare quali categorie sono in evidenza qui. È possibile avere un campo di impostazione personalizzato che consenta di cercare le categorie?

Vorrei anche poter impostare un’immagine di sfondo personalizzata per queste card, oltre all’immagine di sfondo della categoria. È possibile aggiungere un altro campo di caricamento file nella scheda Immagini della finestra di dialogo delle impostazioni della categoria? Ad esempio:

In generale, sembra tutto questo fattibile? Ci sono eventuali insidie o trucchi di cui dovrei essere a conoscenza?

Valuta di utilizzare il plugin TLP come punto di partenza. Esiste già una funzionalità per le immagini in evidenza che punta ai topic. Potresti essere in grado di riutilizzare parte del codice.

Potrebbe usare questo?

Dato che le categorie sono meno dinamiche, un approccio più statico potrebbe avere senso :+1:

Immagino tu debba decidere se vuoi che sia basato sui dati o meno.

Idealmente, vorrei che fosse una versione raffinata della ‘Casella Categoria con Argomenti’ che includa anche il logo della categoria e l’immagine di sfondo, insieme agli ultimi argomenti presenti in quella categoria.

Tuttavia, se ciò non è semplice da realizzare utilizzando i meccanismi standard di estensione del tema o del plugin, potrebbe non valere la pena dello sforzo. In tal caso, opterò per una soluzione statica oppure utilizzerò il layout delle caselle categoria nella homepage, stilizzandole come necessario.

Penso che due test chiave siano:

  1. Esiste un modo standard per esporre un elemento di configurazione ‘Seleziona Categoria’?
  2. Esiste un modo standard per aggiungere campi metadati alla finestra di dialogo delle impostazioni della categoria?

In alternativa, se posso semplicemente utilizzare gli ID delle categorie nella configurazione e comunque essere in grado di recuperare i dati programmaticamente, sarebbe probabilmente accettabile.

Se, invece, non fosse realmente fattibile accedere ai dati della categoria in quel modo, allora utilizzerò uno degli altri approcci.

Puoi fare qualsiasi cosa desideri in un plugin (anche se è ovviamente meglio adottare strategie che riducano al minimo il rischio che il tuo plugin si rompa dopo un aggiornamento del core). Schizza le tue idee, copia da plugin esistenti e dal core di Discourse, quindi inizia con una versione semplice e iterativa.

Ho esaminato questo precedente post di Kris e l’ho direttamente adattato a qualcosa che potresti utilizzare come base. Gran parte di ciò che viene trattato qui è stato esposto da lui nel suo argomento originale.
https://meta.discourse.org/t/how-to-add-a-featured-topic-list-to-your-discourse-homepage/132949

Tutto il codice verrà aggiunto alla sezione </head> (head_tag.html) del tuo tema.

Questa prima sezione verificherà se la pagina in cui ti trovi è la “home page”.

Successivamente, otterremo le categorie del sito utilizzando il metodo Category.list() sulla classe Category.

Confronteremo quindi queste con le categorie che desideri in evidenza. Queste saranno posizionate nell’array definedFeaturedCategories definito nel codice sottostante. Quelle che consenti verranno impostate sul componente da passare a un template per il rendering.

<script type="text/discourse-plugin" version="0.8">
  const Category = require("discourse/models/category").default;
  // useremo il modello Category per recuperare le categorie del sito

  api.registerConnectorClass('above-main-container', 'featured-categories', {
    // above-main-container è l'uscita del plugin,
    // featured-topics è il nome del tuo componente personalizzato

    setupComponent(args, component) {

      api.onPageChange((url, title) => {
        console.log(url,title)
        if ((url === "/") || (url === "/latest") ) {
        // al cambio di pagina, controlla se l'URL corrisponde
        // se la tua home page non è /latest, modifica questo in /categories
        
          $('html').addClass('custom-featured-categories');
          // aggiungi una classe al tag HTML per un facile targeting CSS

          let definedFeaturedCategories = ["uncategorized","blog","two"]
          // array delle categorie che desideri in evidenza
          // assicurati di inserire i titoli delle categorie in minuscolo

          let featuredCategories = [];

          categories = Category.list();

          for (let cat of categories) {
            if (definedFeaturedCategories.includes(cat.name.toLowerCase())) {
              // inserisce nell'array solo le categorie che desideri in evidenza per il rendering
              featuredCategories.push(cat)
            }
          }

          component.set('featuredCategories', featuredCategories)

        } else {

        // Se la pagina non corrisponde agli URL sopra, fai questo:
          $('html').removeClass('custom-featured-categories');
          // Rimuovi la nostra classe personalizzata
          component.set('categories',[])
          // imposta le categorie su un array vuoto per disabilitare il rendering
        }
      });
    }
  });
</script>

Questa prossima sezione inietta il template per il componente creato sopra nell’uscita del plugin above-main-container. Chiamerà il categories-wrapper personalizzato creato nel terzo passaggio e definirà categories come featuredCategories creato sopra.

<script type="text/x-handlebars" data-template-name="/connectors/above-main-container/featured-categories">
      <div class="custom-featured-categories-wrapper">
        {{categories-wrapper categories=featuredCategories}}
          <!-- usa il template categories-wrapper creato sotto -->
          <!-- definisci categories come featuredCategories creato nello script sopra -->
      </div>
</script>

La terza sezione crea il template handlebars personalizzato categories-wrapper per il rendering delle categorie in evidenza. È direttamente adattato dal template categories-only.hbs di Discourse utilizzato nella pagina delle categorie di Discourse.

<script type="text/x-handlebars" data-template-name="components/categories-wrapper">
  <!-- Questo crea un template chiamato 'categories wrapper' -->
  <!-- Tutto questo codice del template è stato adattato dal template della pagina delle categorie di 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">
            Argomenti
          </span>
          <span class="topics-count">
            {{c.topic_count}}
          </span>
          {{category-unread category=c tagName="div" class="unread-new"}}
        </div>
    {{/each}}
  </div>
</script>

Questo dovrebbe aiutarti a iniziare a fare ciò che hai richiesto nel tuo OP.

Per lo stile del colore di ogni riquadro della categoria in base ai suoi colori personalizzati definiti, nella terza sezione, puoi codificare a mano gli stili utilizzando # + c.color per accedere al codice colore delle categorie.

A parte questo, lo stile può essere effettuato nel file common.scss.

Wow! Grazie per questa risposta dettagliata e estremamente utile, @jordan.vidrine! Proverò e ti farò sapere come va :slight_smile:

Ha funzionato benissimo, @jordan.vidrine:

L’unica cosa strana è che i topic vengono caricati solo dopo aver visitato /categories, altrimenti sembra che non ci siano affatto topic:

Hai idea di cosa possa succedere?

Hmm. Mi dispiace, non ne sono sicuro. Non riesco a riprodurre quel problema.