[spip-dev] Boutons administration et en-têtes "Content-Disposition: attachment"

Bonjour à tous,

Je crois que je suis tombé sur un os avec SPIP 3.0.5 [19905] et je me
demande s'il faut que je remplisse un ticket...

J'ai un squelette qui fabrique un XML à télécharger et qui débute ainsi:

#FILTRE{trim}
<BOUCLE_J(BIDULE){id_bidule}>
[(#HTTP_HEADER{Content-Disposition: attachment;
filename=[export_de_(#TITRE*|textebrut|replace{" ","_"}).xml];
Content-type: text/xml[; charset=(#CHARSET)]})]<?xml version="1.0"
encoding="UTF-8"?>

Mon but est d'éviter l'affichage dans le navigateur et de provoquer la
sauvegarde du XML généré par le squelette grâce à
"Content-Disposition: attachment"... Ça marche plutôt bien sauf que le
fichier sauvegardé contient le HTML correspondant aux boutons admin de
SPIP !
Comme les utilisateurs qui vont sauvegarder ce XML seront absolument
tous loggués, c'est très ennuyeux que mon XML soit invalidé par le
rajout du HTML des boutons admin.

Je pourrais bien sûr mettre un $flag_preserver = true pour tout le
site, mais je voudrais l'éviter, d'autant que la doc
(http://www.spip.net/fr_article1902.html) indique:

La balise #HTTP_HEADER{argument} (depuis SPIP 1.9) permet de modifier
l’entête HTTP de la page retournée par SPIP. Exemple :
#HTTP_HEADER{Content-Type: text/css}. Attention ! Le fait d’utiliser
cette balise supprime les boutons d’administration.

Et dans mon cas ça ne marche pas puisque le #HTTP_HEADER est présent
et que les boutons admin le sont aussi.

Ce qui est surprenant c'est que si j’enlève

Content-Disposition: attachment;
filename=[export_de_(#TITRE*|textebrut|replace{" ","_"}).xml];

du #HTTP_HEADER, les boutons admin ne sont plus présents dans la page
(mais elle s'affiche par contre dans le navigateur alors que je
voudrais que ce soit le formulaire de sauvegarde qui s'affiche). À
noter que si je les mets après "Content-Type" le header ne semble plus
envoyé du tout (la page est affichée comme du text/html)...

Bref on dirait qu'il faut que le header *commence* par "Content-type"
pour que $flag_preserver" soit à true pour la page (ce qui est
contradictoire avec: http://www.spip.net/fr_article4631.html qui
indique qu'on peut produire un CSV avec SPIP... Un CSV avec les
boutons admin risque de mal fonctionner)...

J'ai essayé de scruter un peu du côté d'ecrire/assembler.php et j'ai
constaté que dans le cas de mon squelette, $flag_preserver était à
false même après la ligne 116 qui contient:

$flag_preserver |= headers_sent();

je n'ai pas trop compris comment ça marche ni comment $flag_preserver
était mis à true quand il y a un header défini, puisque la fonction
qui semble gérer ça: auto_content_type est qualifiée de superflue dans
les commentaires... alors ça doit être géré ailleurs, mais j'ai pas
trouvé où !

Alors je me demandais si c'était un bug et si je faisais un ticket ???

En attendant très bonne fêtes à tous !

Essaye:

[(#HTTP_HEADER{Content-type: text/xml[; charset=(#CHARSET)]})]
#FILTRE{trim}
<BOUCLE_J(BIDULE){id_bidule}>
[(#HTTP_HEADER{Content-Disposition: attachment;
filename=[export_de_(#TITRE*|textebrut|replace{" ","_"}).xml];})]
<?xml version="1.0" encoding="UTF-8"?>
...

Salut,

Merci de ta réponse !

http://www.spip.net/fr_article4631.html#HTTP_HEADER précise "pas de html
avant cette balise"

Tu avis mis #FILTRE *avant* et j'ai supposé que cela impliquait
peut-être un début d'écriture de html avant...

Par ailleurs, j'ai séparé le contenu de la balise en deux... Je ne sais
pas pourquoi... Par habitude, je met le content-type en tête de fichier
squelette et j'ai constaté qu'ensuite les autres #HTTP_HEADER semblent
venir se concaténer au premier. Je ne sais pas si c'est un bonne pratique.

Mais je ne comprends absolument pas pourquoi ni comment !

#HTTP_HEADER - SPIP précise "pas de html
avant cette balise"

Tu avis mis #FILTRE *avant* et j'ai supposé que cela impliquait
peut-être un début d'écriture de html avant...

Oui, j'avais lu ça, mais justement, le filtre (trim) avait pour but
d'évier qu'il y ait un caractère avant (la fonction PHP trim retire
les espaces avant et après une chaîne)...

Donc je suis un peu surpris du comportement de SPIP sur ce coup...

Par ailleurs, j'ai séparé le contenu de la balise en deux... Je ne sais
pas pourquoi... Par habitude, je met le content-type en tête de fichier
squelette et j'ai constaté qu'ensuite les autres #HTTP_HEADER semblent
venir se concaténer au premier. Je ne sais pas si c'est un bonne pratique.

Ça aussi, ça me surprends... ce n'est documenté nulle part cette
histoire de concaténation...

Je trouve que c'est quand même un peu étrange le fonctionnement de
#HTTP_HEADER...

En tout cas merci de m'avoir sorti du pétrin ! :slight_smile:

#HTTP_HEADER fonctionne exactement comme la fonction php header http://php.net/manual/en/function.header.php
à savoir :
un seul header à chaque appel, qui se cumulent donc au final

Le problème était bien ici le fait que ton appel initial comportait plusieurs headers dans un même appel, ce qui produit un résultat invalide dont une partie est ignorée.

Cédric

Salut,