MOTEUR DE TEMPLATE PHP5

Messages postés
373
Date d'inscription
samedi 9 juillet 2005
Statut
Membre
Dernière intervention
11 août 2008
- - Dernière réponse : cs_garfield90
Messages postés
389
Date d'inscription
lundi 7 juillet 2003
Statut
Webmaster
Dernière intervention
10 février 2009
- 21 avril 2008 à 22:01
Cette discussion concerne un article du site. Pour la consulter dans son contexte d'origine, cliquez sur le lien ci-dessous.

https://codes-sources.commentcamarche.net/source/45263-moteur-de-template-php5

cs_garfield90
Messages postés
389
Date d'inscription
lundi 7 juillet 2003
Statut
Webmaster
Dernière intervention
10 février 2009
-
errata :

sur mon dernier post, le code est plutot :
$i = 0 ;
if ( mysql_num_row($dbResult) > 0 ){
// on a plusieurs resultats
$cTSql = array();
while ( $row = mysql_fetch_array($dbResult) || $i < 10 ){
$oTSql = new ND_Template;
$oTSql->setContent('<tr><td>#sql.id#</td><td>#sql.nom#</td><td>#sql.prenom#</td><td>#sql.role#</td></tr>'); // erreur ici
$oTSql->addValue('sql', $row );
$cTSql[] = $oTSql ;
$i++;
}
}else{
// on n'a aucun résultat
$cTsql = '<tr><td>aucun contenu</td></tr>';
}
$oTPrincipal = new ND_template;
$oTPrincipal->setTemplateFile('tpl/tableau.tpl'); // contenu de tableau.tpl ('#content#
')
$oTPrincipal->addValue('content', $cTSql); // erreur présente ici également

Ca m'apprendra a poster quand on est HS :D
cs_garfield90
Messages postés
389
Date d'inscription
lundi 7 juillet 2003
Statut
Webmaster
Dernière intervention
10 février 2009
-
Concernant la doc, c'est pas tellement que c'est complexe... C'est juste qu'il faut se plonger dans le code source pour savoir ce qu'on peut faire, avec quoi et comment. C'est juste plus long, faut aussi comprendre comment t'as vu les choses en écrivant cette classe, etc. Disons que pour quelqu'un qui veut juste utiliser le moteur de template, c'est pas évident... Y'a pas besoin de grand chose pour expliquer en 2 ou 3 lignes l'intérêt et le fonctionnement des méthodes publiques.
=> la doc a été faite, si tu as des choses a dire, expliquer n'hésites pas

Pour l'assignation de variables, que tu aies fait ça pour le fun ou pas, il n'en demeure pas moins que c'est pas hyper pratique... Encore que... j'ai du mal à bien piger comment ça marche, parce que là, dans ton exemple, tu utilises addGlobal pour assigner un tableau... Alors je suis perdu... et un peu de doc m'aiderait, là, en fait ;)
=> Je n'ai pas vu en quoi c'est pas hyper pratique car tu peux utiliser des tableaux voire des objets, et donc ainsi gérer plusieurs variables d'un coup (via notation pointé [tableau.clé] ou doublement pointé [objet..propriété] ), mais bon je connais mon moteur par coeur, j'ai donc pas forcement le recul nécessaire :S

PCRE : ok... Effectivement, pour supprimer les variables restantes non assignées... Moi, je suis parti du principe que s'il reste des variables, c'est qu'elles n'ont pas été correctement gérées.
=> Je suis pas forcement d'accord avec toi, si tu utilises un (sous-template) utilisées par 2 pages et/ou une variable du template ne doit être affiché que dans un certain cas, ca t'évites de faire 2 templates sensiblement identiques.

return $this => linker les méthodes... Ouais, admettons. C'est vrai que c'est pratique. Mais d'un point de vue sémantique, ça me chiffone un peu, quand même...
=> J'ai suivi en grande partie la nomenclature du Zend Framework, il l'utilise énormement, et quand tu y a gouté tu n'arretes pas. Ca evite une verbosité génante quand tu assignes beaucoup d'entrées

Pour clear() : c'est ce que je viens d'implémenter dans la v0.4 de ma classe (pas encore en ligne). Moi, je trouve ça très pratique. Soit je passe une variable en argument, il la supprime, soit je ne passe rien, il supprime tout.
=> J'ai normalement le meme fonctionnement, mais le fait d'avoir 2 portées différentes (local / global), fait que mon clear est un peu plus complexe. En inversant l'ordre des variables, ca devrait etre plus simple.

Faut dire, on n'a pas la même approche des variables de template locales et globales. Dans ma classe, les variables assignées à l'objet sont globales (du fait que je n'ai pas besoin d'avoir plusieurs instances pour bosser sur plusieurs templates). Les variables locales ne sont pas sauvegardées et directement utilisées lorsque le template est parsé. Du coup, les seules variables que j'ai a supprimer, ce sont les globales. J'ai la même approche que la portée des variables dans les fonctions en PHP : celles qui sont définies dans une fonction ne sont pas accessible en dehors. C'est moins lourd aussi, parce que si j'ai beaucoup beaucoup de variables, celles qui ne sont utilisées qu'une seule fois dans un template (qui peut ne pas être utilisé, donc soumis à condition) ne sont pas stockées en mémoire.
=> En fait ma notion de variables globales est venues d'un besoin, l'internationalisation en particulier ou certaines variables devaient etre passées a plusieurs templates.


Enfin, concernant l'instanciation de plusieurs objets, je trouve ça dommage. Là encore, on n'a pas la même approche (il va sans dire que je préfère la mienne lol, sinon j'aurais pas fait comme ça hein...).
=> Ca reste un point de vue (je ne le dénigre pas), mais en fait le fait d'instancier plusieurs objet me permet de gerer en OO ma construction de page. J'ai en cours de réalisation une classe Template_HTML qui est hérite de ND_Template. Cette classe peut instancier les classes Template_CSS et Template_JS (héritant elles aussi de ND_Template) pour créer le code HTML qui va bien

Je considère ma classe comme un moteur. Un moteur qui peut faire plusieurs choses. Un moteur indépendant. C'est un peu une moulinette à template : tu lui en donnes un, tu récupères du code parsé, tu en passes un autre, etc.
Toi, tu vois plutôt ta classe comme une machine qui ne peut traiter qu'une seule information à la fois.
=> C'est réellement en ca que notre approche differe, tu constuits petit a petit ta page via le meme objet. Moi je considere qu'une page c'est un template qui peut ou pas etre construit a partir d'autre template (ceux ci sont independant hors variables globales). Tu es avec ton approche obligé de récuperer chaque sous template et parser chaque sous template avant son réel affichage, le mien parse tout d'un coup, ca m'évites d'avoir en mémoire le code parser(j'ai en revanche le code non parsé en mémoire, ce qui n'est pas forcement plus économique)

En fait, avec ta classe, on peut tout à fait utiliser plusieurs templates sans instancier d'autres objets. Il suffit de vider le contenu, pour que lors de l'affectation d'un nouvau fichier de template, il le charge complètement (ce qu'il ne fait pas s'il y a du contenu). Personnellement, je ne trouve pas ça très pratique.
=> Ce n'est pas le but du jeu, un template est un tout si tu dois avoir une sous partie template tu l'affecte a ton template master via un template enfant. J'aurai peut etre du définir cela dès le début car c'est un des points majeurs(voir le plus important).

Pour conclure ce commentaire, il est manifeste qu'on n'a pas eu la même approche du problème. Ca donne deux manières de voir, deux codes radicalement différents (pour ne pas dire opposés) dans la manière de fonctionner. Je ne sais pas si, dans l'absolu, l'une est meilleure que l'autre... Ta classe mériterait que tu te penches un peu plus sur la souplesse d'utilisation et l'ergonomie, parce qu'elle est quand même performante, hein. J'ai pas l'impression que tu aies du code qui fait des trucs inutiles.
Tout ça, c'est mon opinion à moi, et c'est quand même bien qu'il y ait de la diversité :)
=> En tout cas, je te remercie de ta patience d'avoir lu le code, de l'avoir commenté. Je pense que la diversité des implémentations de notions identiques sur ce site en fait son interet.

Vielle partie de commentaire non traitée (car lecture en diagonale, désolé)
- manque de souplesse concernant l'assignation des variables. Soit j'ai pas tout bien vu, soit on est obligé d'assigner les variables par couple, une par une. C'est un peu lourd quand on veut assigner le résultat d'une requête SQL.
tu peux normalement récuperer ton resultat sous forme de tableau et/ou d'objet ton ou tes resultats. Rien ne t'empeche avec mon systeme de créer un template associant un row SQL avec un template prédéfini et/ou de boucler sur x row si ta requete renvoi plusieurs rows.

avec un code du genre :
$i = 0 ;
if ( mysql_num_row($dbResult) > 0 ){
// on a plusieurs resultats
$cTSql = array();
while ( $row = mysql_fetch_array($dbResult) || $i < 10 ){
$oTSql = new ND_Template;
$oTSql->setContent('<tr><td>#sql.id#</td><td>#sql.nom</td><td>#sql.prenom</td><td>#sql.role</td></tr>');
$oTSql->addValue('sql', $row );
$cTSql[] = $oTSql ;
$i++;
}
}else{
// on n'a aucun résultat
$cTsql = '<tr><td>aucun contenu</td></tr>';
}
$oTPrincipal = new ND_template;
$oTPrincipal->setTemplateFile('tpl/tableau.tpl'); // contenu de tableau.tpl ('#content#
')
$oTPrincipal->addValue('content', $oTSql);

Voila, j'avoue que j'ai un doute quand a la performance d'un telle systeme si l'on doit instancier beaucoup de sous template a une page.
neigedhiver
Messages postés
2483
Date d'inscription
jeudi 30 novembre 2006
Statut
Membre
Dernière intervention
14 janvier 2011
13 -
Concernant la doc, c'est pas tellement que c'est complexe... C'est juste qu'il faut se plonger dans le code source pour savoir ce qu'on peut faire, avec quoi et comment. C'est juste plus long, faut aussi comprendre comment t'as vu les choses en écrivant cette classe, etc. Disons que pour quelqu'un qui veut juste utiliser le moteur de template, c'est pas évident... Y'a pas besoin de grand chose pour expliquer en 2 ou 3 lignes l'intérêt et le fonctionnement des méthodes publiques.

Pour l'assignation de variables, que tu aies fait ça pour le fun ou pas, il n'en demeure pas moins que c'est pas hyper pratique... Encore que... j'ai du mal à bien piger comment ça marche, parce que là, dans ton exemple, tu utilises addGlobal pour assigner un tableau... Alors je suis perdu... et un peu de doc m'aiderait, là, en fait ;)

PCRE : ok... Effectivement, pour supprimer les variables restantes non assignées... Moi, je suis parti du principe que s'il reste des variables, c'est qu'elles n'ont pas été correctement gérées.

return $this => linker les méthodes... Ouais, admettons. C'est vrai que c'est pratique. Mais d'un point de vue sémantique, ça me chiffone un peu, quand même...

Pour clear() : c'est ce que je viens d'implémenter dans la v0.4 de ma classe (pas encore en ligne). Moi, je trouve ça très pratique. Soit je passe une variable en argument, il la supprime, soit je ne passe rien, il supprime tout.
Faut dire, on n'a pas la même approche des variables de template locales et globales. Dans ma classe, les variables assignées à l'objet sont globales (du fait que je n'ai pas besoin d'avoir plusieurs instances pour bosser sur plusieurs templates). Les variables locales ne sont pas sauvegardées et directement utilisées lorsque le template est parsé. Du coup, les seules variables que j'ai a supprimer, ce sont les globales. J'ai la même approche que la portée des variables dans les fonctions en PHP : celles qui sont définies dans une fonction ne sont pas accessible en dehors. C'est moins lourd aussi, parce que si j'ai beaucoup beaucoup de variables, celles qui ne sont utilisées qu'une seule fois dans un template (qui peut ne pas être utilisé, donc soumis à condition) ne sont pas stockées en mémoire.

Enfin, concernant l'instanciation de plusieurs objets, je trouve ça dommage. Là encore, on n'a pas la même approche (il va sans dire que je préfère la mienne lol, sinon j'aurais pas fait comme ça hein...).
Je considère ma classe comme un moteur. Un moteur qui peut faire plusieurs choses. Un moteur indépendant. C'est un peu une moulinette à template : tu lui en donnes un, tu récupères du code parsé, tu en passes un autre, etc.
Toi, tu vois plutôt ta classe comme une machine qui ne peut traiter qu'une seule information à la fois.
En fait, avec ta classe, on peut tout à fait utiliser plusieurs templates sans instancier d'autres objets. Il suffit de vider le contenu, pour que lors de l'affectation d'un nouvau fichier de template, il le charge complètement (ce qu'il ne fait pas s'il y a du contenu). Personnellement, je ne trouve pas ça très pratique.

Pour conclure ce commentaire, il est manifeste qu'on n'a pas eu la même approche du problème. Ca donne deux manières de voir, deux codes radicalement différents (pour ne pas dire opposés) dans la manière de fonctionner. Je ne sais pas si, dans l'absolu, l'une est meilleure que l'autre... Ta classe mériterait que tu te penches un peu plus sur la souplesse d'utilisation et l'ergonomie, parce qu'elle est quand même performante, hein. J'ai pas l'impression que tu aies du code qui fait des trucs inutiles.
Tout ça, c'est mon opinion à moi, et c'est quand même bien qu'il y ait de la diversité :)
cs_garfield90
Messages postés
389
Date d'inscription
lundi 7 juillet 2003
Statut
Webmaster
Dernière intervention
10 février 2009
-
Documentation :
Je suis ok, rien n'a été fait concernant la doc, mais je pensais pas que c'était si complexe que ca. Je vais m'y mettre un de ces jous.

Assignation de variable:
On ne peut passer qu'une variable a la fois, peut etre faire une methode multiAssign qui prend un tableau en param. Mais bon, ce code a été fait rapidement pour le fun, est l'interet était surtout de pouvoir associé n'importe quel type de variable (tableau, chaine, objet)

Utilisation des PCRE:
normalement, il n'y a en a qu'une seule et c'est pour supprimer les patterns non utilisés.

le "return $this" dans la majorité des methodes permet de linker les methodes entre elle, c'est super pratique de pour faire :
$oT->addValue('to','ta')
->addValue('ti','tu');

Concernant les tests, je pense que je vais mettre ca a jour rapidement
pour la méthode clear, je pense qu'en inversant les params, ca sera plus simple et plus intuitif.
faire 2 methodes pour clear tout, rien ou un ensemble de valeur me semble AMHA pas forcement pertinent.

Sinon, je vais prendre en compte quelques modifs proposé (is_file en place de file_exists et pour le is_null ).

J'ai mis un exemple en fin de code, peut etre que ca permettra aux autres de comprendre mon code et ma facon de voir :P

pour pouvoir utiliser plusieurs template, tu instancies plusieurs templates que tu peux sans soucis associées a 1 template parent
neigedhiver
Messages postés
2483
Date d'inscription
jeudi 30 novembre 2006
Statut
Membre
Dernière intervention
14 janvier 2011
13 -
Ok, j'ai trouvé... Mais c'est quand même tordu...
Il faut utiliser ND_Template::setContent() et lui passer en argument une chaine vide...