Créer des sous-catégories dans le gadget Libellés

Créer des sous-catégories dans le gadget Libellés

Sur Blogger, les libellés servent à organiser vos articles, mais ils restent plats : aucune hiérarchie n’existe entre eux. Pourtant, il est possible de simuler des catégories et sous-catégories en jouant avec le code XML du gadget Libellés.

Dans ce tutoriel, vous allez découvrir comment construire pas à pas un gadget personnalisé capable d’afficher des sous-catégories, en combinant plusieurs libellés. Ce n’est pas une fonction native, mais une astuce pratique pour les bricoleurs et les développeurs qui aiment pousser Blogger au-delà de ses limites.

Introduction

Blogger ne propose pas de véritable gestion de catégories. Tout repose sur les libellés, qui permettent de regrouper des articles par mot-clé. Mais dès que l’on veut aller plus loin – par exemple organiser des contenus en rubriques et sous-rubriques – on se heurte à une limite : il n’existe aucune relation hiérarchique entre les libellés.

C’est ici qu’intervient ce tutoriel. Nous allons explorer une méthode artisanale pour simuler des sous-catégories dans le gadget Libellés, en utilisant le langage XML de Blogger. L’objectif n’est pas de fournir un gadget clé en main, mais de montrer le principe de construction : découpage en inclusions, gestion des libellés via des collections, et combinaison de filtres pour afficher des sous-listes.

Cette approche s’adresse à celles et ceux qui aiment expérimenter avec leur thème : bricoleurs curieux ou développeurs en herbe. Avec un peu de rigueur et d’imagination, vous pourrez obtenir un rendu similaire à un menu hiérarchique, tout en comprenant mieux comment fonctionne la logique des gadgets Blogger.

Libellé vs Catégorie

Les libellés dans Blogger

Un libellé est un mot-clé que vous attribuez à un article.

  • Vous pouvez en ajouter autant que vous voulez.

  • Un même article peut avoir plusieurs libellés.

  • Blogger génère automatiquement une page de recherche pour chaque libellé, accessible via une URL du type : /search/label/Nom_du_libellé

  • Tous les libellés sont placés au même niveau : il n’existe pas de notion de parent/enfant.

Les catégories dans un CMS classique

Dans des systèmes comme WordPress, les catégories forment une arborescence hiérarchique :

  • Catégorie → Sous-catégorie → Sous-sous-catégorie, etc.

  • Chaque article peut appartenir à une ou plusieurs catégories, mais la relation parent/enfant est définie en base de données.

  • Cela permet de naviguer facilement dans des rubriques structurées.

Pourquoi cette distinction est importante

Sur Blogger, parler de “catégorie” est un abus de langage. En réalité, il s’agit toujours de libellés plats.

La méthode présentée dans ce tutoriel consiste donc à simuler une hiérarchie :

  • Le libellé parent sert de “catégorie principale”,

  • Le libellé enfant sert de “sous-catégorie”,

  • Un article doit contenir les deux libellés pour apparaître dans la sous-catégorie correspondante.

Ce n’est pas une fonctionnalité native, mais une astuce de développement pour donner l’illusion d’un classement hiérarchique.

Principe de fonctionnement

L’idée est simple : un article doit contenir au moins deux libellés – un parent et un enfant – pour apparaître dans une sous-catégorie.

Prenons l’exemple suivant :

  • Catégorie : Mes vidéos

  • Sous-catégorie : Films

Un article intitulé “Mon top 10 cinéma” devra porter deux libellés :

  • Mes vidéos

  • Films

Le gadget pourra alors générer un lien combinant ces deux libellés :

/search/label/Mes%20vidéos+Films

Étapes de la construction

  1. Lister les catégories principales dans un tableau (ex. : Mes vidéos, Mes photos, Mes recettes).

  2. Associer manuellement les sous-catégories à chaque catégorie via un <b:switch>.

  3. Générer les liens en concaténant le libellé parent et le libellé enfant, avec l’encodage + (%2B).

  4. Afficher la liste finale sous forme hiérarchique <ul><li>.

Résultat attendu

Visuellement, vous obtiendrez un gadget Libellés en forme de menu :

├─ Mes vidéos
│  ├─ Films
│  ├─ Séries
│  └─ Clips
├─ Mes photos
│  ├─ Vacances
│  └─ Travail
└─ Mes recettes
   ├─ Chocolat
   └─ Frites

À retenir

  • Il n’y a pas de vraie hiérarchie dans Blogger : tout repose sur la co-présence de libellés.

  • La logique est manuelle et explicite : vous devez définir vous-même les associations dans le code.

  • C’est un bon exercice pour comprendre le fonctionnement des collections et des inclusions XML dans Blogger.

Découpage du gadget

1. La structure de base

On commence par créer un nouveau gadget Label, totalement indépendant de celui fourni par défaut.

Ajoutez ce code dans votre thème, juste après une balise <b:section…> :

<b:widget id='Label301' locked='false' title='Libellés' type='Label'>
  <b:includable id='main'>

  </b:includable>
  <b:includable id='cloud'>

  </b:includable>
  <b:includable id='list'>

  </b:includable>
  <b:includable id='subListSwitch'>

  </b:includable>
  <b:includable id='subList'>

  </b:includable>
</b:widget>

Explications

  • <b:widget> : déclare un nouveau gadget de type Label.

  • id='Label301' : identifiant unique que vous pouvez personnaliser.

  • locked='false' : permet de modifier/supprimer le gadget depuis l’éditeur.

  • title='Libellés' : titre affiché (modifiable dans le XML ou via la mise en page).

  • includable : chaque bloc sera rempli dans les étapes suivantes.

À ce stade, le gadget est “vide” : il ne fait rien encore, mais la structure est prête pour accueillir la logique.

2. L’inclusion "main"

Cette inclusion sert de chef d’orchestre : elle affiche le titre, crée le conteneur visuel et choisit quel rendu appeler (cloud ou list).

<b:includable id='main'>
  <!-- Titre optionnel du gadget -->
  <b:with value='data:title == "" ? data:messages.labels : data:title' var='defaultTitle'>
    <b:include name='widget-title'/>
  </b:with>

  <!-- Normalise le mode d’affichage : 'cloud' ou 'list' (par défaut 'list') -->
  <b:with value='data:display ?: "list"' var='mode'>
    <div>
      <b:class expr:name='"widget-content " + data:mode + "-label-widget-content"'/>
      <!-- Délègue à l’inclusion du même nom : 'cloud' ou 'list' -->
      <b:include expr:name='data:mode'/>
    </div>
  </b:with>
</b:includable>

Ce que fait chaque partie

  • Titre : si un titre a été défini dans l’interface, il est utilisé ; sinon, la valeur par défaut issue de data:messages.labels est appliquée dans l'inclusion widget-title.

  • Mode : la variable mode reçoit la valeur de data:display ou, à défaut, la valeur "list".

  • Classe dynamique : <b:class> s’adapte automatiquement selon le mode choisi.

  • Délégation : l’inclusion appropriée (cloud ou list) est appelée pour afficher le contenu.

3. L'inclusion "cloud"

Cette inclusion reprend le fonctionnement classique du gadget Libellés en mode nuage. Elle affiche l’ensemble des libellés disponibles, chacun étant dimensionné en fonction de sa fréquence d’utilisation. Ce mode reste utile lorsqu’il s’agit d’offrir une vue d’ensemble rapide de tous les libellés d’un blog.

<b:includable id='cloud'>
  <b:loop values='data:labels' var='label'>
    <span>
      <b:class expr:name='"label-size label-size-" + data:label.cssSize'/>
      <b:with value='data:view.url == data:label.url' var='isCurrent'>
        <b:tag expr:name='data:isCurrent ? "span" : "a"'>
          <b:attr cond='not data:isCurrent' name='href' expr:value='data:label.url'/>
          <b:attr name='dir' expr:value='data:blog.languageDirection'/>
          <b:attr cond='data:showFreqNumbers' name='data-number' expr:value='data:label.count'/>
        </b:tag>
      </b:with>
    </span>
  </b:loop>
</b:includable>

Explications

  • Boucle : data:labels fournit la liste des libellés disponibles ; la variable label expose leurs propriétés (name, url, count, cssSize, …).

  • Poids visuel : label-size label-size-{x} s’appuie sur data:label.cssSize pour graduer la taille (logique historique du gadget Libellés).

  • État courant : isCurrent est true lorsque l’URL en cours correspond à celle du libellé.

    • Si true → rendu en <span> (pas de lien cliquable).

    • Si false → rendu en <a href="…">.

  • Direction du texte : l’attribut dir utilise data:blog.languageDirection pour respecter les langues RTL/LTR.

  • Compteur non intrusif : lorsque data:showFreqNumbers est actif, la valeur est exposée via data-number.

    Cela permet d’afficher/masquer ou styliser le compteur uniquement en CSS (ex. pseudo-élément), sans alourdir le balisage.

4. L'inclusion "list"

Cette inclusion affiche le premier niveau de la hiérarchie simulée (les « catégories »). La sélection se fait en filtrant les libellés disponibles à partir d’une liste explicite. Chaque entrée mène vers la page du libellé et délègue ensuite l’affichage des sous-catégories à subListSwitch.

<b:includable id='list'>
  <!-- Définir ici les catégories de 1er niveau -->
  <b:with value='["Mes vidéos","Mes photos","Mes recettes"]' var='mainList'>
    <ul class='label-categories'>
      <!-- On ne garde que les libellés présents dans mainList -->
      <b:loop values='data:labels where (l => l.name in data:mainList)' var='label'>
        <li>
          <!-- État courant pré-calculé -->
          <b:with value='data:view.url == data:label.url' var='isCurrent'>
            <!-- Lien si non courant, <span> si courant -->
            <b:tag expr:name='data:isCurrent ? "span" : "a"'>
              <b:attr cond='not data:isCurrent' name='href' expr:value='data:label.url'/>
              <b:attr name='dir' expr:value='data:blog.languageDirection'/>
              <b:attr cond='data:showFreqNumbers' name='data-number' expr:value='data:label.count'/>
              <data:label.name/>
            </b:tag>
          </b:with>

          <!-- Délégation vers le commutateur de sous-listes -->
          <b:include name='subListSwitch'/>
        </li>
      </b:loop>
    </ul>
  </b:with>
</b:includable>

Explications

  • Liste maître : mainList définit explicitement les « catégories » à afficher. L’ordre du tableau est respecté dans le rendu.

  • Filtrage : where (l => l.name in data:mainList) garantit que seuls les libellés visés sont affichés, même si d’autres existent sur le blog.

  • État courant : isCurrent passe l’élément en <span> (non cliquable) lorsque l’URL de la page correspond à celle du libellé.

  • Compteur non intrusif : data-number est exposé uniquement si l’option de fréquence est active, laissant la décision d’affichage au CSS.

  • Sous-niveaux : subListSwitch sera chargé d’associer, pour chaque catégorie, la liste des sous-catégories.

Points d’attention

  • Sensibilité à la casse : les noms dans mainList doivent correspondre exactement aux libellés des articles.

  • Maintenance : ajouter une nouvelle « catégorie » implique d’ajouter son nom dans mainList et son cas correspondant dans subListSwitch.

5. L'inclusion "subListSwitch"

Cette inclusion associe chaque catégorie de premier niveau à ses sous-catégories. Le mécanisme repose sur une instruction b:switch qui compare le nom du libellé courant (data:label.name) avec les valeurs prévues. À chaque correspondance, un tableau de sous-libellés est défini puis transmis à l’inclusion subList.

<b:includable id='subListSwitch'>
  <b:switch var='data:label.name'>

    <!-- Cas de la catégorie 'Mes vidéos' -->
    <b:case value='Mes vidéos'/>
      <b:with value='["Films","Séries","Clips"]' var='subList'>
        <b:include name='subList'/>
      </b:with>

    <!-- Cas de la catégorie 'Mes photos' -->
    <b:case value='Mes photos'/>
      <b:with value='["Vacances","Travail"]' var='subList'>
        <b:include name='subList'/>
      </b:with>

    <!-- Cas de la catégorie 'Mes recettes' -->
    <b:case value='Mes recettes'/>
      <b:with value='["Chocolat","Frites"]' var='subList'>
        <b:include name='subList'/>
      </b:with>

  </b:switch>
</b:includable>

Explications

  • Commutateur : b:switch teste la valeur du libellé courant.

  • Cas : chaque cas correspond à une catégorie définie dans la liste principale.

  • Sous-liste : une collection explicite des sous-catégories est défini avec b:with.

  • Délégation : l’inclusion subList est appelée pour afficher les liens correspondant aux sous-catégories.

Points d’attention

  • Correspondance stricte : le texte du cas doit correspondre exactement au nom du libellé (majuscule/minuscule incluses).

  • Maintenance : pour ajouter une nouvelle catégorie, il faut définir un nouveau cas et lui associer une collection de sous-catégories.

6. L'inclusion "subList"

Cette inclusion génère la liste des sous-catégories pour une catégorie donnée. Chaque lien combine le libellé parent et le libellé enfant, afin de cibler uniquement les articles qui possèdent les deux libellés.

<b:includable id='subList'>
  <ul class='label-subcategories'>
    <!-- Parcourt uniquement les libellés présents dans subList -->
    <b:loop values='data:labels where (l => l.name in data:subList)' var='sub'>
      <li>
        <!-- Construit l’URL combinant parent + enfant -->
        <b:with value='data:blog.searchUrl + "/label/" + data:label.name.escaped + "%2B" + data:sub.name.escaped' var='targetUrl'>
          <!-- Marque l’état courant si la page actuelle correspond à l’URL combinée -->
          <b:with value='data:view.url == data:targetUrl' var='isCurrent'>
            <!-- Lien si non courant, <span> si courant -->
            <b:tag expr:name='data:isCurrent ? "span" : "a"'>
              <b:attr cond='not data:isCurrent' name='href' expr:value='data:targetUrl'/>
              <b:attr name='dir' expr:value='data:blog.languageDirection'/>
              <data:sub.name/>
            </b:tag>
          </b:with>
        </b:with>
      </li>
    </b:loop>
  </ul>
</b:includable>

Explications

  • Filtrage : la boucle restreint l’affichage aux libellés présents dans data:subList, évitant les valeurs orphelines.

  • Construction de l’URL : data:label.name.escaped + "%2B" + data:sub.name.escaped garantit un encodage correct (le + est encodé en %2B).

  • État courant : lorsqu’un lien mène à la page en cours, le rendu passe en <span> non cliquable ; sinon, un <a href="…"> est généré.

  • Compteurs : aucun compteur n’est affiché au niveau des sous-catégories, car data:sub.count ne reflète pas le compte combiné (parent + enfant).

Points d’attention

  • Les articles doivent contenir les deux libellés (parent + enfant) pour apparaître dans la page combinée.

  • La casse et l’orthographe des noms de libellés doivent être strictement identiques à ceux utilisés dans les articles.

Et après ?

La création de sous-catégories dans le gadget Libellés n’est pas une fonction native de Blogger : il s’agit d’un bricolage assumé, basé sur la combinaison manuelle de libellés et l’écriture d’inclusions XML personnalisées.

Ce développement n’a pas pour but d’offrir un gadget universel, mais de montrer comment structurer et articuler du code :

  • découper un widget en inclusions,

  • manipuler des collections,

  • déléguer le rendu selon un mode (cloud, list),

  • simuler une hiérarchie grâce à des associations explicites.

En d’autres termes, il s’agit d’un terrain d’expérimentation : un bon moyen pour mieux comprendre la logique interne des thèmes Blogger, tester des idées, et aller plus loin que l’usage basique de l’interface.

À chacun ensuite d’adapter, de simplifier ou d’étendre ce principe selon ses besoins et son niveau d’exigence.

Spotlight

Populaires cette semaine

L'opérateur de coalescence (alias Elvis)

Plan de publication : calendrier éditorial mensuel

Structurer le contenu pour la chunk-ability