Carnet Wiki

MOTS-DOCUMENTS Liens et Jointure

Version 4 — Juin 2012 — 82.240.xx.xx

Inspiré par une contribution de marcimat sur les listes et par http://marcimat.magraine.net/SPIP-3-Documents-Mots

SPIP 3 permet de qualifier des documents avec des motclés, mais il permet également d’attacher des documents à des mots clés. Ces 2 possibilités sont forts pratiques certainement, mais les boucles à réaliser sont donc plus délicates pour retrouver ce qu’on veut sans erreur, en fonction du site.

Un énième message d’un utilisateur de SPIP et concepteur de squelette ne comprenait pas pourquoi sa boucle documents ne retournait rien :

<BOUCLE_doc(DOCUMENTS){id_mot}>...

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

<BOUCLE_art(ARTICLES){id_mot}>...

Voici quelques explications.

Mots sur documents et documents sur mots

-  Les documents en SPIP 3 peuvent être sur n’importe quel objet, y compris les mots, c’est à dire que 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 c’est à dire que des documents peuvent être taggués par dés mots.

Ces liens ne sont pas symétriques : un document peut être qualifié par un motclé, mais cela ne signifie pas que ce motclé bénéficie de ce document !

Tables de liaisons

-  Lorsqu’on lie un document à un objet, autrement dit lorsqu’on attache un document à un objet, la liaison est stockée dans la table spip_documents_liens. Cette table contient la liste de tous les liens sur des documents. On y trouve donc notamment les mots qualifiant des documents.
-  Lorsqu’on lie un mot à un objet, autrement dit lorsqu’on qualifie un objet par ce mot, la liaison est stockée dans la table spip_mots_liens. On y trouve donc notamment les documents attachés à des motclés.

Cas non ambigu : mots sur articles

Lorsqu’on écrit dans une boucle (ARTICLES) le critère {id_mot}, SPIP recherche comment il peut faire pour honorer la demande.

Pour cela :

  1. SPIP cherche si la table SQL spip_articles possède un champ id_mot. Ce n’est pas le cas.
  2. Du coup, SPIP tente de trouver une construction de liaison entre tables SQL (on parle de jointure) qui permet d’obtenir ce id_mot qui est demandé.
  3. SPIP remarque que spip_mots_liens possède un champ « id_mot » et va donc demander une jointure avec cette table.
  4. Si jamais il y avait plusieurs possibilités de jointure pour obtenir id_mot, SPIP choisirait la jointure la plus courte, c’est à dire celle qui nécessite d’interroger le moins de tables SQL possibles.
  5. Et enfin, si il y a encore plusieurs possibilités, SPIP choisit si possible la jointure sur la table principale de la boucle.

C’est cette dernière règle qui intervient dans la situation qui nous intéresse.

Ambiguité syntaxique

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 sont possibles, mais ils n’ont pas la même signification.

-  Que signifie une boucle (DOCUMENTS){id_mot} ?
-  Est-ce que cette boucle doit ramener : 1) les documents du mot clé ? ou bien 2) les documents taggués par le mot clé ?

Comme on a vu, il existe 2 tables spip_documents_liens et spip_mots_liens candidates pour permettre la jointure.

Il faut remarquer que selon ce qu’a fait le webmestre, dans un certain on aura besoin de l’un, dans un autre cas, de l’autre.

Résolution automatique de l’ambiguité par SPIP

Pour faire la jointure lorsqu’il y a ambiguïté comme avec la boucle (DOCUMENTS){id_mot}, SPIP va systématiquement utiliser la table de lien sur la table principale de cette boucle. C’est à dire que, dans cet exemple, c’est spip_documents_liens qui va fournir les résultats.

En conséquence, cette boucle va retourner : « les documents attachés à un mot clé »

Lever explicitement les ambiguïtés

Dans le cas où on veut l’autre possibilité de lien, en passant par la table spip_mots_liens donc, il faut utiliser une syntaxe explicite pour en forcer l’usage :
-  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é.

À tester ou confirmer :

Par clarté, on peut également vouloir expliciter la liaison faite automatiquement par SPIP :
-  Soit en indiquant la table retenue : (DOCUMENTS documents_liens){id_mot}
-  Soit en l’indiquant dans le critère (DOCUMENTS){documents_liens.objet=mot}{id_mot} (DOCUMENTS){documents_liens.objet=mot}{documents_liens.id_mot} —>

Autres exemples

-  Liaison spip_documents_liens
<BOUCLE_1(DOCUMENTS){id_mot}>#ID_DOCUMENT</BOUCLE_1>

-  Liaison spip_mots_liens

<BOUCLE_2(DOCUMENTS mots_liens){id_mot}>#ID_DOCUMENT</BOUCLE_2>
<BOUCLE_3(DOCUMENTS mots_liens){mots.id_mot}>#ID_DOCUMENT</BOUCLE_3>
&lt;BOUCLE_4(DOCUMENTS){mots_liens.id_mot=#ID_MOT} id_objet=#ID_MOT} >#ID_DOCUMENT</BOUCLE_4>