[spip-dev] plugins et CSS/JS

Beaucoup de plugins vont vouloir importer ou modifier du CSS ou du
javascript dans le <head></head> des pages HTML du site.

Pour l'instant il n'existe aucune méthode pour faire cela, à part éditer
tous les squelettes.

Une solution serait d'avoir une ou des balises spécialisées.

Comme j'ai un peu de mal à voir ce qui serait le mieux parmi plusieurs
possibilités, j'ai pris quelques notes :

- #PLUGINS_HEAD ? On y met tout en vrac et chaque plugin se débrouille à
coups de preg_match pour savoir où il doit travailler (??)

- #SPIP_CSS et #SPIP_JS (ou #SPIP_JAVASCRIPT, peut-être plus compréhensible
à priori ?)

valeurs par défaut :

- #SPIP_CSS pourrait être, par défaut, soit vide soit ce qui actuellement
vaut [(#CHEMIN{spip_style.css}|direction_css)]

- #SPIP_JS pourrait être, par défaut, soit vide, soit charger un truc comme
ahah.js, ce qui permettrait aux formulaires SPIP de fonctionner "sur place"
(comme dans l'ébauche de formulaire "envoyer à un ami" que j'ai mis sur SPIP
Zone).

Enfin, comment mettre en place ces balises :

- Pour le CSS faut-il retourner une somme de tags HTML de la forme <link
rel="stylesheet".... />, au risque de faire charger une foule de micro-css
pour chaque plugin ? Ou au contraire faire un grand pipeline avec le contenu
de spip_style.css, auquel chaque plugin ajoute sa déclaration, et qui à la
fin est transformée par direction_css et enregistré dans IMG/cache-css/ ?

- Pour le javascript deux options aussi : soit on passe le HTML <link etc>
et chacun ajoute son link, soit on passe la liste (array) des fichiers .js
requis

la difficulté ici est que si trois plugins ont besoin de prototype.js il
vaut mieux ne le charger qu'une fois -- mais ça peut se faire avec un
preg_match qui teste la présence du script et sinon l'ajoute ?

Après avoir tapé ces notes, a priori ma préférence irait à #SPIP_CSS +
#SPIP_JS ;
- #SPIP_CSS retournerait un seul <link stylesheet> vers une unique feuille
de style calculée comme la somme de tous les styles demandés par les
plugins; le pipeline transporterait des déclarations CSS, et finirait par un
truc de gestion de la "direction_css" (ce qui permettrait aussi aux plugins
de préciser "left" et que ça donne "right" en arabe).
- #SPIP_JS retournerait une série de <link js> ; le pipeline transporterait
le HTML correspondant (donc, pas le contenu, contrairement à #SPIP_CSS).

-- Fil

Après avoir tapé ces notes, a priori ma préférence irait à #SPIP_CSS +
#SPIP_JS ;
- #SPIP_CSS retournerait un seul <link stylesheet> vers une unique feuille
de style calculée comme la somme de tous les styles demandés par les
plugins; le pipeline transporterait des déclarations CSS, et finirait par un
truc de gestion de la "direction_css" (ce qui permettrait aussi aux plugins
de préciser "left" et que ça donne "right" en arabe).
  

moi je préférerais #SPIP_PLUGIN_CSS et je trouve cela bof d'imposer l'utilisation d'un type de balise pour appeler les css ( link en l'occurence), on peut tres bien vouloir utiliser @import qui à l'avantage de ne pas être prise en compte par les vieux navigateurs.

De plus, comment faire lorsque deux plugin définisse deux selecteurs css identique?

Aurélien

Fil a écrit :

Beaucoup de plugins vont vouloir importer ou modifier du CSS ou du
javascript dans le <head></head> des pages HTML du site.

Pour l'instant il n'existe aucune méthode pour faire cela, à part éditer
tous les squelettes.
[...]

J'ai un seul squelette pour tout ce qui est dans le <head>...</head>
donc, si je veux changer quelque chose au niveau des appels css ou javascript, je n'ai qu'un fichier à changer.

Cela dit, c'est peut-être interessant de voir quelles sont les autres solutions.

peut-être qu'il faudrait plus d'INCLUDE dans la dist.

Amicalement
Grégoire

Salut,
Fil a écrit :

Beaucoup de plugins vont vouloir importer ou modifier du CSS ou du
javascript dans le <head></head> des pages HTML du site.

Pour l'instant il n'existe aucune méthode pour faire cela, à part éditer
tous les squelettes.

Une solution serait d'avoir une ou des balises spécialisées.
  

une autre solution serait de definir simplement l'API correspondante et de ne pas toucher aux squelettes.
Au niveau compatibilité, c'est encore le mieux.

Pourquoi ne pas inclure simplement un spip_plugin.js et un spip_plugin.css si ils sont utilisés par au moins 1 plugin ?

Après, quand plusieurs plugins utilisent du css ou du js, on en revient au probleme d'ordre dans les plugins, mais c'est à priori pas très grave.

sur spipcarto, je fais de l'insertion de styles et de javascript au milieu du code.
Mais pour le js, ca pose pb avec IE si je me souviens bien.
Et coté css, c'est pas tres propre et ca limite les possibilités.

Pouvoir declarer du css ou du js à inserer dans le head via 2 fonctions specifiques à declarer et implémenter ca serait l'idéal.

Après se posera de toutes facons le pb du contexte (si on fait du js ou du css en fonction du contenu), mais c'est pour des utilisations specifiques et je ne vois pas vraiment comment on pourrait s'en sortir, le head n'etant pas forcement dans le meme contexte de mise en cache que le morceau contenant le parametre.
Donc pour moi, l'ajout de js et css par un plugin doit etre du systematique et non contextuel, je ne vois donc pas d'interet "fonctionnel" à devoir ajouter des balises (ou alors de facon optionnelle pour positionner l'appel du .css et du .js mais c'est compliquer les traitements pour un interet limité, d'une maniere generale, on voudra se placer à la fin du head)

Mes 2 sous...

@++

Gregoire wrote:

Fil a écrit :

Beaucoup de plugins vont vouloir importer ou modifier du CSS ou du
javascript dans le <head></head> des pages HTML du site.

Pour l'instant il n'existe aucune méthode pour faire cela, à part éditer
tous les squelettes.
[...]
   
J'ai un seul squelette pour tout ce qui est dans le <head>...</head>
donc, si je veux changer quelque chose au niveau des appels css ou javascript, je n'ai qu'un fichier à changer.

Cela dit, c'est peut-être interessant de voir quelles sont les autres solutions.

peut-être qu'il faudrait plus d'INCLUDE dans la dist.

C'est pas ce qu'on disait ?
Bien sûr , pas officiel.
Pas de citation.

Mais tatoutoi.
à+

Fil wrote:

Beaucoup de plugins vont vouloir importer ou modifier du CSS ou du
javascript dans le <head></head> des pages HTML du site.

Pour l'instant il n'existe aucune méthode pour faire cela, à part éditer
tous les squelettes.

Ca te moucherait de citer http://thread.gmane.org/gmane.comp.web.spip.devel/35600/focus=35600 ?
J'ai pas cité la discussion qu'on avait eu sur irc qui m'avait décidé à poster.
Il la faut ?
Sinon ... je lis
à+

http://thread.gmane.org/gmane.comp.web.spip.devel/35600/focus=35600 ?

Désolé de l'absence de lien ; en effet je suis plutôt d'accord avec ton idée
de "ménager plusieurs points d'entrée pour chaque type d'ajouts dans
<head>".

-- Fil

Fil wrote:

http://thread.gmane.org/gmane.comp.web.spip.devel/35600/focus=35600 ?
   
Désolé de l'absence de lien ; en effet je suis plutôt d'accord avec ton idée
de "ménager plusieurs points d'entrée pour chaque type d'ajouts dans
<head>".

Un aspect de cette discussion était qu'on en avait pas besoin de 36.
La question est uniquement les (re)calculs.

Les héritages et la non dépendance ?

Sans rien répéter , hein !
(css supporte , pas trop js)

Un simple , que tout à chacun puisse rajouter des choses (XML et tout correct) dans le <head>
Comme regrouper les squelettes de la dist qui font tous pareil.

Spiply yours

http://thread.gmane.org/gmane.comp.web.spip.devel/35600/focus=35600 ?

Désolé de l'absence de lien ; en effet je suis plutôt d'accord avec ton idée
de "ménager plusieurs points d'entrée pour chaque type d'ajouts dans
<head>".

Je pense qu'ici nous discutons de 2 besoins différents, mais
complémentaires.

1. Les besoins de webmestres (et de développeurs de squelettes génériques)
désirant personnaliser radicalement les squelettes de la /dist en modifiant
le minimum de fichiers.

2. Les besoins des développeurs de plugins d'ajouter des éléments dans
<head>.

Il me semble que ma suggestion formulé le 2006-06-23 répondrait au premier
besoin :
  http://article.gmane.org/gmane.comp.web.spip.devel/35364/

Quant au deuxième besoin, la proposition de fil d'ajouter de nouvelles
balises pourrait répondre à ce besoin.

Après avoir tapé ces notes, a priori ma préférence irait à #SPIP_CSS +
#SPIP_JS ;
- #SPIP_CSS retournerait un seul <link stylesheet> vers une unique feuille
de style calculée comme la somme de tous les styles demandés par les
plugins; le pipeline transporterait des déclarations CSS, et finirait par un
truc de gestion de la "direction_css" (ce qui permettrait aussi aux plugins
de préciser "left" et que ça donne "right" en arabe).
- #SPIP_JS retournerait une série de <link js> ; le pipeline transporterait
le HTML correspondant (donc, pas le contenu, contrairement à #SPIP_CSS).

Oui, ça répondrait à un besoin immédiat, mais pas sûr que ça convienne, à
long terme. Quand des plugins voudront rajouter des META dans le <head> ou
d'autres types de scripts ou de styles.

J'aurais tendance à laisser ça relativement ouvert au début avec une seule
balise #SPIP_HEAD, pouvant recevoir tous les éléments valides. Ensuite on
pourra raffiner, filtrer ou ordonner tout ça, si besoin est. J'opterais pour
offrir aux développeurs de plugins une seule balise et la possibilité d'y
intervenir correctement, dans l'élément HTML de leur choix, avec les
attributs et les valeurs appropriées.

Il est vrai qu'il n'y a pas 36 types d'éléments possibles à rajouter dans
<head>. En fait, il n'y en a que 5, MAIS avec de très nombreuses variantes
et combinaisons possibles. Pourquoi choisir seulement 2 méthodes ?

Pour rappel des éléments de l'élément <head> (non exhaustif)

    1. <link>
        - rel="[une multitude de possibilités, dont icône, backend, etc...]"
        - rel="sylesheet" ou "alternate stylesheet"
                + media="[divers]
                + title=[optionnel]"
    2. <styles>
        - interne : règles complètes (explicitement déclarées)
        - externe : par : @import url(...)
    3. <script> et son optionnel complément <noscript> souvent oublié...
        - interne : code complet (explicitement déclaré)
        - externe : par : src="mon_script.js"
    4. <meta>
        - là c'est la foire... Et je vois venir des dizaines de plugins.
    5. <base>
        - tiens, on n'utilise pas ça souvent, mais pourtant...

Sans oublier les nécessaires balises de commentaires (en HTML ou CDATA,
selon le cas) pour les styles ou script déclarés explicitement.

CONCLUSION

Andre Vincent wrote:

Je pense qu'ici nous discutons de 2 besoins différents, mais
complémentaires.

1. Les besoins de webmestres (et de développeurs de squelettes génériques)
désirant personnaliser radicalement les squelettes de la /dist en modifiant
le minimum de fichiers.

2. Les besoins des développeurs de plugins d'ajouter des éléments dans
<head>.

Il me semble que ma suggestion formulé le 2006-06-23 répondrait au premier
besoin :
http://article.gmane.org/gmane.comp.web.spip.devel/35364/

Quant au deuxième besoin, la proposition de fil d'ajouter de nouvelles
balises pourrait répondre à ce besoin.

Après avoir tapé ces notes, a priori ma préférence irait à #SPIP_CSS +
#SPIP_JS ;
- #SPIP_CSS retournerait un seul <link stylesheet> vers une unique feuille
de style calculée comme la somme de tous les styles demandés par les
plugins; le pipeline transporterait des déclarations CSS, et finirait par un
truc de gestion de la "direction_css" (ce qui permettrait aussi aux plugins
de préciser "left" et que ça donne "right" en arabe).
- #SPIP_JS retournerait une série de <link js> ; le pipeline transporterait
le HTML correspondant (donc, pas le contenu, contrairement à #SPIP_CSS).
   
Oui, ça répondrait à un besoin immédiat, mais pas sûr que ça convienne, à
long terme. Quand des plugins voudront rajouter des META dans le <head> ou
d'autres types de scripts ou de styles.

J'aurais tendance à laisser ça relativement ouvert au début avec une seule
balise #SPIP_HEAD, pouvant recevoir tous les éléments valides. Ensuite on
pourra raffiner, filtrer ou ordonner tout ça, si besoin est. J'opterais pour
offrir aux développeurs de plugins une seule balise et la possibilité d'y
intervenir correctement, dans l'élément HTML de leur choix, avec les
attributs et les valeurs appropriées.

Il est vrai qu'il n'y a pas 36 types d'éléments possibles à rajouter dans
<head>. En fait, il n'y en a que 5, MAIS avec de très nombreuses variantes
et combinaisons possibles. Pourquoi choisir seulement 2 méthodes ?

Pour rappel des éléments de l'élément <head> (non exhaustif)

   1. <link>
       - rel="[une multitude de possibilités, dont icône, backend, etc...]"
       - rel="sylesheet" ou "alternate stylesheet"
               + media="[divers]
               + title=[optionnel]"
   2. <styles>
       - interne : règles complètes (explicitement déclarées)
       - externe : par : @import url(...)
   3. <script> et son optionnel complément <noscript> souvent oublié...
       - interne : code complet (explicitement déclaré)
       - externe : par : src="mon_script.js"
   4. <meta>
       - là c'est la foire... Et je vois venir des dizaines de plugins.
   5. <base>
       - tiens, on n'utilise pas ça souvent, mais pourtant...

Sans oublier les nécessaires balises de commentaires (en HTML ou CDATA,
selon le cas) pour les styles ou script déclarés explicitement.

CONCLUSION
----------

Je suggère donc :

1. Pour répondre au premier besoin : de remplacer dans le <head> de tous les
squelettes de la /dist les lignes suivantes :

----

   <!-- Ceci est la feuille de style par defaut pour le code genere par
SPIP -->
   <link rel="stylesheet" href="[(#CHEMIN{spip_style.css}|direction_css)]"
type="text/css" media="all" />
   <!-- Feuille de styles CSS pour l'affichage du site sur ecran -->
   <link rel="stylesheet" href="[(#CHEMIN{habillage.css}|direction_css)]"
type="text/css" media="projection, screen, tv" />
   <!-- Feuille de styles CSS pour l'impression -->
   <link rel="stylesheet" href="[(#CHEMIN{impression.css}|direction_css)]"
type="text/css" media="print" />

----

   par :

----

   <INCLURE{fond=inc-head}{lang}>

----

Et d'ajouter dans /dist/ le fichier inc-head.html qui contiendrait ce qu'on
vient justement de remplacer (l'appel aux 3 feuilles de styles communes).

Large +1
(tout en ignorant l'impact sur les perfs)
Eventuellement ajouter à inc-head.html un parametre origine=article,sommaire ... ?
Mais peut-etre que la mécanique spip permet déjà de savoir d'où on vient ?

2. Pour répondre au second besoin des développeurs de plugins, ajouter dans
ce même fichier :

----

   #SPIP_HEAD

----

À mon avis, ça ouvre à toutes les possibilités... ou bien je suis
complètement dans le champ ?

Ca devrait être la direction ... j'aurais même imaginé:

#SPIP_PLUGINS_HEAD

Cette balise étant *uniquement* générée lors des activations / désactivations de plugins à partir de données précisées dans le plugin.xml en y rajoutant des tags, ou par le biais de fichiers aux noms standardisés du genre:
- plugin_head.html : les lignes à rajouter au <head> dont d'éventuels appels à des feuilles de style ou librairies js externes,
- plugin_head.css du style direct,
- plugin.js du javascript direct,
- ...
La génération prendrait soin d'encadrer chaque "fourniture" d'un plugin par des commentaires donnant l'id du plugin et de la "fourniture" puisque plusieurs plugins pourraient en avoir une en commun.
Cela pourrait générer , comme l'indiquait Fil un fichier en cache qui serait la somme de tout ça.
Les apports des plugins pourraient être des liens vers des fichiers css ou js ou des meta ou être du style ou du code js direct.

Et d'ailleurs , pourquoi pas imaginer que ces apports soient du squelette , cela permettrait aux plugins de "récupérer" certaines donnée du site lors de la génération.

Bon, j'arrête le délire :slight_smile:
à+

Pour resumer je vois 2 options techniques possibles :

- Une balise #SPIP_PUBLIC_HEAD qui n'est autre que la sortie d'un pipeline('spip_public_head',""). A charge pour chaque plugin de se brancher sur le pipe si besoin et d'y ajouter son contenu

    Avantage : Permet au plugin de gerer son contenu dynamiquement (attention quand meme : lors du calcul de page uniquement, les pages en cache ne provoquant pas d'appel au pipeline), par exemple en inserant des css ou js uniquement sur une page uniquement
    Inconvenient : Impact perf lors du calcul de page

- Une meta (pas de nouvelle balise !) spip_plugin_head, que l'on insere par #CONFIG{spip_plugin_head}, qui est statique et calculée a la config des plugins comme proposé par togg. Dans ce cas, le contenu est effectivement defini dans un tag <head></head> de plugin.xml

    Avantage : meta mise a jour via le panneau d'admin plugin lors de l'activation/desactivation, donc pas d'impact perfo lors du calcul de page
    Inconvenient : - Contenu statique identique sur tout le site. A charge pour le plugin de faire sa css ou son js sous forme de squelette pour gerer les cas dynamiques
                         - hum, le parser xml utilisé pour lire le fichier plugin.xml est assez simple. S'assurer qu'il va resister a tout ce qu'on mettra dans le <head></head>... Mais bon ca c'est de la plomberie

Pour des raisons de perfo, je sens plutot bien la seconde option, qui me parait pouvoir couvrir l'essentiel des besoins sans necessiter une ligne de code en plus pour le service des pages publiques.

Cedric

bertrand Gugger a écrit :

Pour des raisons de perfo, je sens plutot bien la seconde option, qui me
parait pouvoir couvrir l'essentiel des besoins sans necessiter une ligne
de code en plus pour le service des pages publiques.

Pourquoi penses-tu que ça coûterait cher ? On appelle trois ou quatre
filtres à la suite, ce n'est rien, et ça reste dans le modèle des autres
balises, plugins, etc. L'INCLURE est plus cher, en revanche.

Dans tous les cas il faut trouver un nom à ce système qui ne soit pas lié
aux plugins. Si par exemple les formulaires standards de SPIP deviennent un
jour gérés en ajax (ou ahah), il faudra bien un point d'entrée standard.

-- Fil

Fil wrote:

Pour des raisons de perfo, je sens plutot bien la seconde option, qui me parait pouvoir couvrir l'essentiel des besoins sans necessiter une ligne de code en plus pour le service des pages publiques.
   
Pourquoi penses-tu que ça coûterait cher ? On appelle trois ou quatre
filtres à la suite, ce n'est rien, et ça reste dans le modèle des autres
balises, plugins, etc. L'INCLURE est plus cher, en revanche.

Dans tous les cas il faut trouver un nom à ce système qui ne soit pas lié
aux plugins. Si par exemple les formulaires standards de SPIP deviennent un
jour gérés en ajax (ou ahah), il faudra bien un point d'entrée standard.

Quoiqu'il en soit , le point 1) regrouper les headers communs dans un <INCLURE{fond=inc-head}{lang}> me semble être un préalable quasi incontournable.
C'est du "userland" , je veux dire que ça peut rendre service à n'importe qui ... et que cette "centralisation" sera sans doute nécessaire à une gestion des besoins des plugins.

Je sais pas si ça restera à 3 ou 4 plugins tout ça ...

Pour resumer je vois 2 options techniques possibles :

- Une balise #SPIP_PUBLIC_HEAD qui n'est autre que la sortie d'un
pipeline('spip_public_head',""). A charge pour chaque plugin de se
brancher sur le pipe si besoin et d'y ajouter son contenu

Je vote pour ce principe

    Avantage : Permet au plugin de gerer son contenu dynamiquement
(attention quand meme : lors du calcul de page uniquement, les pages en
cache ne provoquant pas d'appel au pipeline), par exemple en inserant
des css ou js uniquement sur une page uniquement

Un exemple d'application est un détournement du filtre image_typo :
j'avais proposé un patch pour le rendre plus accessible : le principe
était de substituer le texte via CSS, et non pas de le remplacer
brutalement par l'image générée par le filtre. L'inconvénient est
qu'il faut déclarer l'image à utiliser par ma classe css, et pour que
ce soit propre, il faut le faire dans l'entete (on peut le mettre de
façon sale directement dans le contenu)

http://article.gmane.org/gmane.comp.web.spip.devel/33152

Mon patch était alors très moche, car il n'existe pas de point
d'entrée juste avant la mise en cache (il modifiait donc inc_calcul).

Emmanuel avait proposé une solution qui consistait à surcharger
public_localiser_page

http://article.gmane.org/gmane.comp.web.spip.devel/33816
http://trac.rezo.net/trac/spip/changeset/6061

Je n'ai pas eu le temps de tester la méthode, mais j'imagine que le
principe reste valable..

    Inconvenient : Impact perf lors du calcul de page

Ma modif' consistait à modifier la page juste avant de la stocker en
cache, et pas après l'avoir récupéré. Je pense que dans ce cas on ne
doit pas avoir de perte de perf, vu que la gestion du cache n'est pas
modifiée. A mon avis, c'est à cet endroit qu'il faut d'abord rajouter
un pipeline. Pour l'autre, je ne vois pas de cas d'utilisation, mais
là il peut en effet y avoir dégradation si le plugin est mal écrit ou
est trop lourd..

Mes 2 cents,

.Gilles

Fil wrote:

Beaucoup de plugins vont vouloir importer ou modifier du CSS ou du
javascript dans le <head></head> des pages HTML du site.

J'avais oublié de vous remercier !
Enfin on peut poser un my.css après les sacro saints de la dist.
Et du .js si on veut.

Je crois bien que j'ai loupé l'annonce.
Pas grave.