Indenter du code Html

Répondre


Cette question est un moyen d’empêcher des soumissions automatisées de formulaires par des robots.
Smileys
:D :) :( :o :shock: :? 8-) :lol: :x :P :oops: :cry: :evil: :twisted: :roll: :wink: :!: :?: :idea: :arrow: :| :mrgreen: =D> #-o =P~ :^o :non: :priere: 8-|
Voir plus de smileys
  Revue du sujet
 

  Étendre la vue Revue du sujet : Indenter du code Html

par FredoMkb » 05 juin 2007, 23:22

Re...

Merci de vos contributions, je tiens compte de vos remarques et avis, rien n'est arrêté pour l'instant dans mon projet, il y a donc des choses qui vont certainement évoluer, cette question sur l'indentation du code faisant peut-être partie...

Merci... à+ :)

par Hywan » 05 juin 2007, 18:50

J'ose intervenir. L'avis que je vais développé ci-dessous est le mien, et n'engage que moi.

Déjà un petit détail, mais ça m'énerve tellement que je vais le mettre d'entrer de jeu :
$var = '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"'."\n".
       '                      "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">'."\n\n".
       '<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="fr">'."\n".
       '<head>'."\n".
       '  <title>Page principale &mdash; Mon site.</title>'."\n".
       '</head>'."\n".
       '<body>'."\n".
       '  <h1>Titre</h1>'."\n".
       '  <p>Paragraphe.</p>'."\n".
       '</body>'."\n".
       '</html>';
C'est quand même beaucoup plus propre que d'écrire $var à chaque début de lignes ...
Ca fait des caractères en moins, c'est plus beau, c'est plus léger, enfin bref : on n'a que des avantages.

Et c'est beaucoup plus simple d'écrire ton indentation directement comme ça, plutôt qu'avec une fonction ou je ne sais quoi d'autres.

Si tu ne travailles que pour un seul et unique gabarit (template), tu ne te poses la question, sinon ça devient compliqué.

Voilà comment je raisonne :
Quand je construis le site, j'ai une page index.php qui va inclure les autres pages. Le code de la page index.php est indenté à la main (directement dans le code PHP ou alors à travers un gabarit, peu importe). On va appeler pour la suite la balise <_inc>, la balise qui contient la page incluse (ça peut être <body> elle-même, <div> ou autres).

Pour expliquer la suite, on doit d'abord se poser la question : pourquoi on indente le code HTML ? C'est principalement pour ceux qui veulent le lire. Donc la partie la plus important est la balise <_inc> on est bien d'accord. Donc j'écris 1 ou 2 lignes vide après l'ouverture de la balise <_inc>, je remets l'indentation à 0 pour les pages qui sont incluses (dans la balise <_inc> de la page index.php), et je termine par 1 ou 2 lignes vides avant la fermeture de la balise <_inc>.

De cette façon, quand je développe un module, je sais exactement où j'en suis, car je n'ai pas à me soucier de l'indentation de la page index.php. De plus, le code reste très lisible, car la balise <_inc> étant la plus importante, c'est pas mal de remettre l'indentation à 0 surtout si on travaille avec des tabulations et non des espaces (si on est au 17e noeud pour l'inclusion du texte, le nombre d'indentation sera trop élevé, et le code ne sera pas facile à lire).


Ca c'est ma technique. Si tu veux absolument faire un script, tu peux utiliser la méthode développée plus bas. Mais ce n'est pas très malin de développer ton propre script. Pourquoi ? Déjà parce qu'on peut le faire à la main/en dur, et que le résultat est très propre. De plus, utiliser un script juste pour ça, ça va prendre du temps, et de la ressource pour « rien ». Je n'aime pas dire pour « rien », car c'est important pour moi, mais ce n'est pas l'avis général ...

Donc il ne faudrait pas développer ton propre script, mais utiliser un module C de PHP par exemple.
Lequel choisir ? Sablotron le fait très bien. Certes cela concerne XSLT, mais tu peux lui demander d'appliquer une feuille XSLT vide, et il va réécrire (réindenter plutôt) le code pour toi.
Ca reste de la grosse bidouille quand même, mais comme c'est un module écrit en C, ça reste toujours plus rapide que ton propre script PHP. Je précise que Sablotron est installé par défaut sur pratiquement tous les hébergeurs. EasyPHP ne le supporte pas (pour les versions <= 1.8 de sûr, au-dessus, je ne sais pas), mais son installation est rapide et simple.


Je te conseille tout de même d'appliquer ma première méthode, à savoir remettre l'indentation à 0 et l'écrire à la main. C'est celle qui reste la plus « triviale ».

Bonne journée.

par Ripat » 05 juin 2007, 18:47

Je plussoie Xénon et Zeus. Indenter la sortie html en prod ne sert qu'à consommer du temps CPU, de la mémoire et surtout de la bande passante. Des espaces inutiles, ça pèse son poids.

Vous avez déjà regardé le code html d'une page Google? Tout est sur une seule et (très) longue ligne.

Maintenant si tu te sers de tes pages à des fins pédagogiques, c'est une autre histoire.

par Sékiltoyai » 05 juin 2007, 17:26

En fait, si j'ai bien compris, cette fonction met le code généré en cache (ou en tampon), afin de pouvoir faire des traitements avant l'envoi final vers le navigateur, c'est bien ça ?
Oui, en gros, c'est un dispositif qui te permet de gérer le buffer de sortie. Quand tu fais des echo, la plupart du temps, les chaines sont directement envoyées au navigateur. avec ces fonctions, tu peux contrôler le buffer pour faire des modifications sur les chaines avant de les envoyer vers le navigateur, par exemple pour activer la compression.

Pour l'indentation, en fait, c'est vrai que c'est compliqué, puisqu'il faut coder un automate, mais un début d'algorithme serait du genre :

Code : Tout sélectionner

Initialisation : buffer = '' tabs = 0 indent(str) : str = buffer+str buffer = '' i = rechercher dans la chaine str le caractère '<' si on trouve dans la chaine str une chaine vérifiant <machin truc="machin" truc2="machin2"> commencant à la position i et finissant à la position p alors ajouter tabs tabulation à la position i tabs = tabs+1 sinon si on trouve dans la chaine str une chaine vérifiant </machin> commencant à la position i et finissant à la position p alors tabs = tabs-1 ajouter tabs tabulation à la position i sinon si on atteint la fin de la chaine str alors buffer = couper de la position i à la fin de la chaine str finsi retourner str finscript() : retourner buffer
En gros on incrément tabs à chaque balise ouvrante, on le décrémente à chaque balise fermante, et si on tombe sur la fin, on enregistre la fin de la chaine, parce qu'on est peut être tombé sur une balise incomplète, et il suffit ensuite de concaténer avec le reste de la chaine au prochain affichage (on peut déclencher l'affichage périodiquement...). Et à la fin du script, on affiche le buffer.

Mais après selon l'utilisation que l'on fait du buffer, on peut simplifier le truc en considérant qu'on affichera tout en une seule fois, et donc qu'on n'aura jamais une balise coupée, ou ce genre de choses...

par FredoMkb » 05 juin 2007, 11:35

Re...
Disons que le code HTML généré doit, selon moi, uniquement être destiné à être envoyé sur le navigateur.

Tout les développeurs peuvent voir le code HTML depuis les sources PHP. C'est donc ici qu'elles doivent être bien formatées.
Ok, sur le principe je suis d'accord avec toi, sauf que, dans la pratique, le code Html se trouve souvent bien éparpillé dans les fichier Php et, même pour certains développeur plus expérimentés que moi, il est parfois difficile de voir exactement le code Html produit par le script rien qu'en regardant son code Php...

Du coup, il est souvent nécessaire de visualiser le code Html sur une sortie de prévisualisation afin de bien comprendre comment est structuré l'ensemble... bref, c'est en tout cas comme-ça que je fonctionne lorsque la structure du code Html n'est pas évidente à première vue...
Sinon, si tu veux indenter le code automatiquement sans te faire chier, tu peux utiliser ob_start() avec une fonction de callback qui détecte les balises et qui indente le code html juste avant l'affichage...
Merci pour cette piste, que je ne connaissais pas...

En fait, si j'ai bien compris, cette fonction met le code généré en cache (ou en tampon), afin de pouvoir faire des traitements avant l'envoi final vers le navigateur, c'est bien ça ?

Si c'est le cas, ça peut en effet être intéressant, mais ça ne résoud pas pour autant le problème de l'indentation en elle-même, ce n'est pas évident d'imaginer une méthode simple et efficace pour indenter le code Html une fois généré, en tout cas pour moi...

Bref, je vais étudier cette piste et voir si elle peut me rendre service...

Merci... à+ :)

par Sékiltoyai » 05 juin 2007, 11:03

Sinon, si tu veux indenter le code automatiquement sans te faire chier, tu peux utiliser ob_start() avec une fonction de callback qui détecte les balises et qui indente le code html juste avant l'affichage...

par zeus » 05 juin 2007, 10:42

Disons que le code HTML généré doit, selon moi, uniquement être destiné à être envoyé sur le navigateur.

Tout les développeurs peuvent voir le code HTML depuis les sources PHP. C'est donc ici qu'elles doivent être bien formatées.

Sinon, ce que j'utilise moi pour avoir un code HTML correctement indenté, c'est soit les templates, soit l'imbrication PHP/HTML.
exemple :
<html>
  <head>
    <title>ma page indentée</title>
  </head>
  <body>
<?php
  for ($i = 0 ; $i < 10 ; $i++)
  {
?>
    <p>Le numéro courant est le <?= $i ?></p>
<?php
  }
?>
  </body>
</html>
Dans le cas de code HTML simple, c'est assez pratique. Dès qu'il commence à y avoir plus de complexité, le système des templates devient plus simple à utiliser ;)

par FredoMkb » 05 juin 2007, 09:40

Bonjour à tous :)
À part avoir la conscience tranquille ou faciliter ton debug, indenter ton code en sortie ne servira à strictement rien. (à l'exception d'utiliser du temps processeur pour rien)
Depuis le début du thread, j'hésite à le dire. :D
Pourriez-vous développer un peu Svp ?

Le projet sur lequel je travail est destiné, à priori, à des personnes ayant très peu d'expérience avec les langages tels que le Html, je souhaite donc produire un code relativement "propre" ou, à défaut, le plus lisible possible, et l'indentation participe fortement à la lisibilité du code, surtout pour ceux qui ne sont pas familiers avec ce langage.

Quant à "utiliser du temps processeur pour rien", je ne pense pas que prendre un peu de soin à produire un code lisible soit une utilisation stérile du temps processeur... ceci-dit, je n'ai pas encore testé ma solution sur des pages très longues et/ou complexes, il se peut donc que cette méthode d'indentation soit pénalisante sur des données importantes, je ne sais pas, pour l'heure, ça fonctionne plutôt bien et je n'ai pas constaté de ralentissement sensible...
phpBB utilise un système de templates pour l'affichage du HTML. L'indentation est donc directement dans ces fichiers.
J'ai aussi exploré un peu l'utilisation des modèles dans mon projet, d'ailleurs, dans une certaine mesure je m'en sert aussi, mais ceux-ci posent certains problèmes d'indentation lorsqu'on se trouve avec des imbrications successives... bon, rien de bien grave en réalité, mais avec ma méthode j'ai réussi à corriger un peu cette limitation...

Enfin, j'avoue que je ne suis qu'au tout début de mon projet, j'ai encore beaucoup de développement à faire, et il se peut que, à terme, je finisse par abandonner mon idée d'indentation systhèmatique du code, surtout si ça devient trop pénalisant côté performances, et préférer alors un système de modèles mieux conçu et certainement moins gourmand en ressources processeur.

Merci pour vos contributions... à+ :)

par zeus » 05 juin 2007, 08:20

À part avoir la conscience tranquille ou faciliter ton debug, indenter ton code en sortie ne servira à strictement rien. (à l'exception d'utiliser du temps processeur pour rien)
Depuis le début du thread, j'hésite à le dire. :D

Merci Xenon_54

par Xenon_54 » 05 juin 2007, 02:25

À part avoir la conscience tranquille ou faciliter ton debug, indenter ton code en sortie ne servira à strictement rien. (à l'exception d'utiliser du temps processeur pour rien)

phpBB utilise un système de templates pour l'affichage du HTML. L'indentation est donc directement dans ces fichiers.

Exemple bidon utilisant la syntaxe de phpBB:

Code : Tout sélectionner

<h1><a href="forums.php">Les forums</a></h1> <dl class="forums-list"> <!-- BEGIN forums --> <dt>{forums.NAME}</dt> <dd>{forums.DESCRIPTION}</dd> <!-- END forums --> </dl>

par FredoMkb » 04 juin 2007, 19:17

Re...
Euh.... question bête sans doute mais... pourquoi ne pas mettre directement ton indentation dans tes chaines ???
pour compléter la réponse :

les caractères d'indentation et des retours ligne sont interpretés dans les chaines, que ce soit entre apostrophes, guillemets ou heredoc.....
Ok, ta question n'est pas bête Ryle, et ton intervention est tout-à-fait justifiée aussi Jules, seulement, l'exemple que j'ai présenté avait pour seul but de montrer la méthode utilisée, mais il n'illustre pas, en effet, les conditions dans lesquelles cette solution pourrait être utile.

En fait, on peut constater, sur pas mal de scripts de gestion de sites dynamiques, comme des forums par exemple (PunBb, PhpBb, etc.) et d'autres produits de ce type, que les pages Html son construites par des fichiers Php dédiés.

Seulement, dans ces fichiers, le code Html n'est pas construit de manière aussi simple et linéaire que mon exemple, au contraire, le plus souvent la construciton du code Html est fait par étapes succèssives, entrecoupées par des tests, analyses et autre traitements, afin que le code Html suivant corresponde à un contexte défini ou réponde à certaines variables.

Bref, pour schématiser la chose, ça ressemblerait à quelque chose comme :

Code : Tout sélectionner

-> Début du code Html -> Analyse du contexte -> Si tel contexte, un bout de code Html -> Si un autre contexte, un autre bout de code Html -> Suite du code Html -> Test sur un variable -> Si la variable est égale à une valeur précise, un bout de code Html -> Sinon, un bout de code Html différent -> etc.
Or, dans ces conditions de développement, où les étatpes d'analyse et traitement intermédiaires peuvent parfois être assez limportantes et longues, on y perd vite le nombre de "\t" à mettre devant certains codes pour assurer une identation correcte de la page Html produite.

Donc, les pistes que vous évoquez, bien que tout-à-fait fonctionnelles, s'appliquent assez mal ou, du moins, de manière assez laborieuse dans ce type de conditions de développement.

Lors de mes recherches, j'ai commencé par utiliser une solution facultative, qui constait à mettre des "str_repeat("\t", 3);" devant chaque nouvelle ligne de code.

Seulement, dans la pratique, je retrouvais les mêmes difficultés qu'en mettant les tabulations directement dans le code Html, car je devais remonter sans cesse dans mon fichier Php pour bien m'assurer du nombre de "\t" que j'avais mis plus tôt, et ça devenait rapidement fastidieux.

Donc, dans le but de faciliter le développement tout en assurant un code Html relativement bien indenté, j'ai imaginé une solution qui fonctionnerait par addition ou soustraction d'une valeur statique, afin d'y placer le bon nombre de tabulations dans un traitement final, juste avant l'affichage de la page Html.

Le but n'étant évidemment pas de me compliquer inutilement la vie ou de ralentir bêtement la construction des pages avec des solutions accrobatiques, mais plutôt de rendre le développement plus pratique tout en assurant un code Html pas trop moche.

Voilà... je ne sais pas si mes explications sont assez claires, et je ne sais pas non plus si cette solution sera pertinante à long terme, en tout cas, pour l'instant, elle fonctionne plutôt bien, et rend le travail sur des longs fichier Php beaucoup plus aisé...

Merci à tous... à+ :)

par Jules Petibidon » 04 juin 2007, 15:38

hello,

pour compléter la réponse :

les caractères d'indentation et des retours ligne sont interpretés dans les chaines, que ce soit entre apostrophes, guillemets ou heredoc.
echo 'toto
	pouet
tutu';
regarde le résultat HTML, l'indentation est conservée, les sauts de ligne aussi.

une astuce consiste à écrire son HTML proprement, puis ensuite le découper selon les besoins pour l'intégrer au PHP. Heredoc est une solution idéale pour faire cela sans se prendre la tête avec les guillemets et apostrophes divers.

par Ryle » 04 juin 2007, 15:02

Euh.... question bête sans doute mais... pourquoi ne pas mettre directement ton indentation dans tes chaines ??? Quitte à te prendre la tête à gérer des alignement à coup de +1/-1, ca rendrait ton code php bien plus lisible et ca te ferait moins de traitement pour un même résultat
au lieu de :
$doc = '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN">'."\n"; 
$doc .= '<html>'."\n"; 
$doc .= com(1).'<head>'."\n"; 
$doc .= com(1).'<title>Test Html2Php</title>'."\n"; 
$doc .= com(0).'<link rel="stylesheet" type="text/css" href="h2p_styles.css">'."\n"; 
$doc .= com(-1).'</head>'."\n"; 
$doc .= com(0).'<body>'."\n"; 
$doc .= com(1).'<div>'."\n"; 
$doc .= com(1).'<p>Bonjour monde :-)</p>'."\n"; 
$doc .= com(0).'<p>Petit test de fonction d\'identation semi-auto...</p>'."\n"; 
$doc .= com(-1).'</div>'."\n"; 
$doc .= com(-1).'</body>'."\n"; 
$doc .= com(-1).'</html>'; 
Si tu faisais :
$doc = '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN">'."\n"; 
$doc.= '<html>'."\n"; 
$doc.= '  <head>'."\n"; 
$doc.= '    <title>Test Html2Php</title>'."\n"; 
$doc.= '    <link rel="stylesheet" type="text/css" href="h2p_styles.css">'."\n"; 
$doc.= '  </head>'."\n"; 
$doc.= '  <body>'."\n"; 
$doc.= '    <div>'."\n"; 
$doc.= '      <p>Bonjour monde :-)</p>'."\n"; 
$doc.= '      <p>Petit test de fonction d\'identation semi-auto...</p>'."\n"; 
$doc.= '    </div>'."\n"; 
$doc.= '  </body>'."\n"; 
$doc.= '</html>'; 
Tu obtiendrais la même chose... Et à la limite, vu l'exemple si tu n'as pas d'utilisation particulière de php, tu aurais tout intérêt à fermer les balises php pour afficher directement le code html...

par FredoMkb » 04 juin 2007, 13:32

Bonjour à tous :)
Non je fais tout à la main.
Ha d'accord... le but est justement d'éviter de le faire à la mano... surtout lorsque le code se complique un peu...
L'outil Tidy peut indenter ton code source :D
Oui je sais, mais comme je le disais dans mon premier post, la technologie Tidy, bien que très séduisante et visiblement très puissante, elle pose néanmoins un problème de compatibilité, puisqu'elle n'est pas installée par défaut sur tous les serveurs...

Sinon, après quelques recherches infructueuses, j'ai finalement trouvé une solution semi-auto d'identation, qui évite de mettre les espace ou tabulations à la main, mais qui oblige de construire toute la page Html avant de l'afficher, ce qui peut être gênant dans certaines conditions...

Enfin, pour ceux que ça intéresse, voici la solution que j'ai trouvé :

Le principe est simple, lors de la construction du code Html, on met un commentaire à chaque début de ligne qui devra être indentée, commentaire contenant un nombre qui sera ensuite traité par une fonction qui remplacera tous ces commentaires par des tabulations.

Voici un code d'exemple pour mieux visualiser la chose :
<?php
// Variable statique permettant de calculer le nombre de tabulations a inserer
static $tabsNbr;
$tabsNbr = 0;

// Construction du document Html
$doc = '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN">'."\n";
$doc .= '<html>'."\n";
$doc .= com(1).'<head>'."\n";
$doc .= com(1).'<title>Test Html2Php</title>'."\n";
$doc .= com(0).'<link rel="stylesheet" type="text/css" href="h2p_styles.css">'."\n";
$doc .= com(-1).'</head>'."\n";
$doc .= com(0).'<body>'."\n";
$doc .= com(1).'<div>'."\n";
$doc .= com(1).'<p>Bonjour monde :-)</p>'."\n";
$doc .= com(0).'<p>Petit test de fonction d\'identation semi-auto...</p>'."\n";
$doc .= com(-1).'</div>'."\n";
$doc .= com(-1).'</body>'."\n";
$doc .= com(-1).'</html>';

// Des le document construit, on indente le code suivant les commentaires inseres
$doc = indent($doc);
echo $doc;

// Fonction pour inserer des commentaires servant a l'identation
function com($nro) {
	return '<!--|'.$nro.'|-->';
}
// Fonction rechercher/remplacer des commentaires d'identation par des tabulations
function indent($data) {
	return preg_replace('#(<!--\|-?\d\|-->)#e', 'tabs(\'$1\')', $data);
}
// Fonction retournant des tabulations selon un calcul sur la variable statique
function tabs($data) {
	global $tabsNbr;
	$tabsNbr += str_replace(array('<!--|','|-->'), array('',''), $data);
	return str_repeat("\t", $tabsNbr);
}
?>
Donc, grosso modo, sur chaque nouvelle ligne de code, on place un commentaire, avec la fonction "com(1)", contenant un chiffre "1" sur les balises ouvrantes qui doivent être indentés.

Pour les balises ouvrantes situées au même niveau que la balise précédente, on place un commentaire avec un chiffre "0" (zéro), car ils ne doivent pas être indentés d'avantage.

Enfin, sur les balises fermantes présentes sur une nouvelle ligne, on place un commentaire avec un chiffre négatif "-1", l'indentation devant être inférieure à celle de la balise précédente.

Alors, sans le traitement de la fonction d'identation "indent($doc)", le code Html du document (c'est à dire le contenu de la variable "$doc") donnerait ceci :

Code : Tout sélectionner

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"> <html> <!--|1|--><head> <!--|1|--><title>Test Html2Php</title> <!--|0|--><link rel="stylesheet" type="text/css" href="h2p_styles.css"> <!--|-1|--></head> <!--|0|--><body> <!--|1|--><div> <!--|1|--><p>Bonjour monde :-)</p> <!--|0|--><p>Petit test de fonction d'identation semi-auto...</p> <!--|-1|--></div> <!--|-1|--></body> <!--|-1|--></html>
En revanche, avec le traitement de la fonction d'identation "indent($doc)", le code Html du document donne ceci :

Code : Tout sélectionner

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"> <html> <head> <title>Test Html2Php</title> <link rel="stylesheet" type="text/css" href="h2p_styles.css"> </head> <body> <div> <p>Bonjour monde :-)</p> <p>Petit test de fonction d'identation semi-auto...</p> </div> </body> </html>
Voilà... je ne sais pas si cette solution (bidouille devrais-je dire plutôt :shock: ) pourra servir à d'autres personnes, en tout cas, pour mon projet, ça me permet d'afficher des pages Html relativement bien indentés, même si ça demande de construire l'ensemble du code Html pour pouvoir l'indenter...

Bref, sans être parfaite, cette astuce me rend quand-même bien service...

Merci à tous... à+ :)

Re: Indenter du code Html

par albat » 04 juin 2007, 13:21

Ben oui, il le sait déjà... ;)
J'ai déjà vu que la technologie Tidy serait une des solutions les plus indiquées,
sauf que ce n'est pas installé par défaut sur tous les serveurs,
et que je souhaite rester le plus compatible possible...