[spip-dev] #INSERT_HEAD ?

Bonjour,
Cette balise ne fait que créer des ennuis , particulièrement avec les anciens squelettes qui ne l'incluent pas. Il semble que son introduction soit passée inaperçue de beaucoup de monde...
C'est dangereux car alors, les gens s'en sortent en incluant jquery à la main, avec tout le non-suivi des évolutions que cela implique.

Il y a aussi le cas où elle est mise en double, ce qui provoque un effet très amusant (récursion infinie) cf. http://trac.rezo.net/trac/spip/ticket/692

Je crois qu'à l'époque, l'intention était de ne pas forcer la main et de n'inclure jQuery que si il était volontairement demandé.

Je pense, et je ne suis pas tout seul, qu'il faut inverser la chose: inclure jQuery systématiquement sauf si il est explicitement demandé de ne pas le faire ... une balise #NO_INSERT_HEAD ?

Hop,

Personnellement j’avoue ne pas trop comprendre à quoi sert cette balise.

J’ajoute effectivement jquery à la main pour les pages qui l’utilisent. Un plugin peut toujours ajouter jquery si celui-ci n’est pas défini (ça se fait par un test javascript), non ? Si je prends le cas de Crayon, celui-ci ajoute pas mal de choses en entete et vérifie l’existence de jquery et sa version. Mais en cas d’échec il n’en averti pas l’utilisateur et sort silencieusement (au lieu d’afficher un message d’erreur lorsqu’on est admin). Est-ce que le problème lié à #INSERT_HEAD n’est pas un problème de plugin ou de gestion des erreurs javascript, tout simplement ?

En fait ça me rappelle tout à fait l’article d’ALA : http://www.goodphptutorials.com/track/244 :wink:

Quand à ajouter jquery systématiquement c’est ajouter de la bande passante lorsqu’il n’y en a pas forcément besoin, non ? Mais à part jQuery, que rajoute #INSERT_HEAD ? Dernière remarque : quelquesoit l’utilisation de cette balise (ou son obligation), il faudrait que ce soit clairement indiqué dans la doc, ce qui n’est pas le cas de Crayon par exemple…

mes 2 cents,

.Gilles

#INSERT_HEAD est un point d'entrée dans le squelette qui permet a n'importe quel plugin d'ajouter automatiquement des css ou des js dans le <head>..</head> des pages publiques.
Il est utilisé également par le noyau pour inserer jQuery

Avoir cette balise dans son squelette permet aux plugins de gerer automtiquement les inclusions necessaires et d'etre immediatement fonctionnels, sans modification des squelettes.
L'alternative pour faire la meme chose consisterait a intervenir en fin de composition de la page et a coup de regexp d'inserer les lignes dites dans le <head>...</head>, mais cela est couteux et de plus n'est pas mis en cache, donc refait a chaque hit.

La dist integre #INSERT_HEAD depuis qu'il a ete ajouté (en 1.9.1, et c'est indiqué la http://www.spip.net/fr_article3462.html)

Le corrolaire de ce fonctionnement est que si #INSERT_HEAD n'est pas present, aucun js n'est insere dans la page, et le plugin ne peut pas prevenir qu'il n'est pas actif ...

En revanche on pourrait avoir un plan de repli generique qui consisterait a :
- en fin de composition (pipeline afficher_page) regarder si le #INSERT_HEAD a ete appelé (si on a un <head> dans le squelette evidemment)
- si ce n'est pas le cas, appeler le pipeline insert_head et inserer son contenu dans le <head>

Cela permettrait de fonctionner *a coup sur* au prix toutefois d'une degradation de perf, mais plus faible que si chaque plugin fait sa regexp en fin de composition.
Eventuellement, il faudrait alors peut etre regarder si on pourrait avoir un point d'entree non pas dans affichage_final (lorsque la page est extraite du cache pour etre affichée donc a chaque hit) mais au moment du stockage en cache afin de ne pas recommencer tout le temps.

Cedric

Gilles Vincent a écrit :

Non, c’est plus vicieux que ça lorsqu’on a déjà jquery à côté

Le corrolaire de ce fonctionnement est que si #INSERT_HEAD n’est pas
present, aucun js n’est insere dans la page, et le plugin ne peut pas
prevenir qu’il n’est pas actif …

Dans mon cas le comportement était le suivant : je javascript était inséré, Crayon semblait fonctionner (vu qu’on crayon s’affichait à côté de mes éléments). Par contre il n’affichait aucun bouton de validation (normal, vu qu’entre temps il s’était planté à cause de l’absence d’ajaxForm() ). J’avais le sentiment que le plugin ne fonctionnait donc qu’à moitié (ce qui est le cas de pas mal de plugins, on finit par s’y habituer ;), et du coup j’avais fait la mauvaise correction (sur le coup j’ai été trop impulsif :slight_smile:

En revanche on pourrait avoir un plan de repli generique qui
consisterait a :

  • en fin de composition (pipeline afficher_page) regarder si le
    #INSERT_HEAD a ete appelé (si on a un dans le squelette evidemment)
  • si ce n’est pas le cas, appeler le pipeline insert_head et inserer son
    contenu dans le

Ça ne me semble pas très fiable et cela entraînerait des erreurs pour ceux qui utilisent jquery pour autre chose que le plugin (je préfère pour ma part garder la maitrise de l’ajout de jquery au cas ou je - ou le futur admin du site - choisisse ensuite de désactiver le plugin qui en dépend)

Sans parler des problèmes qui peuvent être liés à la version de jquery utilisée : certains scripts ne sont plus compatibles avec les nouvelles versions de jquery et ça ne va pas s’arranger, vu les problèmes d’incompatibilité annoncés pour jquery1.1 (http://jquery.com/blog/2006/12/27/the-path-to-11/)

Là on est limite avec des notions de dépendance des plugins qu’il faudra résoudre… A mes yeux c’est dans l’interface d’admin des plugins que doivent s’afficher les erreurs d’utilisation du plugin (une erreur de dépendance pourrait déclencher un appel Ajax pour mémoriser en base de donnée qu’un squelette n’est pas compatible avec le plugin – et ressortir cette erreur dans l’interface privée) [Bon, dans un premier temps ça pourrait simplement consister en un fichier dans /tmp du type plugins.log]

Pour ce qui est de la doc du plugin, est-ce qu’il serait possible qu’un lien soit inséré dans l’interface privée ? Si je prends le cas de Crayon, j’ai bien cette page : http://www.spip-contrib.net/Widgets-Editer-directement-sur-le
mais je ne sais pas si c’est la doc officielle…

.Gilles

Gilles Vincent wrote:

Hop,

Personnellement j'avoue ne pas trop comprendre à quoi sert cette balise.

J'ajoute effectivement jquery à la main pour les pages qui l'utilisent. Un
plugin peut toujours ajouter jquery si celui-ci n'est pas défini (ça se fait
par un test javascript), non ?

Ben oui, mais on est chez le client là , c'est trop tard...
Par ailleurs, rajouté à la main t'oblige à suivre les modifications , comme les corrections de bugs dans jQuery 1.0.4 , à la main aussi.

Si je prends le cas de Crayon, celui-ci
ajoute pas mal de choses en entete et vérifie l'existence de jquery et sa
version.

Rhhooo... on n'ajoute presque rien.
Pour note, Crayons n'utilise pas #INSERT_HEAD mais le pipeline affichage_final
Et non, la vérification se fait coté client.

Mais en cas d'échec il n'en averti pas l'utilisateur et sort
silencieusement (au lieu d'afficher un message d'erreur lorsqu'on est
admin). Est-ce que le problème lié à #INSERT_HEAD n'est pas un problème de
plugin ou de gestion des erreurs javascript, tout simplement ?

euh... je rajoute une alerte javascript ( [8304] ), tu as raison , mais je sais pas comment js sait que l'utilisateur est admin. Enfin, Crayons ne s'insère que si l'utilisateur a des droits, ça ne fera pas d'alerte pour les non autorisés et l'implémenteur le saura tout de suite de toute façon.

En fait ça me rappelle tout à fait l'article d'ALA :
http://www.goodphptutorials.com/track/244 :wink:

Je ne vois pas le rapport

Quand à ajouter jquery systématiquement c'est ajouter de la bande passante
lorsqu'il n'y en a pas forcément besoin, non ?

Je pense que c'est un faux débat, en théorie , le cache fait qu'on ne rechargera pas

Mais à part jQuery, que
rajoute #INSERT_HEAD ?

C'est vrai que j'oubliais que c'est un point d'entrée général pour tout plugin voulant du js ou css spécifique (cf. la réponse de Cédric)

Dernière remarque : quelquesoit l'utilisation de
cette balise (ou son obligation), il faudrait que ce soit clairement indiqué
dans la doc, ce qui n'est pas le cas de Crayon par exemple..

Tu rigoles ? Dans admin plugins, clickes sur le lien de documentation, si il est là , c'est que c'est l'officiel.
Tu verras que c'est précisé et que ça a été évoqué plusieurs fois dans le forum.

oups, je suis vraiment à la masse pour les plugins :wink:

Gilles Vincent wrote:

Hop,

Personnellement j’avoue ne pas trop comprendre à quoi sert cette balise.

J’ajoute effectivement jquery à la main pour les pages qui
l’utilisent. Un
plugin peut toujours ajouter jquery si celui-ci n’est pas défini (ça
se fait
par un test javascript), non ?
Ben oui, mais on est chez le client là , c’est trop tard…

Non je ne pense pas. Si l’élément manquant est appelé dans ready(), il faut simplement ajouter les éléments manquants avant que le DOM ne soit complète (comme le fait la librairie http://blog.vyvojar.cz/tom/archive/0001/01/01/7669.aspx). Pour les autres dépendances, on peut utiliser des appels Ajax pour charger a posteriori des éléments manquants (dans le cas de Crayon, form.js n’est utilisé que lors de la validation du textarea : on peut très bien imaginer que celui-ci ne soit pas actif tant qu’un appel Ajax à form.js ne se soit terminé)

Par ailleurs, rajouté à la main t’oblige à suivre les modifications ,
comme les corrections de bugs dans jQuery 1.0.4 , à la main aussi.

Cela ne pose pas de problème. Imaginons que j’utilise lightbox depuis longtemps dans mes templates et que je veuille alors rajouter le plugin. Si celui-ci me force à une version trop récente de jQuery, mes anciens squelettes ne fonctionnent plus. Je préfère que ce soit le plugin qui me dise « désolé, je ne peux pas m’installer car je ne suis pas compatible avec votre configuration »

Si je prends le cas de Crayon, celui-ci
ajoute pas mal de choses en entete et vérifie l’existence de jquery et sa
version.
Rhhooo… on n’ajoute presque rien.

Bin y’a quand même pas mal de presque rien :wink:

Pour note, Crayons n’utilise pas #INSERT_HEAD mais le pipeline
affichage_final

Alors il y a un dilemne à résoudre là :
lorsque je clique sur le détail du plugin (dans le panneau d’admin), effectivement ce n’est pas indiqué qu’il faille utiliser #INSERT_HEAD
La doc sur spip-contrib (et l’avant-dernier commit de toggg) indique le contraire.

Et non, la vérification se fait coté client.

Mais en cas d’échec il n’en averti pas l’utilisateur et sort
silencieusement (au lieu d’afficher un message d’erreur lorsqu’on est
admin). Est-ce que le problème lié à #INSERT_HEAD n’est pas un
problème de
plugin ou de gestion des erreurs javascript, tout simplement ?
euh… je rajoute une alerte javascript ( [8304] ), tu as raison , mais
je sais pas comment js sait que l’utilisateur est admin. Enfin, Crayons
ne s’insère que si l’utilisateur a des droits, ça ne fera pas d’alerte
pour les non autorisés et l’implémenteur le saura tout de suite de toute
façon.

Quelques remarques au passage :

  • Très peu d’utilisateurs savent interpréter les erreurs javascript
  • pas mal de navigateurs ne disent rien lors d’une telle erreur (ou affichent un minuscule icône que personne ne voit)

Pour les non-autorisés, je suis d’accord : il n’y a aucun problème vu que le code n’est pas activé

En fait ça me rappelle tout à fait l’article d’ALA :
http://www.goodphptutorials.com/track/244 :wink:
Je ne vois pas le rapport

Si : une gestion silencieuse des erreurs. Ca plante mais on ne sais pas pourquoi, et on a aucune trace nulle part…
Il faudrait que les erreurs d’exécution des plugins soient mémorisées quelquepart ou affichent clairement un message d’erreur (comme le fait [8304])

Quand à ajouter jquery systématiquement c’est ajouter de la bande
passante
lorsqu’il n’y en a pas forcément besoin, non ?
Je pense que c’est un faux débat, en théorie , le cache fait qu’on ne
rechargera pas

Bin pour ceux qui ont des connexions lentes, ça joue quand même.
Et la gestion du cache n’est pas toujours optimale côté serveur / navigateur (il faut envoyer plein d’infos dans l’entête http qui ne sont pas envoyées si on n’a pas de cache proxy ou serveur, et donc de vieux navigateurs – ou dans certaines configs – rechargent tout systématiquement)

Mais à part jQuery, que
rajoute #INSERT_HEAD ?
C’est vrai que j’oubliais que c’est un point d’entrée général pour tout
plugin voulant du js ou css spécifique (cf. la réponse de Cédric)

oki, mais on en revient un peu à la question initiale :
cette balise est-elle la solution optimale pour des manips js ou css ? Comme tu l’indiquais, Crayon utilise aussi le pipeline affichage_final. Est-ce qu’il ne faudrait pas que ce soit soit l’un, soit l’autre ? Avec un tel pipeline, est-ce que #INSERT_HEAD est justifé ?

Dernière remarque : quelquesoit l’utilisation de
cette balise (ou son obligation), il faudrait que ce soit clairement
indiqué
dans la doc, ce qui n’est pas le cas de Crayon par exemple…
Tu rigoles ? Dans admin plugins, clickes sur le lien de documentation,
si il est là , c’est que c’est l’officiel.

Je n’avais tout simplement pas vu ce lien car il n’est pas visible immédiatement : j’ai mis à jour une « vieille » version de spip1.9 dans laquelle il n’y avait pas d’information lorsqu’on cliquait sur le nom du plugin.
Donc il ne m’est pas du tout apparu évident qu’il faille cliquer sur ce lien pour afficher les infos du plugin pour trouver le lien de la doc.
A mon avis c’est un problème d’utilisabilité, là…

Tu verras que c’est précisé et que ça a été évoqué plusieurs fois dans
le forum.

Je lis très peu le forum spip-zone en ce moment…
Je me suis comporté comme un utilisateur lambda : télécharger le zip, décompresser, tester, râler ;)=

.Gilles

Gilles Vincent a écrit :

oups, je suis vraiment à la masse pour les plugins :wink:

    Gilles Vincent wrote:
    > Hop,
    >
    > Personnellement j'avoue ne pas trop comprendre à quoi sert cette
    balise.
    >
    > J'ajoute effectivement jquery à la main pour les pages qui
    > l'utilisent. Un
    > plugin peut toujours ajouter jquery si celui-ci n'est pas défini (ça
    > se fait
    > par un test javascript), non ?
    Ben oui, mais on est chez le client là , c'est trop tard...

Non je ne pense pas. Si l'élément manquant est appelé dans ready(), il faut simplement ajouter les éléments manquants avant que le DOM ne soit complète (comme le fait la librairie http://blog.vyvojar.cz/tom/archive/0001/01/01/7669.aspx). Pour les autres dépendances, on peut utiliser des appels Ajax pour charger a posteriori des éléments manquants (dans le cas de Crayon, form.js n'est utilisé que lors de la validation du textarea : on peut très bien imaginer que celui-ci ne soit pas actif tant qu'un appel Ajax à form.js ne se soit terminé)

non, si tu as pas #INSERT_HEAD, ta page html n'a a priori aucun js embarqué, tu ne peux rien faire, y compris dire que tu ne peux rien faire

    Par ailleurs, rajouté à la main t'oblige à suivre les modifications ,
    comme les corrections de bugs dans jQuery 1.0.4 , à la main aussi.

Cela ne pose pas de problème. Imaginons que j'utilise lightbox depuis longtemps dans mes templates et que je veuille alors rajouter le plugin. Si celui-ci me force à une version trop récente de jQuery, mes anciens squelettes ne fonctionnent plus. Je préfère que ce soit le plugin qui me dise "désolé, je ne peux pas m'installer car je ne suis pas compatible avec votre configuration"

heu il faut un test de version sur jquery c'est ca ?

    > Si je prends le cas de Crayon, celui-ci
    > ajoute pas mal de choses en entete et vérifie l'existence de
    jquery et sa
    > version.
    Rhhooo... on n'ajoute presque rien.

Bin y'a quand même pas mal de presque rien :wink:

non pas tant que ca, ca depend des plugins que tu utilise...
Mais comme on ne sait pas a priori quelle page va utiliser quoi, bien obligé d'inserer tout ce qui peut etre necessaire a chaque fois, en comptant sur le cache du navigateur pour ne pas recharger a chaque hit

    Pour note, Crayons n'utilise pas #INSERT_HEAD mais le pipeline
    affichage_final

Alors il y a un dilemne à résoudre là : lorsque je clique sur le détail du plugin (dans le panneau d'admin), effectivement ce n'est pas indiqué qu'il faille utiliser #INSERT_HEAD

La doc sur spip-contrib (et l'avant-dernier commit de toggg) indique le contraire.

pas de dilemne, un oubli peut etre dans le descriptif, mais c'est la doc qui est la plus complete, forcement

...

    > Mais à part jQuery, que
    > rajoute #INSERT_HEAD ?
    C'est vrai que j'oubliais que c'est un point d'entrée général pour
    tout
    plugin voulant du js ou css spécifique (cf. la réponse de Cédric)

oki, mais on en revient un peu à la question initiale :
cette balise est-elle la solution optimale pour des manips js ou css ? Comme tu l'indiquais, Crayon utilise aussi le pipeline affichage_final. Est-ce qu'il ne faudrait pas que ce soit soit l'un, soit l'autre ? Avec un tel pipeline, est-ce que #INSERT_HEAD est justifé ?

Oui pour des raisons de performances exclusivement

#INSERT_HEAD est evalué lors du calcul de la page et son produit mis en cache avec le reste. De plus elle retourne juste du code qui est insere dans la page a la place de la balise
alors que affichage_final est appelé a chaque hit, et qu'il faudra faire au moins une regexp sur la page complete pour attraper le <head>..</head> et y glisser le code necessaire.

Cela dit ces questions de performances n'ont de sens que 'quand ca marche', donc je pense que je vais faire un truc a tiroir : #INSERT_HEAD restera préconisé pour la performance, mais si pas utilisé, affichage_final viendra glisser son contenu au moment de l'envoi de la page.
Ce comportement sera desactivable pour les bidouilleurs comme toi qui veulent faire ca a la mano :stuck_out_tongue:

    > Dernière remarque : quelquesoit l'utilisation de
    > cette balise (ou son obligation), il faudrait que ce soit clairement
    > indiqué
    > dans la doc, ce qui n'est pas le cas de Crayon par exemple..
    Tu rigoles ? Dans admin plugins, clickes sur le lien de documentation,
    si il est là , c'est que c'est l'officiel.

Je n'avais tout simplement pas vu ce lien car il n'est pas visible immédiatement : j'ai mis à jour une "vieille" version de spip1.9 dans laquelle il n'y avait pas d'information lorsqu'on cliquait sur le nom du plugin.

Ah si si, je proteste fermement, les informations sur les plugins ont toujours ete la ! Avant c'etait avec le triangle qu'on les depliait.

Donc il ne m'est pas du tout apparu évident qu'il faille cliquer sur ce lien pour afficher les infos du plugin pour trouver le lien de la doc.

A mon avis c'est un problème d'utilisabilité, là..

    Tu verras que c'est précisé et que ça a été évoqué plusieurs fois dans
    le forum.

Je lis très peu le forum spip-zone en ce moment.. Je me suis comporté comme un utilisateur lambda : télécharger le zip, décompresser, tester, râler ;)=

Bon ben ca regle le probleme, on va patcher pour que l'utilisateur lambda se pose pas de questions, meme avec un squelette pas optimisé qui contienne pas #INSERT_HEAD
Et les bricoleurs se debrouilleront :stuck_out_tongue:

Cedric

Discussion intéressante dès que j'ai le dos tourné :slight_smile:

Cela dit ces questions de performances n'ont de sens que 'quand ca
marche', donc je pense que je vais faire un truc a tiroir : #INSERT_HEAD
restera préconisé pour la performance, mais si pas utilisé,
affichage_final viendra glisser son contenu au moment de l'envoi de la page.

A ce compte-là il *faut* faire disparaître #INSERT_HEAD : pas la peine de
faire compliqué si on sait faire simple ! Pour la performance, chercher
'</head>' dans la page et le remplacer par "un truc" coûtera pas cher, et on
peut mettre en cache la valeur de "un truc" si on veut.

L'idée de #INSERT_HEAD c'était de ne surtout pas ajouter des trucs de façon
clandestine, mais ça c'est mort désormais (et de toutes façons c'est plutôt
le critère "flag_preserver" qui devrait faire ça, c-à-d maintenant le
#HTTP_HEADER{content-type} ).

J'ai fait une modif de crayons qui insère jquery tout seul s'il y est pas
déjà, je suis pas sûr encore que ce soit l'idéal (qui serait peut-être de
mettre dans crayons.js un mini-jquery qui ne contiendrait que ce dont les
crayons ont besoin, avec un namespace "crayons" plutôt que "jquery")... à
suivre. (Mais de toutes façons les crayons sont sépcifiques dans le sens où
ce plugin ne sert que pour un sous-groupe très limité de visiteurs.)

-- Fil