[spip-dev] du php évalué qu'une fois

L'idée avait été évoquée y'a un bail et je m'en suis servi comme
"travaux pratique" pour la doc du code, alors voila le patch, à discuter
(syntaxe et détails de comportement).

  Le principe est le suivant : si un squelette contient
<PHP>bla bla bla</PHP>, le "bla bla bla" est évalué lors de la mise en
cache d'une page.
  C'est à dire qu'on a du code php "normal" mis en vrac dans la
squelette compilé, mais lorsqu'on évalue une page pour la mettre en
cache, c'est le résultat de l'évaluation qui est stocké, au lieu d'être
évalué à chaque hit sur la page.

  Par exemple, si on veut faire une boucle sur des rubriques, dedans
une boucle sur des articles, et qu'on veut numéroter les articles :
<BOUCLE_r(RUBRIQUES){...}
  <BOUCLE_a(ARTICLES){id_rubrique}{...}>
    numero??? : #TITRE
  </BOUCLE_a>
</BOUCLE_r>

  On ne peut pas utiliser COMPTEUR_BOUCLE car il reviendra à 0 à chaque
tour de la boucle rubriques, il faut donc faire un truc du genre
<? $cpt=1; ?> avant la boucle rubriques et un <? echo $cpt++; ?>
  Mais du coup, ce code est évalué à chaque hit sur la page (qui est
alors estampillée "php" alors qu'elle pourrait être estampillée "html"
sinon).

avec le patch ci joint, on peut écrire ça :
<PHP>$cpt=1;</PHP>
<BOUCLE_r(RUBRIQUES){...}
  <BOUCLE_a(ARTICLES){id_rubrique}{...}>
    <PHP>return $cpt++;</PHP> : #TITRE
  </BOUCLE_a>
</BOUCLE_r>

  Lorsqu'on met en cache la page (ou si on la recalcule), ce code
php est évalué et ce sont les résultats de ces évaluations qui sont
mises en cache, ce qui signifie qu'il n'y a plus de php d'évalué lorsque
récupèrer la page en cache.

  Remarquez le "return" à la place du "echo". On pourrait améliorer le
code en bidouillant à coups de ob_*, mais c'est à discuter car ça ajoute
pas mal de code pour peut-être pas grand chose.

  Reste également à acter une syntaxe (est-ce que <PHP> risque de se
croiser dans des squelettes existants ???) et à voir comment gérer le
statut php/html (j'ai pas trop compris comment ça marchait ce point :
quel est le lien entre les $p->statut=html/php et les process_ins ?)
apparemment, ça se comporte normalement, mais j'suis pas sur de mon coup.

codephp.patch (2.77 KB)

Je ne comprends pas l'intention.

1. si on veut mettre en cache un résultat de PHP, on définit un filtre qu'on applique sur qqch (au pire #NOM_SITE_SPIP, toujours disponible) et on rentre dans le cadre général, pas besoin de rajouter du code.

2. Spip accepte des <?php ... ?> dans les squelettes principalement lorsqu'on veut authentifier le demandeur et on veut le faire justement à chaque requete, donc hors de question de le mettre en cache.

3. Spip en insère aussi pour les includes, et l'idée est de permettre des inclusions de code à délai différents, donc il faut executer à chaque requete

Il y a de rares cas où on interpole du PHP pour d'autres raisons (par exemple des headers qu'on ne peut mettre dans le script homonyme du squelette parce qu'ils dépendent de pleins de choses dans le squelette) mais de mon point de vue ce sont des scories à évacuer par d'autres moyens (par exemple une balise #DELAI que le compilo traiterait à la manière de #SPIP_CRON).

Maintenant, c'est mon opinion et je la partage ;-).

Déesse A.

1. si on veut mettre en cache un résultat de PHP, on définit un
filtre qu'on applique sur qqch (au pire #NOM_SITE_SPIP, toujours
disponible) et on rentre dans le cadre général, pas besoin de
rajouter du code.

C'est tjours possible, certes, mais parfois pour faire un truc vite fait la
proposition de Piif serait plus facile : pas besoin d'éditer un fichier
externe (mes_fonctions) au squelette pour y ajouter du code. Tu places donc
le code à l'endroit où tu développes, ça permet d'aller vite et d'obtenir
des résultats visuellement plus "évidents".

3. Spip en insère aussi pour les includes, et l'idée est de permettre
des inclusions de code à délai différents, donc il faut executer à
chaque requete

Là dessus je crois qu'il serait pas mal d'avoir un autre type d'inclusion,
qui inclue "un squelette" directement à la compilation.

Par exemple tu pourrais avoir

header.html :
        <title>#TITRE</title>

et dans le squelette article.html
        <BOUCLE_a(ARTICLES){...}>
                INCLURE_NEW_STYLE(header.html)
        </BOUCLE_a>

et dans rubrique.html
        <BOUCLE_a(RUBRIQUES){...}>
                INCLURE_NEW_STYLE(header.html)
        </BOUCLE_a>

là évidemment le squelette serait inclus par le phraseur.

Maintenant, c'est mon opinion et je la partage ;-).

Cette question du tag <PHP> est un vieux serpent de mer ; je crois que ça
faciliterait la prise en mains de SPIP par certains. Cependant il faut faire
attention à ce qui se passe si on fait un critère du type {titre=<PHP>du
code</PHP>} : qu'est-ce-qui s'exécute en premier ?

-- Fil

1. si on veut mettre en cache un résultat de PHP, on définit un
filtre qu'on applique sur qqch (au pire #NOM_SITE_SPIP, toujours
disponible) et on rentre dans le cadre général, pas besoin de
rajouter du code.

C'est tjours possible, certes, mais parfois pour faire un truc vite fait

S'il s'agit de "vite fait", la question des performances ne se pose pas. Si elle se pose, alors on prend le temps de faire qqch de propre, c'est à dire un fichier html et un fichier php par squelette.

3. Spip en insère aussi pour les includes, et l'idée est de permettre
des inclusions de code à délai différents, donc il faut executer à
chaque requete

Là dessus je crois qu'il serait pas mal d'avoir un autre type d'inclusion,
qui inclue "un squelette" directement à la compilation.

C'est ce que j'avais fait à une certaine époque, sans syntaxe supplémentaire: au moment de l'inclusion, si l'incluant à un délai plus court que l'inclus, il est légitime d'inclure en ligne. On en a des vestiges avec les différents "$delais" dont Pif se plaint à juste titre dans son autre mail. Il faudrait reprendre tout ça.

Déesse A.

Mais, vite fait ou pas, je ne vois pas comment coder proprement un
compteur à cheval sur plusieurs boucles comme expliqué dans l'exemple,
à moins de créer des balises #COMPTEUR{nom} et [(#COMPTEUR{nom}|plusun)]
ou un machin tout moche de ce genre, là ou un bête $i++ fait l'affaire.

S'il s'agit de "vite fait", la question des performances ne se pose
pas. Si elle se pose, alors on prend le temps de faire qqch de
propre, c'est à dire un fichier html et un fichier php par squelette.

  Mais, vite fait ou pas, je ne vois pas comment coder proprement un
compteur à cheval sur plusieurs boucles

Avec un filtre comportant une variable statique.

comme expliqué dans l'exemple,
à moins de créer des balises #COMPTEUR{nom} et [(#COMPTEUR{nom}|plusun)]
ou un machin tout moche de ce genre, là ou un bête $i++ fait l'affaire.

et si tu inclus un squelette qui a lui aussi un bete $i++ tu verras que ça ne fera pas l'affaire.

Déesse A.

> Mais, vite fait ou pas, je ne vois pas comment coder proprement un
> compteur à cheval sur plusieurs boucles

Avec un filtre comportant une variable statique.

  Ouais, en gros c'est ce que je dis en dessous, avec en plus
l'obligation d'appeler ce filtre via une balise pipo, ce qui est quand
même mochissime.

> comme expliqué dans l'exemple,
> à moins de créer des balises #COMPTEUR{nom} et [(#COMPTEUR{nom}|
> plusun)]
> ou un machin tout moche de ce genre, là ou un bête $i++ fait
> l'affaire.

et si tu inclus un squelette qui a lui aussi un bete $i++ tu verras
que ça ne fera pas l'affaire.

Heu ouais, mais bon, si l'autre $i c'est le compteur pour un autre cas,
ta variable statique, il va lui arriver pile poil la même chose :slight_smile:

  Bref, sérieusement, admettons (d'ailleurs je l'ai jamais prétendu) que
ça ne soit pas la solution ultime à tous les maux de la terre :wink:
  Disons que ça reste donc ce que c'était au départ, c'est à dire un TP
d'application de ça : http://www.spip-contrib.net/spikini/ccmPhraseur

  Si ça botte des gens, je prendrais p'tet le temps d'en faire une
contrib.