Un énième message d’un utilisateur de SPIP et concepteur de squelette ne comprenait pas pourquoi sa boucle documents ne retournait rien.
En fait il s’attendait à ce que la boucle retourne la liste des documents qui ont un mot clé donné (les mots clés taguent des documents donc). C’est une compréhension fort logique, vu que c’est ce que fait la boucle :
Les tables de liaisons
Mais ce n’est pourtant pas ce qui se passe avec la boucle documents. La différence est simple, il existe une table SQL « spip_documents_liens » qui sert de pivot (on parle souvent de table de liaison) où est stockée donc l’information disant tel document est lié à ceci, cela, c’est à dire à des objets éditoriaux (articles, rubriques, mots, tout ce que l’on veut).
Il existe la même table « spip_mots_liens » qui sert de pivot pour indiquer que tel mot est attaché à tel objet éditorial, lorsqu’on tague des articles, des documents d’un mot clé.
Mais il n’existe pas de table « spip_articles_liens ».
Cas non ambigus
Lorsqu’on écrit dans une boucle ARTICLES
le critère {id_mot}
, SPIP recherche comment il peut faire pour honorer la demande. Il cherche donc si la table SQL spip_articles
possède un champ « id_mot » (ce qui n’est pas le cas), et du coup tente de trouver une construction de liaison entre tables SQL (on parle de jointure) qui permet d’obtenir ce id_mot qui est demandé. SPIP remarque que spip_mots_liens
possède un champ « id_mot » et va donc demander une jointure avec cette table.
Il pourrait aussi rechercher une table ayant le couple de champs « objet » et « id_objet » et faire une jointure dessus en indiquant, du coup, que objet=mot
et id_objet=l'identifiant
.
Pour aller plus loin, disons simplement que s’il y a plusieurs possibilités de jointure pour obtenir id_mot
, SPIP choisira la jointure la plus courte, c’est à dire qui nécessite d’interroger le moins de tables SQL possibles.
Cas ambigus
Indiquer un critère {id_mot}
sur une boucle DOCUMENTS
est plus ambigu. Effectivement, SPIP peut choisir de prendre le mot soit sur la liaison spip_documents_liens
, soit sur la liaison spip_mots_liens
. Les deux étant corrects, mais ils n’ont pas la même signification.
Il faut donc savoir que dans ce cas, SPIP choisit de préférence une liaison avec la même table que celle de la boucle, c’est à dire que comme nous sommes dans une boucle DOCUMENTS
, SPIP choisira de préférence la liaison avec spip_documents_liens
.
Alors, pourquoi y a t’il deux tables de liaisons possibles avec les documents ou avec les mots ? et à quoi servent-elles ? qu’est-ce qui les différencient ?
Des mots sur des documents, des documents sur des mots
Pour expliquer ce qui se passe :
- Les documents en SPIP 3 peuvent être sur n’importe quel objet (y compris les mots) (des mots peuvent avoir des documents attachés)
- Les mots en SPIP 3 peuvent être mis sur n’importe quel objet (y compris les documents) (des documents peuvent être tagués par dés mots)
On voit bien ici que c’est délicat pour SPIP de comprendre ce que signifie (DOCUMENTS){id_mot}
: est-ce qu’on veut ?
- les documents d’un mot clé ?
- les documents tagués d’un mot clé ?
Il faut donc faire un peu d’analyse de fonctionnement de SPIP pour comprendre ce qui va se passer :
- Lorsqu’on lie un document à un objet, la liaison est stockée dans la table
spip_documents_liens
- Lorsqu’on lie un mot à un objet, la liaison est stockée dans la table
spip_mots_liens
Ce que SPIP va décider lorsqu’il y a ambiguïté, c’est à dire comme ici (DOCUMENTS){id_mot}
alors qu’il existe les 2 tables spip_documents_liens
et spip_mots_liens
, c’est qu’il va préférer interpréter cela comme une liaison sur la table de lien de la boucle en cours, c’est à dire sur spip_documents_liens
, ce qui signifie donc que ça va retourner « les documents attachés à un mot clé »
Pour lever les ambiguïtés, on peut indiquer, donc, la relation du lien de plusieurs manières, lorsqu’on veut l’autre relation :
- Soit en l’indiquant comme table :
(DOCUMENTS mots_liens){id_mot}
- Soit en l’indiquant dans le critère
(DOCUMENTS){mots_liens.id_mot}
Il faut noter que mettre simplement (DOCUMENTS){mots.id_mot}
n’est pas suffisant pour lever l’ambiguïté.
D’autres exemples :
Liaison spip_documents_liens
(Les documents attachés à un mot)
Liaison spip_mots_liens
(Les documents tagués d’un mot)
Attraper les documents tagués avec un mot clé appartenant à un certain groupe :