Voici un patch ultra simple, qui fait que les urls arbos utilisent enfin la VRAIE déclaration du titre (si elle existe). Ce qui permet à d'autres objets inconnus d'avoir automatiquement de superbes urls sans rien faire du tout.
Chez moi c'est testé et mis en prod avec des objets ayant "title" ou "problem" comme champ de titre, par exemple.
Quelqu'un pourrait-il corriger ce bug (oui c'est un bug) sur la branche stable ? Et le reporter en dev.
Pas trop d'accord avec ce patch: les AS ci-dessus sont déjà présents dans le fichier interfaces.php avec la globale $table_titrue.
Pour le type "site", il ne devrait pas y avoir de bug, il est bien déclaré.
Pour le type 'auteur', le pb est que c'est déclaré sous l'index "auteurs" avec un S; il vaudrait mieux se rabattre dessus, et je ne comprends pas pourquoi ce n'est que pour les auteurs qu'il y a un pb.
Ma modif permet justement d'utiliser ce qui est déclaré dans la globale $table_titre, et donc d'être totalement universalisable, puisque cette globale passe dans le pipeline interfaces.
Ce que j'ai mis là pour les urls "arbos", c'est ce qu'utilise les urls "propres" depuis longtemps et qui marche implacablement bien. Les urls "arbos" avaient ce code de test moche en dur dans le code, alors que le champ titre est déjà déclaré autre part.
Ma modif dit : "si le titre de ce type (rubrique, article, patate) est déclaré dans $table_titre, on le prend, sinon on utilise 'titre' par défaut".
Ah pardon, j'avais lu le patch à l'envers tellement j'étais persuadé avoir écrit la modif que tu proposes au moment où j'ai introduit l'index "titre" dans le tableau $desc retourné par trouver_table.
Je m'en occupe.
À propos de titres, j'en profite pour rappeler une remarque que j'avais faites lorsqu'on a ajouté la $table_titre dans le pipeline interfaces afin de rendre le système générique.
Avec l'API sur les d'objets/tables + le système de liens génériques (documents_liens) qui a un type et un id, on est désormais très souvent amené à devoir faire des listes d'objets, sans savoir à l'avance de quel type ils sont.
On peut d'ors et déjà générer l'URL de chacun de ces objets, uniquement avec les informations données par les tables de liaison. Mais impossible de récupérer directement le titre (ben oui, pour afficher une liste c'est mieux !) sans devoir le coder en dur à chaque fois.
À vrai dire, il n'y a même que les systèmes d'URLS qui utilisent le système de titre générique.
Ne trouvez-vous pas pertinent d'avoir une fonction *parallèle* à generer_url_entite(), dans utils, qui serait generer_titre_entite($id_objet, $type_objet) ?
J'utilise pour l'instant cette fonction en 2.0.9 qui me parait générique, donc pour le noyau :
function generer_titre_entite($id_objet, $type_objet){
include_spip('base/connect_sql');
include_spip('inc/texte');
global $table_titre;
$champ_titre = $table_titre[table_objet($type_objet)];
if (!$champ_titre) $champ_titre = 'titre';
$ligne = sql_fetsel(
$champ_titre,
table_objet_sql($type_objet),
id_table_objet($type_objet).'='.intval($id_objet)
);
return $ligne ? typo($ligne['titre']) : '';
}
Ne trouvez-vous pas pertinent d'avoir une fonction *parallèle* à
generer_url_entite(), dans utils, qui serait generer_titre_entite($id_objet,
$type_objet) ?
Ce serait pratique aussi pour générer un
<head><title>...</title></head> sans devoir boucler sur tout.
L’utilisation de typo ici me parait discutable car en dur au lieu de reprendre l’info declaree dans la table_des_traitements
Par ailleurs, plutot que developper x fonctions de ce type, une balise generique du type #INFO_ENTITE{id_objet,objet,quoi}
qui supporterait pour la valeur de quoi
‹ url › via generer_url_entite
‹ titre ›, via table_titre
et par defaut renverrai le champ sql formate comme il faut correspondant a ‹ quoi ›
me paraitrait plus polyvalente non ?
(bon, le nom que je propose est assez moche, mais je suis sur que vous allez trouver mieux ! )
Oui c'est super car plus générique. Par contre il ne faut pas juste que ce soit une balise, mais il faut qu'on puisse l'appeler en PHP aussi, on ne sait jamais.
Pour que ce soit extensible il faut faire :
- regarder s'il existe une fonction "generer_QUOI_entite" (c'est la forme commencé pour les URLs, autant garder la même)
- dans ce cas l'utiliser en priorité (et donc pas faire $table_titre en dur dans cette fonction générique, mais dans generer_titre_entite()
- si la fonction n'existe pas, là on va chercher le champ SQL comme tu dis
Pour le nom, j'ai une idée : ne mettre aucun nom et utiliser le système de balise générique, tout simplement comme le fait la balise #URL afin de pouvoir faire #URL_ARTICLE, #URL_SITE, #URL_PATATE automatiquement.
Après avoir codé la fonction PHP générique qu'on utilisera, il faut donc coder une balise : balise_INFO__dist() ayant deux arguments : l'id et le nom de l'info. Le type de l'objet sera alors dans la balise.
Ainsi on aura exactement le même comportement que pour les URLs :
- quand on connait à l'avance le type, on utilise #INFO_ARTICLE{#ENV{id_article}, titre}
- quand on ne connait pas à l'avance le type, on utilise le filtre (comme generer_url_entite) : generer_info_entite($id_objet, $type, $quoi)
Par ailleurs, plutot que developper x fonctions de ce type, une balise
generique du type #INFO_ENTITE{id_objet,objet,quoi}
qui supporterait pour la valeur de quoi
‹ url › via generer_url_entite
‹ titre ›, via table_titre
et par defaut renverrai le champ sql formate comme il faut correspondant
a ‹ quoi ›
me paraitrait plus polyvalente non ?
(bon, le nom que je propose est assez moche, mais je suis sur que vous
allez trouver mieux ! )
Oui c’est super car plus générique. Par contre il ne faut pas juste que ce soit une balise, mais il faut qu’on puisse l’appeler en PHP aussi, on ne sait jamais.
On peut faire un point d’entree PHP generer_info_entite qui soit appelable en php
Pour que ce soit extensible il faut faire :
regarder s’il existe une fonction « generer_QUOI_entite » (c’est la forme commencé pour les URLs, autant garder la même)
en utilisant charger_fonction()
dans ce cas l’utiliser en priorité (et donc pas faire $table_titre en dur dans cette fonction générique, mais dans generer_titre_entite()
ok, mais je serai d’avis de faire la requete en sql_select(‹ * ›,‹ spip_objets ›,‹ id_objet=xx ›) dans la fonction point d’entree et de passer le row à la fonction appelee le cas echeant (arguments a definir, la fonction url existante restant alors un cas particulier), de facon a pouvoir optimiser avec une static dans la fonction point d’entree
(pour eviter que 2 appels a balise pour un meme objet generent 2 requetes SQL).
si la fonction n’existe pas, là on va chercher le champ SQL comme tu dis
J'ai presque fini mais ya un blèm.
Je comprends le soucis d'optimisation, mais ça ne colle pas, au moins pour les titres.
En effet dans la globale $table_titre, il n'y a pas le nom d'UN champ, mais il y a une déclaration de select. C'est-à-dire que la valeur du tableau pour tel type devra être utilisé dans la commande SELECT du SQL.
On déclare quelque chose du style $table_titre['patates'] = 'variete AS titre';
Et ensuite dans la ligne de résultat on récupérera *toujours* immédiatement $ligne['titre'].
Ta méthode de faire un "select *" ne marche donc pas puisqu'ensuite la ligne de résultat ne pourra pas resservir : il faudra refaire une requête pour le titre avec le $table_titre...
Or le titre sera sûrement l'info la plus utilisée avec l'url, et c'est celle là qui ne sera pas optimisée. C'est un peu couillon.
Une solution ?
Je peux dire que le "select *" est fait pour rien dans le cas du titre, et je refais un deuxième static dans generer_titre_entite()...
En effet créer une fonction generer_TRUC_entite sert justement lorsqu'on veut gérer un cas particulier où l'info n'est pas directement le champ sql.
oui, dans ce cas injecter le $desc[‹ titre ›] dans le select de la fonction generique meme et y traiter directement le titre, sans faire de fonction dediee
El Friday 11 September 2009 04:01:15 Cédric Morin va escriure:
Par ailleurs, plutot que developper x fonctions de ce type, une
balise generique du type #INFO_ENTITE{id_objet,objet,quoi}
qui supporterait pour la valeur de quoi
'url' via generer_url_entite
'titre', via table_titre
Question de néophyte, mais pourquoi ne pas faire en sorte que par
exemple la balise #TITRE renvoie le champ titre s'il existe, ou le champ
qui a fonction de titre le cas échéant ? En gros pareil que
generer_titre_entite ou #INFO_ENTITE{...,...,titre} mais juste en
étendant la balise #TITRE.
#TITRE ne pourrait être mis que dans une boucle.
Le but des generer_truc_entite c'est de pouvoir choisir à quel type d'objet ça s'applique.
En plus avec la solution #INFO_<OBJET>{id, titre}, on peut sortir justement d'autre infos que le titre.
El Saturday 12 September 2009 03:19:00 RastaPopoulos va escriure:
#TITRE ne pourrait être mis que dans une boucle.
Le but des generer_truc_entite c'est de pouvoir choisir à quel type
d'objet ça s'applique.
En plus avec la solution #INFO_<OBJET>{id, titre}, on peut sortir
justement d'autre infos que le titre.
Je comprends.
Je crois que ma crainte de fond, c'est que le "vocabulaire" SPIP, en
devenant générique, perde en intuitivité. #INFO_ARTICLE{42,titre} est
certes plus puissant que #TITRE{42} ou #TITRE dans une boucle, et moins
puissant qu'un sql_select(), mais si on regarde la facilité d'approche,
le rapport s'inverse.
#TITRE, dans un squelette de page, c'est classe. #INFO_ARTICLE{42,titre}, déjà, je me sens davantage développeur, y'a une
partie du charme qui se brise.
Du coup je crois que c'est ça ma peur, c'est de voir se perdre la
"magie" de SPIP... Mais peut-être que j'ai tort (j'espère, même).
Moi aussi je comprends tout à faire ce que tu veux dire.
Mais ce sont deux usages totalement différents.
La fonctionnalité generer_TRUC_entite(), c'est quand tu ne sais pas à l'avance à quel type d'objet tu t'adresses. C'est donc de toute façon dans la plupart des cas un truc utilisé par les développeurs dans les squelettes de formulaires ou d'interfaces privées. Fort rarement dans le site public.
Lorsque tu es dans un squelette classique, tu fais des boucles, et dans une boucle tu sais explicitement quel objet tu demandes. Donc dans ce cas là, une fonction générique n'a pas trop de sens puisque tu sais quels champ utiliser.
Si je suis déjà dans une boucle (PATATE) (oui c'est toi qui a commencé avec les pommes de terre comme exemple), et que le titre déclaré pour une patate, c'est le champ SQL "variete". Et bien je n'ai pas besoin d'une balise générique #TITRE qui chercherait pour moi le titre : je le sais déjà, puisque je suis explicitement dans une boucle que je connais.
La magie est préservé pour 80% des gens. Les 20% qui veulent plus auront une fonction plus puissante pour les cas spécifiques.
Bon finalement je penche pour le contraire. En effet, dans les paramètres, on pet plutôt les infos qui peuvent varier, et là c'est justement le type des objets qui peut varier.
Ce que je proposais précédemment se rapprochait plus de ce qu'on connait avec #URL_<TYPE>{id}, mais pour la balise générique #INFO, je trouve finalement plus lisible de casser ça. Au profit donc de :
#INFO_<INFO>{type, id} qui pourra donc aller directement dans une boucle variable sans passer par le filtre generer_info_entite(). Alors que lorsque le type est variable, on est obligé de passer par le filtre pour generer_url_entite().
Ce qui donne : #INFO_TITRE{article, 1}
#INFO_URL{article, #ENV{id_article}}
(sans passer par un filtre, donc lisible !!)
#INFO_TITRE{patate, #ENV{id_patate}}
davux, ça te va comme ça ? ça reste assez magique ?