Taxonomies et relations

Classer des posts par termes, les relier entre eux, les imbriquer et fixer leur ordre manuellement.

Trois mécanismes relient un post à un autre contenu : les taxonomies le classent par termes, les relations le lient à des posts d'un autre type, la hiérarchie l'imbrique sous un post du même type. Les trois se déclarent comme des champs, et sont stockés hors des données JSON.

Taxonomies

Une taxonomie est un ensemble de termes qui classent les posts d'un type. Le module n'impose ni catégories ni étiquettes : un type peut en déclarer autant qu'il veut, avec les noms qu'il veut.

LRVO_MODULE_POSTS_TYPE_BLOGUE=title:title|slug:slug|categories:taxonomy:Catégories:multi|tags:taxonomy:Tags:multi

Chaque champ taxonomy crée une taxonomie dont la clé est le nom du champ. Le mode single restreint la sélection à un terme, multi en autorise plusieurs et reste le comportement par défaut.

Portée des termes

Les termes sont scopés par le couple (type de post, taxonomie). La taxonomie categories du type blogue et la taxonomie categories du type cve sont donc deux ensembles distincts, sans terme commun.

Un terme porte un titre, une description facultative et un drapeau is_active. Il n'a pas de slug : les taxonomies servent au classement dans l'admin et au filtrage par identifiant dans l'API, pas au routage. Le module ne rend aucune page d'archive par terme.

Aucune contrainte d'unicité n'est posée sur le titre. Deux termes homonymes dans la même taxonomie sont possibles.

Administration

Chaque taxonomie obtient son propre item dans la section d'admin du type, sous le libellé donné à la déclaration et avec l'icône Layers01Icon. La liste des termes affiche pour chacun le nombre de posts qui l'utilisent. Voir Administration.

Un terme utilisé par au moins un post ne peut pas être supprimé. La suppression échoue avec Cannot delete term used by N post(s). Le désactiver via is_active le retire des sélecteurs et de la route publique tout en conservant les classements existants.

Filtrer par terme

Les routes de liste, d'admin comme publiques, acceptent un paramètre par taxonomie :

GET /lrvo/api/posts/blogue?taxonomy_categories=3&taxonomy_tags=7

Le suffixe est validé contre les taxonomies déclarées du type, et la valeur doit être un identifiant numérique de terme. Plusieurs filtres se cumulent en et logique : un post doit porter tous les termes demandés pour ressortir.

Relations

Un champ relation lie un post à des posts d'un autre type.

LRVO_MODULE_POSTS_TYPE_PROJET=title:title|slug:slug|equipe:relation:membre

Le troisième segment est la clé du type cible. Il est ramené en minuscules, comme les clés de type.

Dans l'éditeur, le champ ouvre un sélecteur qui interroge la route de recherche du type cible. En base, chaque lien est une ligne portant sa position, ce qui rend l'ordre de sélection significatif et conservé.

À la lecture, le champ est remplacé par un tableau de posts cibles complets, données comprises. Ce n'est donc pas une simple liste d'identifiants.

Les relations sont unidirectionnelles. Déclarer equipe:relation:membre sur projet ne fait pas apparaître de champ inverse sur membre. Pour naviguer dans l'autre sens, déclarer un second champ sur le type cible.

Supprimer un post cible supprime les lignes de relation qui le pointent, par cascade. Le post source reste en place, avec un lien de moins.

Hiérarchie

Un champ parent permet à un post d'en avoir un autre du même type pour parent.

LRVO_MODULE_POSTS_TYPE_EXPERTISE=title:title|slug:slug|parent:parent:Parent:sidebar

Le type cible est implicite : toujours celui du champ. Aucun segment de cible n'est à donner, le segment optionnel sert de libellé.

Effet sur les URL

Sans champ parent, un post est servi à /<type>/<slug>, et le résolveur public refuse toute URL plus profonde.

Avec un champ parent, l'URL publique devient la chaîne complète des slugs : /<type>/<slug du parent>/<slug de l'enfant>. Le module la reconstruit depuis la racine, et vérifie que chaque maillon de la chaîne est public. Un parent privé rend donc tous ses descendants inaccessibles, même publiés.

Un post enfant n'est jamais servi à son URL plate. /expertise/enfant renvoie une page introuvable si enfant a un parent.

Garde-fous

L'affectation d'un parent est refusée dans trois cas :

  • le post se désignerait lui-même ;
  • le parent visé n'existe pas, ou appartient à un autre type de post ;
  • le parent visé descend du post, ce qui créerait un cycle.

La vérification remonte la chaîne d'ascendants complète, pas seulement le parent direct.

Supprimer un parent ne supprime pas ses enfants : leur parent_id est remis à vide et ils remontent à la racine du type. Leurs URL publiques changent en conséquence.

Fil d'Ariane

La chaîne d'ascendants est calculée une fois par rendu et passée au template sous la propriété breadcrumb, de la racine jusqu'au post courant inclus. Voir Templates.

Ordre manuel

LRVO_MODULE_POSTS_TYPE_EXPERTISE_ORDERABLE=true

Le drapeau ajoute une poignée de glisser-déposer dans la liste d'admin et bascule le tri par défaut, en admin comme sur l'API publique, sur la colonne d'ordre.

L'ordre est scopé par fratrie, c'est-à-dire par couple (type de post, parent). Réordonner les enfants d'un parent ne touche pas aux autres branches. Un nouveau post prend la position suivante dans sa fratrie, et déplacer un post sous un autre parent lui réattribue une position dans sa nouvelle fratrie.

La route de réordonnancement refuse un lot qui contiendrait un identifiant hors de la fratrie visée, plutôt que de réécrire silencieusement des positions dans un autre groupe.

Pour lire cet ordre depuis un consommateur :

GET /lrvo/api/posts/expertise?sortBy=order&sortOrder=ASC

Sans sortBy, la route applique déjà ce tri quand le type est réordonnable.

Notes

  • Les taxonomies et les relations n'existent en base que si au moins un type les déclare. Après avoir ajouté le premier champ de ce genre, relancer npx lrvo-db init. Voir Modèle de données.
  • Une taxonomie retirée de la déclaration d'un type cesse d'apparaître dans l'admin, mais ses termes et ses classements restent en base.
  • La recherche textuelle des routes de liste ne porte que sur le champ de titre. Ni les termes de taxonomie, ni les données des autres champs ne sont interrogés.

Sur cette page