Intégration de l'API de parenté #71

Merged
cerdic merged 8 commits from issue_3844_bis into master 1 day ago
Owner

Intégration de l’API de parenté dans le core de SPIP. Cette API a été développée et testée en amont dans le plugin Déclarer parent, puis utilisée dans plusieurs plugins. Elle comporte 4 fonctions : 2 pour connaitre les types parent et enfants d’un type donné (que objet), 2 pour connaitre les contenus parent et enfants d’un contenu donné (objet + id_objet). Un filtre est ajouté pour connaitre le parent d’un contenu facilement (cas le plus courant). On déclare le parent pour les articles et les rubriques. Une fois intégré, il faudra ajouter les autres déclarations qui étaient fournies par le plugin pour les plugins-dist : syndic, mots, et forums.

C’est l’occasion d’avoir une nouvelle fonctionnalité attendue depuis longtemps par beaucoup de monde, dès la 3.3. En effet, c’est uniquement du nouveau, ça ne casse donc rien, et l’API a déjà été éprouvée dans plusieurs plugins, comme on le demandait au départ. Une fois dans le noyau, il sera toujours temps ensuite d’améliorer ce qui relève du core et des plugins-dist (hiérarchie, URL, etc), au moins l’API est là déjà dispo.

Note :

  • intègre la gestion des tables de liens en parenté
  • remplace !44
  • n’hésitez pas à compléter pour la doc.
Intégration de l’API de parenté dans le core de SPIP. Cette API a été développée et testée en amont dans le plugin Déclarer parent, puis utilisée dans plusieurs plugins. Elle comporte 4 fonctions : 2 pour connaitre les types parent et enfants d’un type donné (que objet), 2 pour connaitre les contenus parent et enfants d’un contenu donné (objet + id_objet). Un filtre est ajouté pour connaitre le parent d’un contenu facilement (cas le plus courant). On déclare le parent pour les articles et les rubriques. Une fois intégré, il faudra ajouter les autres déclarations qui étaient fournies par le plugin pour les plugins-dist : syndic, mots, et forums. C’est l’occasion d’avoir une nouvelle fonctionnalité attendue depuis longtemps par beaucoup de monde, dès la 3.3. En effet, c’est uniquement du nouveau, ça ne casse donc rien, et l’API a déjà été éprouvée dans plusieurs plugins, comme on le demandait au départ. Une fois dans le noyau, il sera toujours temps ensuite d’améliorer ce qui relève du core et des plugins-dist (hiérarchie, URL, etc), au moins l’API est là déjà dispo. Note : - intègre la gestion des tables de liens en parenté - remplace !44 - n’hésitez pas à compléter pour la doc.

Vraie question parce que ça fait plusieurs fois que je vois ça sur d'autres tickets/PR : on travaille sur un dépôt commun, en ayant les mêmes droits sur toutes les branches, et pareil pour les PR. Du coup quand le contenu du code d'une PR ne convient pas, quel est l'intérêt de fermer une PR et en rouvrir une autre, plutôt que juste changer le code de la branche sur laquelle basée cette PR ?

La PR sera forcément automatiquement à jour avec le nouveau contenu de la branche, y compris si on la supprime et qu'on la refait à zéro. On peut même modifier la PR dans l'interface aussi pour changer de branche si vraiment il faut (bcp plus rare). Là on se retrouve avec plusieurs PR parlant de la même chose, alors qu'il y avait déjà des discussion, un historique, un suivi. Après à suivre c'est galère, m'est-avis, ça complique inutilement.

Vraie question parce que ça fait plusieurs fois que je vois ça sur d'autres tickets/PR : on travaille sur un dépôt commun, en ayant les mêmes droits sur toutes les branches, et pareil pour les PR. Du coup quand le contenu du code d'une PR ne convient pas, quel est l'intérêt de fermer une PR et en rouvrir une autre, plutôt que juste changer le code de la branche sur laquelle basée cette PR ? La PR sera forcément automatiquement à jour avec le nouveau contenu de la branche, y compris si on la supprime et qu'on la refait à zéro. On peut même modifier la PR dans l'interface aussi pour changer de branche si vraiment il faut (bcp plus rare). Là on se retrouve avec plusieurs PR parlant de la même chose, alors qu'il y avait déjà des discussion, un historique, un suivi. Après à suivre c'est galère, m'est-avis, ça complique inutilement.
Poster
Owner

Tu fais bien de poser la question parce que je ne suis pas sûr moi-même.

Cependant je viens de faire quelques tests à côté pour vérifier un peu le comportement lorsqu’une branche diverge par qu’on a forcé sa réécriture avec un git push --force

Et...

Ça se passe plutôt bien en fait.
Le git pull indique "force update" par exemple :

To gitlab.com:magraine/test-renames.git
 + d45538d...4290f0c spip-3.1 -> spip-3.1 (forced update)

Si tu avais en plus utilisé la branche localement, il va te le signaler

test-renames2 git:(master) git co spip-3.1      
Switched to branch 'spip-3.1'
Your branch and 'origin/spip-3.1' have diverged,
and have 1 and 1 different commits each, respectively.
  (use "git pull" to merge the remote branch into yours)

Et le git pull resynchronise un peu tout ça effectivement.

Si enfin tu étais sur la branche elle même, le git pull fait un "(forced update)" directement sur ta branche locale sans même t’embêter (tant que tu as pas de commits à toi je présume)

Ma conclusion est que pour les issues, effectivement on devrait pouvoir réécrire les branches, en plus de commiter des corrections dessus donc.

Cependant il reste les commentaires ajoutées au fil du code dans les PR. Je sais pas ce que ça devient dans ce cas.

Tu fais bien de poser la question parce que je ne suis pas sûr moi-même. Cependant je viens de faire quelques tests à côté pour vérifier un peu le comportement lorsqu’une branche diverge par qu’on a forcé sa réécriture avec un `git push --force` Et... Ça se passe plutôt bien en fait. Le git pull indique "force update" par exemple : ``` To gitlab.com:magraine/test-renames.git + d45538d...4290f0c spip-3.1 -> spip-3.1 (forced update) ``` Si tu avais en plus utilisé la branche localement, il va te le signaler ``` test-renames2 git:(master) git co spip-3.1 Switched to branch 'spip-3.1' Your branch and 'origin/spip-3.1' have diverged, and have 1 and 1 different commits each, respectively. (use "git pull" to merge the remote branch into yours) ``` Et le git pull resynchronise un peu tout ça effectivement. Si enfin tu étais sur la branche elle même, le git pull fait un "(forced update)" directement sur ta branche locale sans même t’embêter (tant que tu as pas de commits à toi je présume) Ma conclusion est que pour les issues, effectivement on devrait pouvoir réécrire les branches, en plus de commiter des corrections dessus donc. Cependant il reste les commentaires ajoutées au fil du code dans les PR. Je sais pas ce que ça devient dans ce cas.
Poster
Owner

J’ai actualisé la branche du coup, pour enlever le souligné de la variable.

J’ai actualisé la branche du coup, pour enlever le souligné de la variable.
cerdic added 4 commits 3 weeks ago
54bb65d758 Fix #3844. Intégration de l'API de parenté dans le core de SPIP.
8c4f00ef5c objet_trouver_parents() passe au pluriel et est agnostique : puisqu'on a potentiellement plusieurs liens de parentés (car plusieurs méthodes de parentés et certaines méthodes pouvant remonter plusieurs liens), la fonction ne choisit pas et retourne l'ensemble des parents symétriquement aux enfants.
Owner

J'ai donc actualisé la PR :

  • Rebase sur la branche master à jour
  • ajout du filtre |objet_trouver_enfants
  • evolution de l'API parent qui passe au pluriel objet_trouver_parents() et retourne tous les parents de façon agnostique puisque on peut déclarer plusieurs méthodes de parentées, que certaines peuvent lier plusieurs parents, et que dans tous les cas il n'y a aucune raison que l'API choisisse un parent plutot qu'un autre.

Avec le code initial, et même avant l'introduction des parentées par table de liens, on pouvait déclarer 2 méthodes via id_parent1 et id_parent2, et la fonction aurait retourné tantôt le premier si pointant sur quelque chose, tantôt le second si le premier est nul. A contrario, la fonction objet_trouver_enfants() aurait fonctionné sur les deux parents, créant de fait une disymétrie entre les 2.

Avec cette évolution objet_trouver_enfants() et objet_trouver_parents() sont symétriques et tous les enfants trouvés par la première permettront de remonter aux parents par la seconde.

Les consommateurs ne doivent donc jamais présumer de l'unicité des parents, même si c'est le cas le plus courant, et les traiter tous.

Le support de compatibilité avec l'API objet_trouver_parent() au singulier pourra être assuré par le plugin puisque lui seul a proposé cette API, en ne retenant que le premier parent ce qui donnera le même résultat que ce qu'il implémente actuellement.

J'ai donc actualisé la PR : - Rebase sur la branche master à jour - ajout du filtre |objet_trouver_enfants - evolution de l'API parent qui passe au pluriel `objet_trouver_parents()` et retourne tous les parents de façon agnostique puisque on peut déclarer plusieurs méthodes de parentées, que certaines peuvent lier plusieurs parents, et que dans tous les cas il n'y a aucune raison que l'API choisisse un parent plutot qu'un autre. Avec le code initial, et même avant l'introduction des parentées par table de liens, on pouvait déclarer 2 méthodes via id_parent1 et id_parent2, et la fonction aurait retourné tantôt le premier si pointant sur quelque chose, tantôt le second si le premier est nul. A contrario, la fonction `objet_trouver_enfants()` aurait fonctionné sur les deux parents, créant de fait une disymétrie entre les 2. Avec cette évolution `objet_trouver_enfants()` et `objet_trouver_parents()` sont symétriques et tous les enfants trouvés par la première permettront de remonter aux parents par la seconde. Les consommateurs ne doivent donc jamais présumer de l'unicité des parents, même si c'est le cas le plus courant, et les traiter tous. Le support de compatibilité avec l'API `objet_trouver_parent()` au singulier pourra être assuré par le plugin puisque lui seul a proposé cette API, en ne retenant que le premier parent ce qui donnera le même résultat que ce qu'il implémente actuellement.

Avec le code initial, et même avant l'introduction des parentées par table de liens, on pouvait déclarer 2 méthodes via id_parent1 et id_parent2, et la fonction aurait retourné tantôt le premier si pointant sur quelque chose, tantôt le second si le premier est nul. A contrario, la fonction objet_trouver_enfants() aurait fonctionné sur les deux parents, créant de fait une disymétrie entre les 2.

Je n'arrive toujours pas trop à comprendre de quoi tu parles avec cette dysymétrie puisque le principe de déclarer plusieurs possibilités de parentés (et non pas du tout plusieurs parents), se faisait toujours avec un paramètre "condition", qui justement permet qu'il n'y ait qu'une seule réponse à chaque fois. Et c'est bien le cas y compris pour la dist : un forum peut soit être enfant d'un objet, soit être enfant d'un autre forum, mais jamais les deux à la fois, il y en a toujours un des deux qui est the parent : et l'API déclarait bien cela avec une condition, et c'est uniquement avec cette condition que c'est prévu d'être utilisé si ya plusieurs possibilités :
https://git.spip.net/spip-contrib-extensions/declarerparent/src/branch/master/declarerparent_pipelines.php#L29

Le support de compatibilité avec l'API objet_trouver_parent() au singulier pourra être assuré par le plugin puisque lui seul a proposé cette API, en ne retenant que le premier parent ce qui donnera le même résultat que ce qu'il implémente actuellement.

Euuuh, on va pas demander à installer un plugin en plus, si c'est intégré dans le core. Le fait d'avoir un parent principal unique étant the cas le plus méga courant (genre… 90% au moins ?), je trouverais parfaitement logique que le core continue de le proposer, afin que les utilisations les plus courantes n'aient justement pas à faire elles-mêmes des tests et des choix.

Quand on code un truc qui utilise la notion de parenté et qu'on sait qu'on a besoin d'un parent principal, ça prend selon les conditions (donc déjà ça élimine) et selon l'ordre de déclaration (le premier trouvé est le plus important). Et on ne devrait pas avoir à faire des tests en plus soi-même.

> Avec le code initial, et même avant l'introduction des parentées par table de liens, on pouvait déclarer 2 méthodes via id_parent1 et id_parent2, et la fonction aurait retourné tantôt le premier si pointant sur quelque chose, tantôt le second si le premier est nul. A contrario, la fonction objet_trouver_enfants() aurait fonctionné sur les deux parents, créant de fait une disymétrie entre les 2. Je n'arrive toujours pas trop à comprendre de quoi tu parles avec cette dysymétrie puisque le principe de déclarer plusieurs **possibilités** de parentés (et non pas du tout *plusieurs parents*), se faisait toujours avec un paramètre "condition", qui justement permet qu'il n'y ait qu'une seule réponse à chaque fois. Et c'est bien le cas y compris pour la dist : un forum peut **soit** être enfant d'un objet, **soit** être enfant d'un autre forum, mais jamais les deux à la fois, il y en a toujours un des deux qui est the parent : et l'API déclarait bien cela avec une condition, et c'est uniquement avec cette condition que c'est prévu d'être utilisé si ya plusieurs *possibilités* : https://git.spip.net/spip-contrib-extensions/declarerparent/src/branch/master/declarerparent_pipelines.php#L29 > Le support de compatibilité avec l'API objet_trouver_parent() au singulier pourra être assuré par le plugin puisque lui seul a proposé cette API, en ne retenant que le premier parent ce qui donnera le même résultat que ce qu'il implémente actuellement. Euuuh, on va pas demander à installer un plugin en plus, si c'est intégré dans le core. Le fait d'avoir un parent principal unique étant the cas le plus méga courant (genre… 90% au moins ?), je trouverais parfaitement logique que le core continue de le proposer, afin que les utilisations les plus courantes n'aient justement pas à faire elles-mêmes des tests et des choix. Quand on code un truc qui utilise la notion de parenté et qu'on sait qu'on a besoin d'un parent principal, ça prend selon les conditions (donc déjà ça élimine) et selon l'ordre de déclaration (le premier trouvé est le plus important). Et on ne devrait pas avoir à faire des tests en plus soi-même.
Owner

Ton exemple est un très bon exemple !

un message de forum a potentiellement 0, 1 ou 2 parents :

  • un article (ou rubrique ou autre objet editorial)
  • un autre message de forum auquel il réponds donc

En quoi et pourquoi l'API parents() en choisirait un ? Pourquoi si le message réponds à un autre message on a plus accès à l'article parent et il faut se fader la remontée des parents jusqu'au début du thread pour retrouver l'article parent via l'API (si on a la chance qu'aucun message du thread n'a été supprimé/perdu, puisque dans ce cas l'API nous laisse en plan).

Tu as fais un choix d'utilisation de l'API en déclarant une condition restrictive exclusive pour que celle-ci ne remonte qu'un seul parent : l'article ou le message auquel on réponds. C'est un choix déjà discutable, mais surtout c'est purement un choix.

L'API en elle même n'offre aucune garantie d'exclusivité/unicité/priorité d'un parent par rapport à un autre : à tout moment un plugin peut venir ajouter une déclaration de parent avant ou après l'existante et transformer la relation.

De ce point de vue, si l'API se contente de renvoyer le premier parent on est pas générique et on va casser très facilement du code.

Alors que si l'API renvoie toujours tous les parents on a un fonctionnement clair (et surtout symétrique avec la fonction enfants() )

Et les fonctions utilisatrices de l'API doivent toujours itérer sur cette liste de parents, quitte à ajouter un filtrage pour se limiter à certains types de parent si leur traitement n'est pertinent que pour certains types de parent.

C'est pour ça que je dis que la fonction au singulier ne doit pas être dans l'API du core, car elle est restrictive et elle pré-suppose une forme de relation. Elle existe du fait du plugin, je comprends qu'elle est utilisée, et c'est pourquoi je dis que le plugin doit assurer la retro-compat tant que nécessaire.

Mais le bon fonctionnement c'est que les utilisations de la fonction parent() au singulier doivent être modifier pour s'appuyer sur la fonction parents() au pluriel.

Typiquement, un code écrit avec la fonction parent() au singulier va casser si j'installe le plugin polyhierarchie parce que tout d'un coup je ne prendrai en compte qu'un seul parent et pas tous les parents (que ce soit pour exposer dans le fil d'arianne, pour invalider lors de la publication, etc.)

Ton exemple est un très bon exemple ! un message de forum a potentiellement 0, 1 ou 2 parents : - un article (ou rubrique ou autre objet editorial) - un autre message de forum auquel il réponds donc En quoi et pourquoi l'API parents() en choisirait un ? Pourquoi si le message réponds à un autre message on a plus accès à l'article parent et il faut se fader la remontée des parents jusqu'au début du thread pour retrouver l'article parent via l'API (si on a la chance qu'aucun message du thread n'a été supprimé/perdu, puisque dans ce cas l'API nous laisse en plan). Tu as fais un choix d'utilisation de l'API en déclarant une condition restrictive exclusive pour que celle-ci ne remonte qu'un seul parent : l'article ou le message auquel on réponds. C'est un choix déjà discutable, mais surtout c'est purement un choix. L'API en elle même n'offre aucune garantie d'exclusivité/unicité/priorité d'un parent par rapport à un autre : à tout moment un plugin peut venir ajouter une déclaration de parent avant ou après l'existante et transformer la relation. De ce point de vue, si l'API se contente de renvoyer le premier parent on est pas générique et on va casser très facilement du code. Alors que si l'API renvoie toujours tous les parents on a un fonctionnement clair (et surtout symétrique avec la fonction enfants() ) Et les fonctions utilisatrices de l'API doivent toujours itérer sur cette liste de parents, quitte à ajouter un filtrage pour se limiter à certains types de parent si leur traitement n'est pertinent que pour certains types de parent. C'est pour ça que je dis que la fonction au singulier ne doit pas être dans l'API du core, car elle est restrictive et elle pré-suppose une forme de relation. Elle existe du fait du plugin, je comprends qu'elle est utilisée, et c'est pourquoi je dis que le plugin doit assurer la retro-compat tant que nécessaire. Mais le bon fonctionnement c'est que les utilisations de la fonction parent() au singulier doivent être modifier pour s'appuyer sur la fonction parents() au pluriel. Typiquement, un code écrit avec la fonction parent() au singulier va casser si j'installe le plugin polyhierarchie parce que tout d'un coup je ne prendrai en compte qu'un seul parent et pas tous les parents (que ce soit pour exposer dans le fil d'arianne, pour invalider lors de la publication, etc.)
Owner

Exemple concrêt de l'incohérence potentielle de l'API au singulier :

Si je déclare le parent comme suit pour les forum :

	$tables['spip_forum']['parent']     = array(
		array('condition' => 'id_parent>0', 'type' => 'forum', 'champ' => 'id_parent'),
		array('condition' => 'id_objet>0', 'champ_type' => 'objet', 'champ' => 'id_objet', 'exclus' => array('forum')),
	);

qui, selon l'API du plugin, est tout aussi juste que ce que propose le plugin, alors j'ai un fonctionnement de l'API tout a fait illogique dans un cas de figure comme ici :

Enfants de l'article 340 :
forum: 326, 328, 309, 310, 311, 312, 321, 319, 313, 327, 322, 323, 324, 325

Enfants de message 309 :
forum: 319, 326, 328

Parent du message forum id_forum=326
objet: forum
id_objet: 309
champ: id_parent
table: spip_forum

Parent du message forum id_forum=328
objet: forum
id_objet: 309
champ: id_parent
table: spip_forum

Parent du message forum id_forum=309
objet: article
id_objet: 340
champ: id_objet
champ_type: objet
table: spip_forum 

avec en base

sqlite> select id_forum, id_objet, objet, id_parent from spip_forum where id_forum IN (309,326,328)  order by objet, id_objet;
309|340|article|0
326|340|article|309
328|340|article|309

C'est à dire que l'API me dit bien que les messages 322 et 328 sont enfants de l'article 340 ET du message de forum 309.
MAIS ces derniers n'ont donc qu'un parent, le message 309 selon l'API.

On est donc dans une situation où selon ce qu'on va avoir mis dans la déclaration de parentée, on a un fonctionnement cohérent ou incohérent de l'API.

A contrario, avec l'API plurielles, générique, on remonte tous les parents dans tous les cas, et les traitements derrière s'adaptent en fonction de ce qu'ils doivent/veulent faire en filtrant sur le type, ou sur les infos du lien de parentée

Exemple concrêt de l'incohérence potentielle de l'API au singulier : Si je déclare le parent comme suit pour les forum : ``` $tables['spip_forum']['parent'] = array( array('condition' => 'id_parent>0', 'type' => 'forum', 'champ' => 'id_parent'), array('condition' => 'id_objet>0', 'champ_type' => 'objet', 'champ' => 'id_objet', 'exclus' => array('forum')), ); ``` qui, selon l'API du plugin, est tout aussi juste que ce que propose le plugin, alors j'ai un fonctionnement de l'API tout a fait illogique dans un cas de figure comme ici : <pre> Enfants de l'article 340 : forum: 326, 328, 309, 310, 311, 312, 321, 319, 313, 327, 322, 323, 324, 325 Enfants de message 309 : forum: 319, 326, 328 Parent du message forum id_forum=326 objet: forum id_objet: 309 champ: id_parent table: spip_forum Parent du message forum id_forum=328 objet: forum id_objet: 309 champ: id_parent table: spip_forum Parent du message forum id_forum=309 objet: article id_objet: 340 champ: id_objet champ_type: objet table: spip_forum </pre> avec en base <pre> sqlite> select id_forum, id_objet, objet, id_parent from spip_forum where id_forum IN (309,326,328) order by objet, id_objet; 309|340|article|0 326|340|article|309 328|340|article|309 </pre> C'est à dire que l'API me dit bien que les messages 322 et 328 sont enfants de l'article 340 ET du message de forum 309. MAIS ces derniers n'ont donc qu'un parent, le message 309 selon l'API. On est donc dans une situation où selon ce qu'on va avoir mis dans la déclaration de parentée, on a un fonctionnement cohérent ou incohérent de l'API. A contrario, avec l'API plurielles, générique, on remonte tous les parents dans tous les cas, et les traitements derrière s'adaptent en fonction de ce qu'ils doivent/veulent faire en filtrant sur le type, ou sur les infos du lien de parentée

Je trouve ce raisonnement en partie biaisé :

  • l'actuelle déclaration des conditions de parenté pour les forums part du principe que le but est d'avoir un parent unique qui est "le principal", le fait de savoir lequel bien sûr que c'est un choix du dev (avec une manière fournie par défaut), mais ça peut être changé par pipeline donc, si pour tel site le principal est plutôt un autre
  • ton exemple de modification de cette déclaration sert à continuer de parler de l'API au singulier, mais en partant du principe inverse que ça peut être multiple : le résultat est obligatoirement incohérent du coup ! donc c'est facile de générer des résultats incohérents, en mettant une déclaration qui ne suit pas le principe d'origine allant avec le concept de parent principal, forcément…

Avec la déclaration d'origine, c'est bien synchro entre parent et enfant puisque conçu pour n'en sortir qu'un.

Pour les forums (ça vaut pour le plugin Chapitres pareil), le choix partait du principe carrément courant dans 99% des utilisations des forums, que lorsqu'il y a bien un forum parent, que ce n'est pas un forum racine, et bien les champs "objet" et "id_objet" servaient d'accès rapide pour faire des requêtes plus performantes (pour compter les forums d'un objet, pour un résultat de recherche, etc), mais pas du tout en tant que "vrai parent" pour faire une hiérarchie. Dire que le sous-sous-sous-commentaire est enfant de l'objet racine, au niveau sémantique, c'est gentil si c'est 1% des cas…

Bien que ça puisse exister, je continue donc de trouver ce raisonnement un peu fallacieux : oui, comme tout dans la nature, toute exception existe, mais vla les proportions différentes.

Faire que la parenté déclare tout et n'importe quoi, sans aucune notion explicite possible de hiérarchisation de l'information (un parent prioritaire aux autres), ça augmente les possibilités pour quelques utilisations rares (très bien), en complexifiant grandement pour les 99% d'utilisations simples.

Comme pour tout ce qui est générique, je suis bien d'accord qu'il faut tenter de ne pas bloquer les utilisations moins courantes, mais pour ça faut pas rendre compliqué celles courantes. Voilà pourquoi dans l'autre ticket du plugin je proposais qu'il y ait une méthode explicite (pas "le premier qui vient", pour définir clairement lequel est le principal. Et OUI c'est UN CHOIX, personne n'a jamais dit le contraire : mais un choix qui peut se changer si t'es pas content du choix par défaut).


soit on est dans une situation multiparentale […] ET dans ce cas la règle générale c'est qu'il n'y a pas de parent "principal" mais juste des parents.

je vais pas le nier parceque

On peut dire pile exactement pareil pour ça… En effet, beaucoup d'utilisations finales attendent un seul résultat, ou que des choses ne sortent pas plusieurs fois. Donc non, c'est pas juste "des parents" : à un moment pour générer the URL principale, bah faut bien décider lesquels des parents sont à utiliser à chaque niveau.
=> je vais pas le nier parce que


Pour y voir plus clair, je trouverais utile de lister quelques utilisations réelles, notamment de parentés uniques, pour comprendre concrètement comment ça doit être utilisé ensuite, une fois qu'on a la parenté multiple. En effet, ce qui compte c'est pas que la déclaration ("je pense que tel objet est le parent de tels autres") mais les utilisations réelles ensuite ("j'ai besoin de générer une URL unique").

Quelques cas courants donc, depuis 3 ans que la déclaration existe avec le plugin :

  • Générer un chemin hiérarchique
    Exemple pour un Forum, ou un Chapitre : Accueil => Rubrique => Sous-rubrique => Article => Chapitre => Sous-chapitre (je suis là)
    Ici Chapitre et Sous-chapitre ont objet/id_objet de l'article
  • Générer l'URL principale canonique en arborescente (en gros sensiblement pareil que le chemin hiérarchique)
    Exemple : /rubrique/article/chapitre/sous-chapitre
    Ici Chapitre et Sous-chapitre ont objet/id_objet de l'article
  • Dupliquer un objet et ses enfants en cascade sans dupliquer plusieurs fois les mêmes contenus
    Exemple : dupliquer un article et tous ses commentaires, ou un article et tous ses chapitres
    Les sous-commentaires (ou sous-chapitres) ne doivent être dupliqués à la fois car enfant de l'article, puis ensuite car enfant d'un commentaire parent, mais bien une seule fois au fil de la hiérarchie
Je trouve ce raisonnement en partie biaisé : - l'actuelle déclaration des conditions de parenté pour les forums *part du principe* que le but est d'avoir un parent unique qui est "le principal", le fait de savoir lequel bien sûr que c'est un choix du dev (avec une manière fournie par défaut), mais ça peut être changé par pipeline donc, si pour tel site le principal est plutôt un autre - ton exemple de modification de cette déclaration sert à continuer de parler de l'API au singulier, mais en partant du principe inverse que ça peut être multiple : le résultat est obligatoirement incohérent du coup ! donc c'est facile de générer des résultats incohérents, en mettant une déclaration qui ne suit pas le principe d'origine allant avec le concept de parent principal, forcément… Avec la déclaration d'origine, c'est bien synchro entre parent et enfant puisque conçu pour n'en sortir qu'un. Pour les forums (ça vaut pour le plugin [Chapitres](https://git.spip.net/spip-contrib-extensions/chapitres/) pareil), le choix partait du principe carrément courant dans 99% des utilisations des forums, que *lorsqu'il y a bien un forum parent*, que ce n'est pas un forum racine, et bien les champs "objet" et "id_objet" servaient d'accès rapide pour faire des requêtes plus performantes (pour compter les forums d'un objet, pour un résultat de recherche, etc), mais pas du tout en tant que "vrai parent" pour faire une hiérarchie. Dire que le sous-sous-sous-commentaire est enfant de l'objet racine, au niveau sémantique, c'est gentil si c'est 1% des cas… Bien que ça puisse exister, je continue donc de trouver ce raisonnement un peu fallacieux : oui, comme tout dans la nature, toute exception existe, mais vla les proportions différentes. Faire que la parenté déclare tout et n'importe quoi, sans aucune notion explicite possible de hiérarchisation de l'information (un parent prioritaire aux autres), ça augmente les possibilités pour quelques utilisations rares (très bien), en complexifiant grandement pour les 99% d'utilisations simples. Comme pour tout ce qui est générique, je suis bien d'accord qu'il faut tenter de ne pas bloquer les utilisations moins courantes, mais pour ça faut pas rendre compliqué celles courantes. Voilà pourquoi dans l'autre ticket du plugin je proposais qu'il y ait une méthode explicite (pas "le premier qui vient", pour définir clairement lequel est le principal. Et OUI c'est UN CHOIX, personne n'a jamais dit le contraire : mais un choix qui peut se changer si t'es pas content du choix par défaut). --- > soit on est dans une situation multiparentale […] ET dans ce cas la règle générale c'est qu'il n'y a pas de parent "principal" mais juste _des parents_. > je vais pas le nier _parceque_ On peut dire pile exactement pareil pour ça… En effet, beaucoup d'utilisations finales attendent un seul résultat, ou que des choses ne sortent pas plusieurs fois. Donc non, c'est pas juste "des parents" : à un moment pour générer the URL principale, bah faut bien décider lesquels des parents sont à utiliser à chaque niveau. => je vais pas le nier _parce que_ --- Pour y voir plus clair, je trouverais utile de lister quelques utilisations réelles, notamment de parentés uniques, pour comprendre concrètement comment ça doit être utilisé ensuite, une fois qu'on a la parenté multiple. En effet, ce qui compte c'est pas que la déclaration ("je pense que tel objet est le parent de tels autres") mais les utilisations réelles ensuite ("j'ai besoin de générer une URL unique"). Quelques cas courants donc, depuis 3 ans que la déclaration existe avec le plugin : - Générer un chemin hiérarchique Exemple pour un Forum, ou un Chapitre : Accueil => Rubrique => Sous-rubrique => Article => Chapitre => Sous-chapitre (je suis là) Ici Chapitre et Sous-chapitre ont objet/id_objet de l'article - Générer l'URL principale canonique en arborescente (en gros sensiblement pareil que le chemin hiérarchique) Exemple : /rubrique/article/chapitre/sous-chapitre Ici Chapitre et Sous-chapitre ont objet/id_objet de l'article - Dupliquer un objet *et ses enfants en cascade* sans dupliquer plusieurs fois les mêmes contenus Exemple : dupliquer un article et tous ses commentaires, ou un article et tous ses chapitres Les sous-commentaires (ou sous-chapitres) ne doivent être dupliqués à la fois car enfant de l'article, puis ensuite car enfant d'un commentaire parent, mais bien une seule fois au fil de la hiérarchie
Owner

ton exemple de modification de cette déclaration sert à continuer de parler de l'API au singulier, mais en partant du principe inverse que ça peut être multiple : le résultat est obligatoirement incohérent du coup ! donc c'est facile de générer des résultats incohérents, en mettant une déclaration qui ne suit pas le principe d'origine allant avec le concept de parent principal, forcément…

C'est bien le sens de la démonstration. Là j'ai fait exprès de tomber dans l'angle mort de l'API, mais à partir du moment où il y a une zone de comportement incohérent tu peux être sur que quelqu'un va tomber dessus et là on va dire "ah mais c'est un bug de l'API".

Donc soit elle est concue pour gérer un unique parent, et elle doit apporter les garanties qu'on a bien un unique parent déterminisite ie lancer une exception si la déclaration n'est pas correcte pour trouver plusieurs parents, ou bien vérifier la déclaration et générer une erreur si la déclaration n'est pas correcte (mais bonjour la complication), ou encore quand elle cherche des enfants, faire une recherche de parent sur chaque enfant pour éliminer ceux dont le parent ne correspond pas (au moins on aurait symétrie).

Soit elle assume que oui, il y a des modes de déclaration qui permettent d'avoir des parents multiples, que ça représente la réalité des données, et elle est donc robuste à ce cas, ce qui passe par un retour de tableau de parents.

Je pense surtout que le défaut principal de la version monoparent c'est qu'on dit "Il faut un et un seul parent, on ne peut en avoir qu'un et ça doit être décidé dans la déclaration, une fois pour toute" alors qu'à partir du moment où un objet a plusieurs parents le choix du parent pertinent est souvent contextuel.

Si je reprends l'exemple du chemin hiérarchique que tu donnes

  • sur un message de forum en fond de thread, est-ce que ça a du sens de faire un chemin du genre "Acceuil => Rubrique => Article => Message1 => Message2 => Message3" ou bien est-ce que le chemin signifiant c'est pas simplement "Acceuil => Rubrique => Article => Message3" ? Je note que sur la dist on a pas choisi et on a éludé en faisant simplement "Acceuil => ... => Message3"

  • sur une rubrique polyhiérarchique, le chemin que je vais afficher va être contextuel d'un id_rubrique en environnement car tous les chemins ont du sens, et celui que je vais voulois afficher dépend de par quel menu je suis arrivé au contenu.

Le fait est que l'API monoparent ne permet même pas une implémentation propre du plugin polyhiérarchie, qui devra continuer à bidouiller...

Dans ton exemple de duplication d'un objet : si je veux faire une fonction qui fait "dupliquer cet article pour en faire un brouillon" je veux connaitre tous les parents de l'article pour pouvoir associer les mêmes à la copie (ie donc toutes ses rubriques)

Ensuite le fait de ne pas dupliquer le même contenu plusieurs fois ça a aucune raison de reposer sur l'API parent. En l'espèce si tu fais cela ta fonction est actuellement bugguée puisqu'avec mon exemple de déclaration parent du message précédent tu dupliquerai plusieurs fois au message 319 (vu comme un enfant de l'article 340 et du message 309)

Je pense qu'à partir du moment ou la structure des données donne plusieurs parents à un objet, ce n'est pas à la fonction API de collecte des parents d'en choisir un arbitrairement, mais à la fonction utilisatrice de choisir, si elle le doit, lequel est le plus pertinent dans son cas.

Si il se trouve que cette fonction n'a aucune espèce de préférence, elle prendra le premier parent, et elle aura le même résultat qu'avec l'API monoparent. Mais sinon au moins elle aura connaissance de tous les parents et pourra faire un choix eclairé.

Alors qu'avec l'API qui tronque et décide qu'un seul parent est possible on est mort : l'affaire est pliée, un parent unique a été élu et on a aucune visibilité des autres parents.

Et avoir les 2 fonctions API est un non sens, parce que c'est continuer à entretenir le doute et la confusion et inciter les dev à se reposer sur une fonction qui ne renvoie qu'un parent en masquant les autres, ce qui inévitablement provoquera des bugs.

> ton exemple de modification de cette déclaration sert à continuer de parler de l'API au singulier, mais en partant du principe inverse que ça peut être multiple : le résultat est obligatoirement incohérent du coup ! donc c'est facile de générer des résultats incohérents, en mettant une déclaration qui ne suit pas le principe d'origine allant avec le concept de parent principal, forcément… C'est bien le sens de la démonstration. Là j'ai fait exprès de tomber dans l'angle mort de l'API, mais à partir du moment où il y a une zone de comportement incohérent tu peux être sur que quelqu'un va tomber dessus et là on va dire "ah mais c'est un bug de l'API". Donc soit elle est concue pour gérer un unique parent, et elle doit apporter les garanties qu'on a bien un unique parent déterminisite ie lancer une exception si la déclaration n'est pas correcte pour trouver plusieurs parents, ou bien vérifier la déclaration et générer une erreur si la déclaration n'est pas correcte (mais bonjour la complication), ou encore quand elle cherche des enfants, faire une recherche de parent sur chaque enfant pour éliminer ceux dont le parent ne correspond pas (au moins on aurait symétrie). Soit elle assume que oui, il y a des modes de déclaration qui permettent d'avoir des parents multiples, que ça représente la réalité des données, et elle est donc robuste à ce cas, ce qui passe par un retour de tableau de parents. Je pense surtout que le défaut principal de la version monoparent c'est qu'on dit "Il faut un et un seul parent, on ne peut en avoir qu'un et ça doit être décidé dans la déclaration, une fois pour toute" alors qu'à partir du moment où un objet a plusieurs parents le choix du parent pertinent est souvent contextuel. Si je reprends l'exemple du chemin hiérarchique que tu donnes * sur un message de forum en fond de thread, est-ce que ça a du sens de faire un chemin du genre "Acceuil => Rubrique => Article => Message1 => Message2 => Message3" ou bien est-ce que le chemin signifiant c'est pas simplement "Acceuil => Rubrique => Article => Message3" ? Je note que sur la dist on a pas choisi et on a éludé en faisant simplement "Acceuil => ... => Message3" * sur une rubrique polyhiérarchique, le chemin que je vais afficher va être contextuel d'un id_rubrique en environnement car tous les chemins ont du sens, et celui que je vais voulois afficher dépend de par quel menu je suis arrivé au contenu. Le fait est que l'API monoparent ne permet même pas une implémentation propre du plugin polyhiérarchie, qui devra continuer à bidouiller... Dans ton exemple de duplication d'un objet : si je veux faire une fonction qui fait "dupliquer cet article pour en faire un brouillon" je veux connaitre tous les parents de l'article pour pouvoir associer les mêmes à la copie (ie donc toutes ses rubriques) Ensuite le fait de ne pas dupliquer le même contenu plusieurs fois ça a aucune raison de reposer sur l'API parent. En l'espèce si tu fais cela ta fonction est actuellement bugguée puisqu'avec mon exemple de déclaration parent du message précédent tu dupliquerai plusieurs fois au message 319 (vu comme un enfant de l'article 340 et du message 309) Je pense qu'à partir du moment ou la structure des données donne plusieurs parents à un objet, ce n'est pas à la fonction API de collecte des parents d'en choisir un arbitrairement, mais à la fonction utilisatrice de choisir, si elle le doit, lequel est le plus pertinent dans son cas. Si il se trouve que cette fonction n'a aucune espèce de préférence, elle prendra le premier parent, et elle aura le même résultat qu'avec l'API monoparent. Mais sinon au moins elle aura connaissance de tous les parents et pourra faire un choix eclairé. Alors qu'avec l'API qui tronque et décide qu'un seul parent est possible on est mort : l'affaire est pliée, un parent unique a été élu et on a aucune visibilité des autres parents. Et avoir les 2 fonctions API est un non sens, parce que c'est continuer à entretenir le doute et la confusion et inciter les dev à se reposer sur une fonction qui ne renvoie qu'un parent en masquant les autres, ce qui inévitablement provoquera des bugs.
Poster
Owner

Votre discussion est forte intéressante et à propos 🍿.

J'ai une question au pif : est-ce qu'on aura moyen avec ça de générer les fil d'ariane des objets éditoriaux de l'espace privé de SPIP sans que ça soit prise de tête ? et comment ça se passerait ? ou est-ce que ce n'est pas la portée de cette API ?

C'est peut être ce que veut signifier Rasta ? qu'il y ait la possibilité de déclarer «le cas standard de parent dans le contexte de visualisation dans l'espace privé de SPIP, c'est celui-là» ?.

Ou pas, et que si fil d'ariane il y a, et qu'un objet a 2 parents, ça doit créer 2 fils d'ariane. Mais lequel se mettrait le plus en haut ?

Votre discussion est forte intéressante et à propos 🍿. J'ai une question au pif : est-ce qu'on aura moyen avec ça de générer les fil d'ariane des objets éditoriaux de l'espace privé de SPIP sans que ça soit prise de tête ? et comment ça se passerait ? ou est-ce que ce n'est pas la portée de cette API ? C'est peut être ce que veut signifier Rasta ? qu'il y ait la possibilité de déclarer «le cas standard de parent dans le contexte de visualisation dans l'espace privé de SPIP, c'est celui-là» ?. Ou pas, et que si fil d'ariane il y a, et qu'un objet a 2 parents, ça doit créer 2 fils d'ariane. Mais lequel se mettrait le plus en haut ?
Owner

Si je prends l'exemple du plugin polyhiérarchie, on affiche dans l'espace privé un fil d'ariane par parent - mais uniquement par parent de l'objet concerné.

Aka : si un article a 2 rubriques, on affiche 2 fils d'arianne, mais si ensuite une des rubrique parent a elle même 2 rubriques, on ne doublonne pas, on reste sur le fil d'arianne de la première rubrique.

C'est un choix purement éditorial, un compromis entre l'information utile et trop d'information. Mais ça montre aussi, que c'est bien une histoire de contexte : dans certains cas je vais considérer tous les parents, dans d'autres cas je vais prendre le premier uniquement pour ne pas alourdir.

Et donc dans tous les cas l'API parents permettra d'écrire un fil d'Ariane. Mais dans le cas monoparent ça ne génèrera qu'un seul fil d'Ariane, et les cas multiparents devront être bricolés-patchés à la main comme le fait le plugin polyhierarchie actuellement.

Alors que dans le cas multiparent on peut avoir un fil d'Ariane qui fonctionne automatiquement, avec la stratégie d'affichage que l'on veut.

Si je prends l'exemple du plugin polyhiérarchie, on affiche dans l'espace privé un fil d'ariane par parent - mais uniquement par parent de l'objet concerné. Aka : si un article a 2 rubriques, on affiche 2 fils d'arianne, mais si ensuite une des rubrique parent a elle même 2 rubriques, on ne doublonne pas, on reste sur le fil d'arianne de la première rubrique. C'est un choix purement éditorial, un compromis entre l'information utile et trop d'information. Mais ça montre aussi, que c'est bien une histoire de contexte : dans certains cas je vais considérer tous les parents, dans d'autres cas je vais prendre le premier uniquement pour ne pas alourdir. Et donc dans tous les cas l'API parents permettra d'écrire un fil d'Ariane. Mais dans le cas monoparent ça ne génèrera qu'un seul fil d'Ariane, et les cas multiparents devront être bricolés-patchés à la main comme le fait le plugin polyhierarchie actuellement. Alors que dans le cas multiparent on peut avoir un fil d'Ariane qui fonctionne automatiquement, avec la stratégie d'affichage que l'on veut.

Ensuite le fait de ne pas dupliquer le même contenu plusieurs fois ça a aucune raison de reposer sur l'API parent. En l'espèce si tu fais cela ta fonction est actuellement bugguée puisqu'avec mon exemple de déclaration parent du message précédent tu dupliquerai plusieurs fois au message 319 (vu comme un enfant de l'article 340 et du message 309)

La phrase est fause tant qu'elle ne précise pas de quelle version de l'API tu parles. Car justement, non "ma fonction" n'est pas buguée du tout puisqu'elle est basée sur l'API actuelle, donc qui ne sort toujours qu'un seul parent. Donc non, ça ne peut rien dupliquer plusieurs fois.

Forcément si l'API change, la fonction doit être recodée en bonne partie, bien évidemment !

Je pense qu'à partir du moment ou la structure des données donne plusieurs parents à un objet, ce n'est pas à la fonction API de collecte des parents d'en choisir un arbitrairement, mais à la fonction utilisatrice de choisir, si elle le doit, lequel est le plus pertinent dans son cas.

Si il se trouve que cette fonction n'a aucune espèce de préférence, elle prendra le premier parent, et elle aura le même résultat qu'avec l'API monoparent.

Je ne comprends pas, pour le moment, ce concept de choix "par l'utilisation". À partir du moment où on parle d'utilisations génériques, ya justement PAS de contexte, ou quasiment pas.

Si je sais que je suis dans un squelette spécifiquement de Patate, bah je peux faire des choses propres aux Patates, je n'ai limite pas besoin de l'API de parenté ou quasi pas.

Mais moi je parle bien en priorité de toutes les utilisations où il n'y a pas de contexte précis ! On est "dans un objet", c'est tout. Et on doit générer son URL, ou son chemin unique principal (et avec Polyhiérarchie il y en a bien un principal, et des classements annexes en plus : donc les "différents chemins" ne doivent pas être aux mêmes niveaux : il y en a un précis qui doit être en premier).

Et non il ne faut pas prendre "le premier qui vient", comme on l'a dit dans le ticket du plugin (y compris toi) car à partir du moment où il y a plusieurs parents, l'ordre peut parfaitement être incontrôlable, dépendant de SQL, d'identifiants random, qui changent, etc.

Donc lorsqu'on a une utilisation qui a besoin d'une hiérarchie unique, on ne doit pas se baser sur le hasard : on devrait se baser sur une déclaration explicite, mise en place par les devs à un instant T (donc avec un CHOIX par défaut oui) mais modifiable si on n'est pas content puisque tout ça est dans un pipeline des objets.

De plus, au moment de l'utilisation, si jamais je pouvais donner un tant soit peu de contexte (ce qui n'est pas le cas la plupart du temps en générique comme je viens de le dire), ça serait uniquement sur l'objet final où on se trouve. Mais ensuite à chaque remontée, le parent lui-même peut avoir plusieurs parents, et donc là aussi il faut faire un choix, qui ne doit pas être aléatoire. Et ça un nombre indéfini de fois, 3, 5, 10, suivant le nombre de parents.

Donc vraiment, je ne comprends pas cette persistance à dire que "dès qu'il y en a plusieurs, c'est comme ça, et tu te démerdes à en prendre un au hasard" et qu'il n'y ait plus que la fonction qui retourne du multiple.

Par ailleurs, que l'on puisse éventuellement personnaliser (pour l'objet final sur lequel on est, voire pour tous les parents ce qui est mille fois plus compliqué à remplir) lors d'un appel, c'est une chose. Mais ça devrait surtout être utilisable toujours avec un défaut. Si j'ai besoin d'une hiérarchie unique (pour l'URL canonique par exemple, ou le chemin principal d'accès qui ne doit surtout pas renvoyer des parents secondaires), on ne devrait pas avoir à coder 12 couches en plus de config pour chaque utilisation.

Alors qu'avec l'API qui tronque et décide qu'un seul parent est possible on est mort : l'affaire est pliée, un parent unique a été élu et on a aucune visibilité des autres parents.

Enfin, vraiment… stop avec ça, ça fait deux mois maintenant qu'à aucun moment je n'ai dit que je voulais pas de multiple, mais que je dis que ça devrait AUSSI permettre de définir explicitement quelle lignée est "la principale". Et cela par défaut, sans plugin en plus, avec une fonction dédiée qui ne fait pas de hasard, mais qui prend bien une déclaration explicite.

Personne n'a parlé de tronquer quoi que ce soit. Ou plutôt si, c'est du coup toi qui préfère tronquer l'API ! :)
En ne permettant QUE du multiples "tout en bazar", sans jamais permettre de base de définir une hiérarchie de l'information, en disant lequel est le plus important (encore une fois, c'est une déclaration explicite donc je ne vois pas le problème vu que ça peut être modifié si le défaut convient pas).
Et du coup on se retrouvera avec plein d'utilisations courantes (à mon sens : la majorité) qui vont galérer à savoir quoi générer comme hiérarchie unique principale, alors que le but c'est pas de faire du hasard.
Qu'on puisse tout faire : super. Qu'on simplifie de base les cas d'utilisations courants : bien mieux.

sur un message de forum en fond de thread, est-ce que ça a du sens de faire un chemin du genre "Acceuil => Rubrique => Article => Message1 => Message2 => Message3" ou bien est-ce que le chemin signifiant c'est pas simplement "Acceuil => Rubrique => Article => Message3" ? Je note que sur la dist on a pas choisi et on a éludé en faisant simplement "Acceuil => ... => Message3"

Mais peu importe ce qui a du sens : yen a un principal quand même pour CE site ! Et donc ce que je dis d'avoir une déclaration duquel des deux (l'article racine ou le forum parent) est le principal est justement parfaitement pertinent. Le sytème fournit un choix par défaut, mais pour tel site tu peux le changer. Et ça vaut alors pour tout le site entier, et pas à faire à chacun des 15 utilisations où yen a besoin.

sur une rubrique polyhiérarchique, le chemin que je vais afficher va être contextuel d'un id_rubrique en environnement car tous les chemins ont du sens, et celui que je vais voulois afficher dépend de par quel menu je suis arrivé au contenu.

De même là, c'est uniquement ton utilisation perso… D'où ça sort à part chez toi ce truc d'avoir un id_rubrique en environnement, on peut très bien être sur la page d'un objet loin dessous en sous-enfant, sans strictement aucun contexte, et on DOIT pouvoir générer un chemin (autant pour l'interface que pour son URL unique canonique si on fait de l'arbo).

Imaginons que l'article suivant ait 5 rubriques en tout (chacune de ces rubriques pouvant AUSSI avoir plusieurs parents !)
Secteur => Rubrique => Sous-rubrique => Article => Chapitre => Sous-chapitre

  • Si je suis sur la page de cet article sans strictement rien d'autre dans l'URL,
  • ou pire si je suis dans un sous sous objet de cet article (je mets chapitre mais ça peut être n'importe quoi du moment que loin dessous)
  • => à aucun moment je n'ai de contexte autre que l'objet/id_objet de là où je suis.

La question est pourtant simple : on génère quoi comme chemin par défaut, sans 12000 calculs persos à faire ensuite. Si l'API prévoit une manière de dire "c'est ça la lignée principale par défaut" et qu'il y a bien toujours la fonction au singulier, c'est très simple.

> Ensuite le fait de ne pas dupliquer le même contenu plusieurs fois ça a aucune raison de reposer sur l'API parent. En l'espèce si tu fais cela ta fonction est actuellement bugguée puisqu'avec mon exemple de déclaration parent du message précédent tu dupliquerai plusieurs fois au message 319 (vu comme un enfant de l'article 340 et du message 309) La phrase est fause tant qu'elle ne précise pas _de quelle version de l'API_ tu parles. Car justement, non "ma fonction" n'est pas buguée du tout puisqu'elle est basée _sur l'API actuelle_, donc qui ne sort toujours qu'un seul parent. Donc non, ça ne peut rien dupliquer plusieurs fois. Forcément si l'API change, la fonction doit être recodée en bonne partie, bien évidemment ! > Je pense qu'à partir du moment ou la structure des données donne plusieurs parents à un objet, ce n'est pas à la fonction API de collecte des parents d'en choisir un arbitrairement, mais à la fonction utilisatrice de choisir, si elle le doit, lequel est le plus pertinent dans son cas. > > Si il se trouve que cette fonction n'a aucune espèce de préférence, elle prendra le premier parent, et elle aura le même résultat qu'avec l'API monoparent. Je ne comprends pas, pour le moment, ce concept de choix "par l'utilisation". À partir du moment où on parle d'utilisations génériques, ya justement PAS de contexte, ou quasiment pas. Si je sais que je suis dans un squelette spécifiquement de Patate, bah je peux faire des choses propres aux Patates, je n'ai limite pas besoin de l'API de parenté ou quasi pas. Mais moi je parle bien en priorité de toutes les utilisations où il n'y a pas de contexte précis ! On est "dans un objet", c'est tout. Et on doit générer son URL, ou son chemin unique principal (et avec Polyhiérarchie il y en a bien un principal, et des classements annexes en plus : donc les "différents chemins" ne doivent pas être aux mêmes niveaux : il y en a un précis qui doit être en premier). Et non il ne faut pas prendre "le premier qui vient", comme on l'a dit dans le ticket du plugin (y compris toi) car à partir du moment où il y a plusieurs parents, l'ordre peut parfaitement être incontrôlable, dépendant de SQL, d'identifiants random, qui changent, etc. Donc lorsqu'on a une utilisation qui a besoin d'une hiérarchie unique, on ne doit pas se baser sur le hasard : on devrait se baser sur une déclaration explicite, mise en place par les devs à un instant T (donc avec un CHOIX par défaut oui) mais modifiable si on n'est pas content puisque tout ça est dans un pipeline des objets. De plus, au moment de l'utilisation, si jamais je pouvais donner un tant soit peu de contexte (ce qui n'est pas le cas la plupart du temps en générique comme je viens de le dire), ça serait uniquement sur l'objet *final* où on se trouve. Mais ensuite à chaque remontée, le parent lui-même peut avoir plusieurs parents, et donc là aussi il faut faire un choix, qui ne doit pas être aléatoire. Et ça un nombre indéfini de fois, 3, 5, 10, suivant le nombre de parents. Donc vraiment, je ne comprends pas cette persistance à dire que "dès qu'il y en a plusieurs, c'est comme ça, et tu te démerdes à en prendre un au hasard" et qu'il n'y ait plus que la fonction qui retourne du multiple. Par ailleurs, que l'on puisse éventuellement personnaliser (pour l'objet final sur lequel on est, voire pour tous les parents ce qui est mille fois plus compliqué à remplir) lors d'un appel, c'est une chose. Mais ça devrait surtout être utilisable toujours avec un défaut. Si j'ai besoin d'une hiérarchie unique (pour l'URL canonique par exemple, ou le chemin principal d'accès qui ne doit surtout pas renvoyer des parents secondaires), on ne devrait pas avoir à coder 12 couches en plus de config pour chaque utilisation. > Alors qu'avec l'API qui tronque et décide qu'un seul parent est possible on est mort : l'affaire est pliée, un parent unique a été élu et on a aucune visibilité des autres parents. Enfin, vraiment… stop avec ça, ça fait deux mois maintenant qu'à aucun moment je n'ai dit que je voulais pas de multiple, mais que je dis que ça devrait AUSSI permettre de définir explicitement quelle lignée est "la principale". Et cela par défaut, sans plugin en plus, avec une fonction dédiée qui ne fait pas de hasard, mais qui prend bien une déclaration explicite. Personne n'a parlé de tronquer quoi que ce soit. Ou plutôt si, c'est du coup toi qui préfère tronquer l'API ! :) En ne permettant QUE du multiples "tout en bazar", sans jamais permettre de base de définir *une hiérarchie de l'information*, en disant lequel est le plus important (encore une fois, c'est une déclaration explicite donc je ne vois pas le problème vu que ça peut être modifié si le défaut convient pas). Et du coup on se retrouvera avec plein d'utilisations courantes (à mon sens : la majorité) qui vont galérer à savoir quoi générer comme hiérarchie unique principale, alors que le but c'est pas de faire du hasard. Qu'on puisse tout faire : super. Qu'on simplifie de base les cas d'utilisations courants : bien mieux. > sur un message de forum en fond de thread, est-ce que ça a du sens de faire un chemin du genre "Acceuil => Rubrique => Article => Message1 => Message2 => Message3" ou bien est-ce que le chemin signifiant c'est pas simplement "Acceuil => Rubrique => Article => Message3" ? Je note que sur la dist on a pas choisi et on a éludé en faisant simplement "Acceuil => ... => Message3" Mais peu importe ce qui a du sens : yen a un principal quand même pour CE site ! Et donc ce que je dis d'avoir une déclaration duquel des deux (l'article racine ou le forum parent) est le principal est justement parfaitement pertinent. Le sytème fournit un choix *par défaut*, mais pour tel site tu peux le changer. Et ça vaut alors pour tout le site entier, et pas à faire à chacun des 15 utilisations où yen a besoin. > sur une rubrique polyhiérarchique, le chemin que je vais afficher va être contextuel d'un id_rubrique en environnement car tous les chemins ont du sens, et celui que je vais voulois afficher dépend de par quel menu je suis arrivé au contenu. De même là, c'est uniquement ton utilisation perso… D'où ça sort à part chez toi ce truc d'avoir un id_rubrique en environnement, on peut très bien être sur la page d'un objet loin dessous en sous-enfant, sans strictement aucun contexte, et on DOIT pouvoir générer un chemin (autant pour l'interface que pour son URL unique canonique si on fait de l'arbo). Imaginons que l'article suivant ait 5 rubriques en tout (chacune de ces rubriques pouvant AUSSI avoir plusieurs parents !) Secteur => Rubrique => Sous-rubrique => Article => Chapitre => Sous-chapitre - Si je suis sur la page de cet article sans strictement rien d'autre dans l'URL, - ou pire si je suis dans un sous sous objet de cet article (je mets chapitre mais ça peut être n'importe quoi du moment que loin dessous) - => à aucun moment je n'ai de contexte autre que l'objet/id_objet de là où je suis. La question est pourtant simple : on génère quoi comme chemin *par défaut*, sans 12000 calculs persos à faire ensuite. Si l'API prévoit une manière de dire "c'est ça la lignée principale par défaut" et qu'il y a bien toujours la fonction au singulier, c'est très simple.

Je lis depuis quelques jours vos discussions. Et je dois dire que vous arriverez jamais à vous mettre d'accord, car ce qui est le par defaut ne doit pas être le même pour vous.

Ainsi voici une proposition :

  • declarer_parents_multiples, équivalent du declarer_parents de Cédric
  • declarer_parent_unique, équivalent du declarer_parent de Rasta

Ainsi :

  • pas de risque de confusion
  • chaque objet dit clairement si les parents sont uniques ou multiples
  • pour les cas des plugins qui ajoutent des parents multiples pour un objet à parent unique, declarer_parents_multiples prendrait le pas.
Je lis depuis quelques jours vos discussions. Et je dois dire que vous arriverez jamais à vous mettre d'accord, car ce qui est le _par defaut_ ne doit pas être le même pour vous. Ainsi voici une proposition : - `declarer_parents_multiples`, équivalent du `declarer_parents` de Cédric - `declarer_parent_unique`, équivalent du `declarer_parent` de Rasta Ainsi : - pas de risque de confusion - chaque objet dit clairement si les parents sont uniques ou multiples - pour les cas des plugins qui ajoutent des parents multiples pour un objet à parent unique, declarer_parents_multiples prendrait le pas.
b_b commented 3 weeks ago
Owner

hihi @maieul bien tenté, mais qu'apporte donc le fait de rajouter unique derrière parent au signulier et multiple derrière parents au pluriel ? ^^

hihi @maieul bien tenté, mais qu'apporte donc le fait de rajouter unique derrière parent au signulier et multiple derrière parents au pluriel ? ^^
Owner

@maieul ben non c'est pire que tout, on va pas créer 2 API et c'est pas aux objets de décider. Exemple dans le cas des rubriques elles ont par défaut 1 seul parent dans le core, et l'installation du plugin polyhierarchie leur confère plusieurs parents : il est pas question que le code qui fonctionnait avec une API ne fonctionne plus ensuite...

Si je sais que je suis dans un squelette spécifiquement de Patate, bah je peux faire des choses propres aux Patates, je n'ai limite pas besoin de l'API de parenté ou quasi pas.

@rastapopoulos ben si, typiquement l'exemple du dessus sur les messages de forum. On a pas géré dans le core parce que c'était trop compliqué et typiquement un endroit ou l'API est utile et on pourrait l'utiliser en disant "hop je remonte au parent qui n'est pas aussi un message de forum, et hop je remonte à ses parents et j'affiche le breadcrumb correspondant"

Mais on fond cette discussion a quand même quelque chose d'un peu ridicule :

  • soit on implémente une API au singulier au pretexte que c'est la majeure partie des cas ET l'API est limitée et ne permet même pas de gérer un cas comme le plugin polyhierarchie : c'est juste un non sens d'intégrer une nouvelle API qui ne gère même pas les cas connus

  • soit on implémente une API au pluriel, qui gère tous les cas, et les fonctions qui ne veulent prendre en compte qu'un seul parent ont juste à prendre le premier, ce qui fera exactement comme l'API au singulier fait actuellement. Mais au moins on peut coder des fonctions qui marchent dans tous les cas.

Si c'est vraiment un point de blocage on peut mettre en plus à disposition la fonction au singulier qui retourne le premier parent uniquement, mais ça me semble assez contreproductif...

@maieul ben non c'est pire que tout, on va pas créer 2 API et c'est pas aux objets de décider. Exemple dans le cas des rubriques elles ont par défaut 1 seul parent dans le core, et l'installation du plugin polyhierarchie leur confère plusieurs parents : il est pas question que le code qui fonctionnait avec une API ne fonctionne plus ensuite... > Si je sais que je suis dans un squelette spécifiquement de Patate, bah je peux faire des choses propres aux Patates, je n'ai limite pas besoin de l'API de parenté ou quasi pas. @rastapopoulos ben si, typiquement l'exemple du dessus sur les messages de forum. On a pas géré dans le core parce que c'était trop compliqué et typiquement un endroit ou l'API est utile et on pourrait l'utiliser en disant "hop je remonte au parent qui n'est pas aussi un message de forum, et hop je remonte à ses parents et j'affiche le breadcrumb correspondant" Mais on fond cette discussion a quand même quelque chose d'un peu ridicule : - soit on implémente une API au singulier au pretexte que c'est la majeure partie des cas ET l'API est limitée et ne permet même pas de gérer un cas comme le plugin polyhierarchie : c'est juste un non sens d'intégrer une nouvelle API qui ne gère même pas les cas connus - soit on implémente une API au pluriel, qui gère tous les cas, et les fonctions qui ne veulent prendre en compte qu'un seul parent ont *juste* à prendre le premier, ce qui fera exactement comme l'API au singulier fait actuellement. Mais au moins on peut coder des fonctions qui marchent dans tous les cas. Si c'est vraiment un point de blocage on peut mettre *en plus* à disposition la fonction au singulier qui retourne le premier parent uniquement, mais ça me semble assez contreproductif...

@b_b bah ca apporte que pour les objets qui peuvent avoir plusieurs parents, on utilise multiples, et pour ceux avec un parent unique, on utilise unique.

  • On sait donc clairement si on accepte 1 ou plusieurs parents
  • On repond aux deux besoins : pouvoir déclarer des parewnts multiples OU un parent unique
  • pour autant on évite le risque de confusions entre declarer_parents et declarer_parent.
@b_b bah ca apporte que pour les objets qui peuvent avoir plusieurs parents, on utilise multiples, et pour ceux avec un parent unique, on utilise unique. - On sait donc clairement si on accepte 1 ou plusieurs parents - On repond aux deux besoins : pouvoir déclarer des parewnts multiples OU un parent unique - pour autant on évite le risque de confusions entre `declarer_parents` et `declarer_parent`.

Si c'est vraiment un point de blocage on peut mettre en plus à disposition la fonction au singulier qui retourne le premier parent uniquement, mais ça me semble assez contreproductif...

@cerdic c'était la mon sens de ma proposition. Mais je reconnais que ma formulation n'était pas bonne, et que j'aurais du tout relire. Pas forcément proposer 2 APIs. Mais permettre de l'API "pluriel" (qui peut le plus peut le moins), tout en proposant quelques chose pour le cas courant "singulier". Donc

  • objet_trouver_parents()
  • objet_trouver_parent_unique() ou bien objet_trouver_parent_principal()
> Si c'est vraiment un point de blocage on peut mettre en plus à disposition la fonction au singulier qui retourne le premier parent uniquement, mais ça me semble assez contreproductif... @cerdic c'était la mon sens de ma proposition. Mais je reconnais que ma formulation n'était pas bonne, et que j'aurais du tout relire. Pas forcément proposer 2 APIs. Mais permettre de l'API "pluriel" (qui peut le plus peut le moins), tout en proposant quelques chose pour le cas courant "singulier". Donc - `objet_trouver_parents()` - `objet_trouver_parent_unique()` ou bien `objet_trouver_parent_principal()`
Owner

@maieul ben non c'est pire que tout, on va pas créer 2 API et c'est pas aux objets de décider. Exemple dans le cas des rubriques elles ont par défaut 1 seul parent dans le core, et l'installation du plugin polyhierarchie leur confère plusieurs parents : il est pas question que le code qui fonctionnait avec une API ne fonctionne plus ensuite...

Si c'est vraiment un point de blocage on peut mettre en plus à disposition la fonction au singulier qui retourne le premier parent uniquement, mais ça me semble assez contreproductif...

Franchement je ne comprends pas en quoi avoir tous les parents est un souci. Donc allons-y qui le plus peut le moins on va pas arguer pendant des années sur le sujet.
Après si il faut une fonction pour faire parents[0]...

> @maieul ben non c'est pire que tout, on va pas créer 2 API et c'est pas aux objets de décider. Exemple dans le cas des rubriques elles ont par défaut 1 seul parent dans le core, et l'installation du plugin polyhierarchie leur confère plusieurs parents : il est pas question que le code qui fonctionnait avec une API ne fonctionne plus ensuite... > > Si c'est vraiment un point de blocage on peut mettre *en plus* à disposition la fonction au singulier qui retourne le premier parent uniquement, mais ça me semble assez contreproductif... Franchement je ne comprends pas en quoi avoir tous les parents est un souci. Donc allons-y qui le plus peut le moins on va pas arguer pendant des années sur le sujet. Après si il faut une fonction pour faire parents[0]...
Owner

@maieul ta réponse illustre bien le problème de l'API singulier.

Tu dis "bah ca apporte que pour les objets qui peuvent avoir plusieurs parents, on utilise multiples, et pour ceux avec un parent unique, on utilise unique."

Mais justement, tu ne sais pas a priori si un objet peut avoir un ou plusieurs parents.

Je continue à prendre l'exemple de la polyhiérarchie de rubriques. Si on suit ta logique on va utiliser l'API au singulier dans tout le core parce que "les rubriques ne peuvent avoir qu'un parent".

Sauf justement que si je veux étendre ça, rien ne marchera.

Ce n'est donc pas en fonction des objets, mais éventuellement en fonction de l'usage.
Exemple : je veux afficher le fil d'Ariane, mais un seul, je prends le premier parent de chaque objet et j'ignore les autres. Tout en sachant que j'affiche volontairement pas tout éventuellement.

@maieul ta réponse illustre bien le problème de l'API singulier. Tu dis "bah ca apporte que pour les objets qui peuvent avoir plusieurs parents, on utilise multiples, et pour ceux avec un parent unique, on utilise unique." Mais justement, tu ne sais pas *a priori* si un objet peut avoir un ou plusieurs parents. Je continue à prendre l'exemple de la polyhiérarchie de rubriques. Si on suit ta logique on va utiliser l'API au singulier dans tout le core parce que "les rubriques ne peuvent avoir qu'un parent". Sauf justement que si je veux étendre ça, rien ne marchera. Ce n'est donc pas en fonction des objets, mais éventuellement en fonction de l'usage. Exemple : je veux afficher le fil d'Ariane, mais un seul, je prends le premier parent de chaque objet et j'ignore les autres. Tout en sachant que j'affiche volontairement pas tout éventuellement.
cerdic added 4 commits 2 days ago
55da3cb3c6 Fix #3844. Intégration de l'API de parenté dans le core de SPIP.
23b73be405 objet_trouver_parents() passe au pluriel et est agnostique : puisqu'on a potentiellement plusieurs liens de parentés (car plusieurs méthodes de parentés et certaines méthodes pouvant remonter plusieurs liens), la fonction ne choisit pas et retourne l'ensemble des parents symétriquement aux enfants.
cerdic added 2 commits 1 day ago
e3da3bd64c La fonction objet_trouver_enfants() retourne un tableau dans le même format que la fonction objet_trouver_parents(), a savoir une liste d'enfants de la forme
Owner

J'ai donc rebasé la PR pour la mettre à jour, et ajouté 2 commits :

  • la fonction objet_trouver_parents() retourne également le lien complet pour chaque parent trouvé via une table de liens, ce qui permet d'avoir accès au rang ou role ou toute autre information portée par le lien
  • la fonction objet_trouver_enfants() retourne une liste au même format que objet_trouver_parents() avec donc des informations détaillées et le lien si pertinent

On a donc ainsi une symétrie complète des 2 fonctions parents() et enfants() et elles renvoient toutes les informations utile sur la relation de parentée.

En complément j'ai ajouté 2 fonctions objet_trouver_enfants_par_type() et objet_trouver_parents_par_type() qui renvoient des listes simplifiées d'id regroupés par objet (le type de retour que la fonction objet_trouver_enfants() avait initialement)

D'un point de vue API on a donc maintenant quelque chose de complet et cohérent qui me semble bon à merger.

Par contre, on assure pas la continuité par rapport au plugin declarer_parent sur le retour des fonctions et leurs signatures.

Donc

  • soit on dit "tant pis, de toute façon c'est un SPIP 4, donc c'est le jeu ma pauvre lucette",
  • soit on renomme les fonctions objet_trouver_xxx() en objet_lister_xxx() (et idem pour les pipeline) ce qui évite tout risque de collision, et permettra une transition douce depuis le plugin qui continuera à fonctionner en utilisant les mêmes déclarations de parenté que le core mais avec ses propres fonctions.
    Et le code qui utilise le plugin declarer_parent pourra être recodé tranquillement sans urgence et sans rupture fonctionnelle

Le plan 2 me parait le mieux, si ça vous va je renomme et je merge.

J'ai donc rebasé la PR pour la mettre à jour, et ajouté 2 commits : - la fonction `objet_trouver_parents()` retourne également le lien complet pour chaque parent trouvé via une table de liens, ce qui permet d'avoir accès au rang ou role ou toute autre information portée par le lien - la fonction `objet_trouver_enfants()` retourne une liste au même format que `objet_trouver_parents()` avec donc des informations détaillées et le lien si pertinent On a donc ainsi une symétrie complète des 2 fonctions parents() et enfants() et elles renvoient toutes les informations utile sur la relation de parentée. En complément j'ai ajouté 2 fonctions `objet_trouver_enfants_par_type()` et `objet_trouver_parents_par_type()` qui renvoient des listes simplifiées d'id regroupés par objet (le type de retour que la `fonction objet_trouver_enfants()` avait initialement) D'un point de vue API on a donc maintenant quelque chose de complet et cohérent qui me semble bon à merger. Par contre, on assure pas la continuité par rapport au plugin declarer_parent sur le retour des fonctions et leurs signatures. Donc * soit on dit "tant pis, de toute façon c'est un SPIP 4, donc c'est le jeu ma pauvre lucette", * soit on renomme les fonctions `objet_trouver_xxx()` en `objet_lister_xxx()` (et idem pour les pipeline) ce qui évite tout risque de collision, et permettra une transition douce depuis le plugin qui continuera à fonctionner en utilisant les mêmes déclarations de parenté que le core mais avec ses propres fonctions. Et le code qui utilise le plugin declarer_parent pourra être recodé tranquillement sans urgence et sans rupture fonctionnelle Le plan 2 me parait le mieux, si ça vous va je renomme et je merge.
Poster
Owner

Excellent !

Excellent !
Eric commented 1 day ago
Owner

Parfait.

Pour le renommage pourquoi pas, ça permet une transition douce. Maintenant, comme le dit Lucette, je ne suis pas sur que cette API soit utilisée ailleurs que dans un ou deux plugins, donc pas directement. Si c'est bien ça, on pourrait rester sur le nommage actuel.

Parfait. Pour le renommage pourquoi pas, ça permet une transition douce. Maintenant, comme le dit Lucette, je ne suis pas sur que cette API soit utilisée ailleurs que dans un ou deux plugins, donc pas directement. Si c'est bien ça, on pourrait rester sur le nommage actuel.
b_b commented 1 day ago
Owner

@cerdic super, merci.

Juste une question, "Et le code qui utilise le plugin declarer_parent pourra être recodé tranquillement sans urgence et sans rupture fonctionnelle" => vous avez une idée de combien de plugins sont concernés par ça ? Est-ce que ça vaut le coup de se prendre la tête s'il n'y en que quelques uns.

@cerdic super, merci. Juste une question, "Et le code qui utilise le plugin declarer_parent pourra être recodé tranquillement sans urgence et sans rupture fonctionnelle" => vous avez une idée de combien de plugins sont concernés par ça ? Est-ce que ça vaut le coup de se prendre la tête s'il n'y en que quelques uns.
Owner

+1 pour la méthode 2...
...et @cerdic merci pour l'effort et la patience :)

+1 pour la méthode 2... ...et @cerdic merci pour l'effort et la patience :)
cerdic added 2 commits 1 day ago
cerdic merged commit a8026da42a into master 1 day ago
Owner

Allez c'est tout renommé pour éviter toute collision avec le plugin, et intégré

Allez c'est tout renommé pour éviter toute collision avec le plugin, et intégré
cerdic deleted branch issue_3844_bis 1 day ago
Owner

A bah bravo on fait les trucs pendant que les gens mangent.

C'est moi où personne ne m'a jamais répondu sur comment on fait pour les cas très concrets de la vie réelle, où on a besoin d'une seule hiérarchie principale ? :)

Par ex sans parler du tout de plugins annexes : si le noyau doit être modifié pour rendre générique la génération des URL arbos par défaut : que doit faire le code utilisateur pour obtenir LA hiérarchie unique principale qui va générer l'URL canonique "officielle" de l'objet ? On peut bien générer 12 URL si ya 12 parents, mais seule UNE adresse sera la canonique officielle. Le noyau lui-même doit prendre "le premier parent qui vient" donc sans déclaration explicite, au hasard de l'ordre ?

A bah bravo on fait les trucs pendant que les gens mangent. C'est moi où personne ne m'a jamais répondu sur comment on fait pour les cas très concrets de la vie réelle, où on a besoin d'une seule hiérarchie principale ? :) Par ex sans parler du tout de plugins annexes : si le noyau doit être modifié pour rendre générique la génération des URL arbos par défaut : que doit faire le code utilisateur pour obtenir LA hiérarchie unique principale qui va générer l'URL canonique "officielle" de l'objet ? On peut bien générer 12 URL si ya 12 parents, mais seule UNE adresse sera la canonique officielle. Le noyau lui-même doit prendre "le premier parent qui vient" donc sans déclaration explicite, au hasard de l'ordre ?

C'est moi où personne ne m'a jamais répondu sur comment on fait pour les cas très concrets de la vie réelle, où on a besoin d'une seule hiérarchie principale ? :)

Mais si :
6321ffd6f3 : Renommer toutes les fonctions parents/enfants pour eviter tout risque de collision avec le plugin historique declarer_parent qui pourra donc coexister et assurer une transition douce du code. Les pipelines sont aussi renommes

> C'est moi où personne ne m'a jamais répondu sur comment on fait pour les cas très concrets de la vie réelle, où on a besoin d'une seule hiérarchie principale ? :) Mais si : https://git.spip.net/spip/spip/commit/6321ffd6f39b6938d92ca3779d6f7d0c75919173 : Renommer toutes les fonctions parents/enfants pour eviter tout risque de collision avec le plugin historique declarer_parent qui pourra donc coexister et assurer une transition douce du code. Les pipelines sont aussi renommes
Owner

Alors je peux répondre parce que justement j'utilise la polyhierarchie ET les urls arbos dans la vie réelle.

Et donc déjà du point de vue de gestion des urls proprement dit :

  • dans la table spip_urls on stocke uniquement le segment de l'objet, associé à un id_parent ou non, et on peut donc gérer la multitude des parents
  • l'url par défaut est en effet celle obtenue en prenant le premier parent rubrique et en remontant la chaine des urls, et on peut définir que c'est l'URL canonique ou non, car cela dépend en pratique de comment et pourquoi tu utilises tes contenus polyhiérarchiques
  • mais on peut avoir d'autres URLs pertinentes et existantes, si par exemple je consulte l'article dans le contexte d'une autre rubrique. Dans ce cas les fils d'arianne ET les urls prennent en compte la rubrique du contexte pour remonter les parents (ie si plusieurs parents et l'un est dans le contexte on prend celui la).

Typiquement on peut faire fonctionner ça si l'API nous retourne bien tous les parents, pas si l'API choisit arbitrairement un seul parent.

Et encore une fois, forcer un choix dans l'API elle même, là où l'on ne sait pas l'usage ne résout pas la question du choix, ça ne fait que la cacher sous le tapis.

Dans la version amendée et mergée, l'API retourne en plus les informations sur les liens ce qui inclue éventuellement des rôles et permet de faire un choix de parent éclairé quand il y a besoin

Alors je peux répondre parce que justement j'utilise la polyhierarchie ET les urls arbos dans la vie réelle. Et donc déjà du point de vue de gestion des urls proprement dit : * dans la table spip_urls on stocke uniquement le segment de l'objet, associé à un id_parent ou non, et on peut donc gérer la multitude des parents * l'url par défaut est en effet celle obtenue en prenant le premier parent rubrique et en remontant la chaine des urls, et on peut définir que c'est l'URL canonique ou non, car cela dépend en pratique de comment et pourquoi tu utilises tes contenus polyhiérarchiques * mais on peut avoir d'autres URLs pertinentes et existantes, si par exemple je consulte l'article dans le contexte d'une autre rubrique. Dans ce cas les fils d'arianne ET les urls prennent en compte la rubrique du contexte pour remonter les parents (ie si plusieurs parents et l'un est dans le contexte on prend celui la). Typiquement on peut faire fonctionner ça si l'API nous retourne bien tous les parents, pas si l'API choisit arbitrairement un seul parent. Et encore une fois, forcer un choix dans l'API elle même, là où l'on ne sait pas l'usage ne résout pas la question du choix, ça ne fait que la cacher sous le tapis. Dans la version amendée et mergée, l'API retourne en plus les informations sur les liens ce qui inclue éventuellement des rôles et permet de faire un choix de parent éclairé quand il y a besoin
Owner

C'est pas pour faire chier mais je n'ai à peu près rien compris à cette réponse si on parle de code générique. :(

Il ne s'agit pas d'une utilisation pour tel site précis où tu contrôles ton code, je parle bien de toutes les utilisations où on va obligatoirement générer un truc par défaut. À chaque fois que j'ai mis des exemples plus haut au fil de la discussion t'as répondu à côté en disant "mais moi je fais comme ça dans mon code qui n'est propre qu'à tel site perso car c'est toujours dépendant de l'utilisation" en gros.

Je n'ai jamais demandé quoi faire quand on a son code qu'on contrôle pour tel site précis. Je parle de qu'est-ce qu'on génère dans tous les modules, squelettes, etc, qui sont génériques, et qui doivent générer un truc par défaut qui ne contient qu'un chemin principal.

Pouvoir personnaliser ensuite pour tel site, c'est totalement autre chose, c'est en plus et c'est super. Mais ya toujours un comportement par défaut quand même.

C'est le cas pour l'URL par défaut, pour savoir c'est laquelle. Pour chaque morceau ya bien UN couple type/id parent principal par défaut (càd quand il n'y a pas de contexte autre que la page où on est) : lequel ?
Mais ce n'est qu'un exemple, c'est pareil pour un squelette générique qui doit marcher pour tout objet et qui génère un chemin d'accès : ergonomiquement pour faire retenir à un visiteur "où se trouve ce contenu" pour qu'il s'en souvienne et revienne plus tard, on ne lui affiche pas 12 chemins possibles, on en affiche un principal par défaut (quand il n'y a aucun autre contexte) : lequel ?

Et j'ai déjà répondu pour l'histoire de "si on a un contexte" : déjà c'est propre à ton utilisation + t'as un contexte que pour l'objet final sur lequel tu es, mais chaque parent peut avoir plusieurs parents : donc pour chacun il faut aussi décider par défaut quel va être le parent pour faire un chemin et non pas un arbre. Quand tu veux afficher un fil d'ariane, un chemin hiérarchique : c'est un chemin qu'on affiche, pas un énorme arbre infini qui part dans tous les sens.

Sous-chapitre <= Chapitre <= Article <= peut avoir plusieurs parents (lequel prendre pour le principal ?) <= chaque parent peut avoir plusieurs parents (LEquel prendre à chaque fois ?) <= etc

Typiquement on peut faire fonctionner ça si l'API nous retourne bien tous les parents, pas si l'API choisit arbitrairement un seul parent.

Et encore une fois tu réponds avec l'homme de paille alors que j'ai jamais une seule fois dit ça depuis le tout début !…

Depuis le début je dis que si l'API permet de renvoyer plusieurs parents, il faudrait aussi donc en plus

  1. avoir une méthode permettant de déclarer lequel correspond à la "lignée principale" la plus importante (je redis encore ? c'est du par défaut : c'est une déclaration, donc ça peut se changer dans le pipeline si TOI t'es pas content du par défaut pour tel site précis où c'est autrement : quel rapport avec de l'arbritraire par l'API ? Aucun.).
  2. avoir une fonction (et/ou l'info dans le tableau multiple) montrant lequel est le principal

Justement pour que ça ne soit pas au code utilisateur de choisir "un au hasard à l'arrache" ! Sans aucun choix explicite, voulu, déterminé. Et surtout sans aucun choix qui peut se changer de manière claire (alors que c'est le but du pipeline de pouvoir s'insérer dedans pour changer les déclarations par défaut).

Bref : je ne comprends toujours pas ce que doit faire un code utilisateur qui a besoin de générer un chemin et non pas un arbre à branches.

Je sais pas quoi faire pour expliquer mieux, et surtout pour arrêter de faire dire des choses jamais dites… Faut une conversation orale pour dissiper les quiproquos ?

C'est pas pour faire chier mais je n'ai à peu près rien compris à cette réponse si on parle de code générique. :( Il ne s'agit pas d'une utilisation pour *tel* site précis où tu contrôles ton code, je parle bien de toutes les utilisations où on va obligatoirement générer un truc par défaut. À chaque fois que j'ai mis des exemples plus haut au fil de la discussion t'as répondu à côté en disant "mais moi je fais comme ça dans mon code qui n'est propre qu'à tel site perso car c'est toujours dépendant de l'utilisation" en gros. Je n'ai jamais demandé quoi faire quand on a son code qu'on contrôle pour tel site précis. Je parle de qu'est-ce qu'on génère dans tous les modules, squelettes, etc, qui sont génériques, et qui doivent générer un truc *par défaut* qui ne contient qu'un chemin principal. Pouvoir personnaliser *ensuite* pour tel site, c'est totalement autre chose, c'est en plus et c'est super. Mais ya toujours un comportement par défaut quand même. C'est le cas pour l'URL par défaut, pour savoir c'est laquelle. Pour chaque morceau ya bien UN couple type/id parent principal par défaut (càd quand il n'y a pas de contexte autre que la page où on est) : **lequel** ? Mais ce n'est qu'un exemple, c'est pareil pour un squelette générique qui doit marcher pour tout objet et qui génère un chemin d'accès : ergonomiquement pour faire retenir à un visiteur "où se trouve ce contenu" pour qu'il s'en souvienne et revienne plus tard, on ne lui affiche pas 12 chemins possibles, on en affiche un principal par défaut (quand il n'y a aucun autre contexte) : lequel ? Et j'ai déjà répondu pour l'histoire de "si on a un contexte" : déjà c'est propre à ton utilisation + t'as un contexte que pour l'objet final sur lequel tu es, mais *chaque parent* peut avoir plusieurs parents : donc pour chacun il faut aussi décider *par défaut* quel va être le parent pour faire un chemin et non pas un arbre. Quand tu veux afficher un fil d'ariane, un chemin hiérarchique : c'est un chemin qu'on affiche, pas un énorme arbre infini qui part dans tous les sens. Sous-chapitre <= Chapitre <= Article <= peut avoir plusieurs parents (lequel prendre pour le principal ?) <= chaque parent peut avoir plusieurs parents (LEquel prendre à chaque fois ?) <= etc > Typiquement on peut faire fonctionner ça si l'API nous retourne bien tous les parents, pas si l'API choisit arbitrairement un seul parent. Et encore une fois tu réponds avec l'homme de paille alors que j'ai jamais une seule fois dit ça depuis le tout début !… Depuis le début je dis que si l'API permet de renvoyer plusieurs parents, il faudrait *aussi* donc **en plus** 1) avoir une méthode permettant de déclarer lequel correspond à la "lignée principale" la plus importante (je redis encore ? c'est du **par défaut** : c'est une déclaration, donc ça peut se changer dans le pipeline si TOI t'es pas content du par défaut pour tel site précis où c'est autrement : quel rapport avec de l'arbritraire par l'API ? Aucun.). 2) avoir une fonction (et/ou l'info dans le tableau multiple) montrant lequel est le principal Justement pour que ça ne soit pas au code utilisateur de choisir "un au hasard à l'arrache" ! Sans aucun choix explicite, voulu, déterminé. Et surtout sans aucun choix qui peut se changer de manière claire (alors que c'est le but du pipeline de pouvoir s'insérer dedans pour changer les déclarations par défaut). Bref : je ne comprends toujours pas ce que doit faire un code utilisateur qui a besoin de générer *un chemin* et non pas un arbre à branches. Je sais pas quoi faire pour expliquer mieux, et surtout pour arrêter de faire dire des choses jamais dites… Faut une conversation orale pour dissiper les quiproquos ?
The pull request has been merged as a8026da42a.
Sign in to join this conversation.
No reviewers
No Label
No Milestone
No Assignees
8 Participants
Notifications
Due Date

No due date set.

Dependencies

This pull request currently doesn't have any dependencies.

Loading…
There is no content yet.