[PHP5] LIGHTEMPLATE - MOTEUR DE TEMPLATES ULTRA-LÉGER

codefalse Messages postés 1123 Date d'inscription mardi 8 janvier 2002 Statut Modérateur Dernière intervention 21 avril 2009 - 14 avril 2008 à 10:01
neigedhiver Messages postés 2480 Date d'inscription jeudi 30 novembre 2006 Statut Membre Dernière intervention 14 janvier 2011 - 28 déc. 2008 à 11:36
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/46354-php5-lightemplate-moteur-de-templates-ultra-leger

neigedhiver Messages postés 2480 Date d'inscription jeudi 30 novembre 2006 Statut Membre Dernière intervention 14 janvier 2011 19
28 déc. 2008 à 11:36
Salut,

Merci de t'intéresser à ma source :) Elle n'est donc pas totalement morte ^^

Dans l'ordre...
- Des exemples : Oui, ça pourrait être pas mal, en effet. Je pensais en fait que c'était l'utilisation de la classe qui nécessitait d'être illustrée, un template restant un template...
- Nettoyer les lignes vides : euh... Je vois pas bien l'utilité fondamentale...
- isEmptyDir : je crains que ta fonction n'offre pas la même finesse dans la gestion des exceptions. Ou alors je suis pas assez bien réveillé pour bien comprendre.
- DIRECTORY_SEPARATOR : dans l'absolu, je te donne raison. Dans la pratique, PHP sait parfaitement manipuler les / dans les chemins sur Windows avec toutes les fonctions de fichiers... Je n'ai jamais vraiment compris l'intérêt profond que présente cette variable dans l'utilisation courante... Si encore il était utile d'écrire à l'écran le chemin d'un fichier pour l'utilisateur... mais même pas...
- blocs imbriqués : Je ne souhaite pas que ce soit possible, parce que cela obligerait l'utilisation d'expressions régulières, or c'est une contrainte que je me suis fixé dès le départ. Et si je dois utiliser des Regex, autant réécrire Smarty. On peut imbriquer des blocs en utilisant un template par boucle, et en assignant le résultat d'un premier à une variable d'un autre. Permettre des blocs imbriqués reviendrait à permettre de faire la même chose de plusieurs manières différentes, ce qui est contraire à ma ligne de coding.
- ob_start() : je vois pas bien l'intérêt... Si tu veux bien expliquer un peu...
WildGroup Messages postés 15 Date d'inscription mercredi 21 janvier 2004 Statut Membre Dernière intervention 2 novembre 2010
28 déc. 2008 à 01:55
Re...

peut être mais de mon coté je trouve ceci bien pour alléger le contenu.

:: IDEES ::
Pour quoi pas :
- donner un/des exemple/s précis avec les fonctions de ta classe en utilisent des *.tpl
- un petit netoyage des lignes vides dans le file_get_contents
- un function qui peut etre t'evitera de faire trop des vérifications dans ton __construct

function isEmptyDir($dir,$_return = false) {
if(is_dir($dir)):$_return (($files @scandir($dir)) && count($files) <= 2);
endif;
return $_return;
}

- utiliser DIRECTORY_SEPARATOR;
- donner la possibilité d'utiliser des block in block
ex:
<!-- BEGIN main_menu -->
<!-- BEGIN items -->
<!-- END items -->
<!-- END main_menu -->
- utiliser ob_start() avant "file_get_contents"

P.S.: il est 2h de mat je n'ai pas trop épluché ton code mais je reviendrais a l'occasion

Bon travail si non encore quelques modif et tu peux changer de niveaux ...:p
neigedhiver Messages postés 2480 Date d'inscription jeudi 30 novembre 2006 Statut Membre Dernière intervention 14 janvier 2011 19
27 déc. 2008 à 14:09
Salut,

Cela n'est, à mon sens, pas du ressort du template. Cela peut être fait de manière indépendante par une fonction externe.
Le template se contente de remplacer des variables dans un modèle : c'est son rôle, il ne fait rien d'autre.
WildGroup Messages postés 15 Date d'inscription mercredi 21 janvier 2004 Statut Membre Dernière intervention 2 novembre 2010
27 déc. 2008 à 02:09
bonsoir.... et joyeux noel

le bosseurs ils se retrouve meme "dans le coin"

pour quoi pas prévoir/ajouter une fonction de sanitize?

function sanitize_tpl($buffer) {
$search = array("/\>[^\S ]+/s", "/[^\S ]+\</s", "/(\s)+/s");
$replace = array(">", "<", "\\1");
$buffer = preg_replace($search, $replace, $buffer);
$buffer = str_replace(array("\n", "\t", "\r"), "", $buffer);
$buffer = str_replace(array(" "), " ", $buffer);
return $buffer;
}
neigedhiver Messages postés 2480 Date d'inscription jeudi 30 novembre 2006 Statut Membre Dernière intervention 14 janvier 2011 19
17 avril 2008 à 09:20
Plop,

Encore une mise à jour : v0.4
- Nouvelle méthode : append() permet d'ajouter du contenu à une variable déjà définie. Si la variable n'existe pas, elle est automatiquement créée.
- Suppression de la méthode clearVars() et renommage de la méthode clearVar() en clear(). Avec argument : supprime la variable spécifiée. Sans argument, supprime toutes les variables.
- correction de quelques tests (avec is_scalar() notamment), parmi lesquels certains provoquaient un comportement inattendu

Je prévois un petit site à l'arrache pour documenter tout ça correctement, en plus de la doc fournie dans le code source.
Je suis également preneur de toute idée de fonctionnalité qui pourrait être utile (ah j'ai pas encore implémentée l'idée de Malalam concernant l'alternance) sans sacrifier aux performances ni à la légèreté.
neigedhiver Messages postés 2480 Date d'inscription jeudi 30 novembre 2006 Statut Membre Dernière intervention 14 janvier 2011 19
15 avril 2008 à 18:51
Plop,

J'ai mis à jour.

- foreach() au lieu de array_map()
- type hinting qui économise des tests
- possibilité de passer des variables locales à fetch()
- fetch() ne prend plus de tableau en argument, uniquement un iterateur
- correction de la méthode assign() selon les conseils de Malalam
- suppression de display() et displayLoop()
- test de l'existance et de l'accès en lecture du répertoire de template
- correction d'un petit bug qui empêchait de supprimer une variable assignée dans un tableau

Logiquement, j'ai pas du rajouter de bug...
neigedhiver Messages postés 2480 Date d'inscription jeudi 30 novembre 2006 Statut Membre Dernière intervention 14 janvier 2011 19
15 avril 2008 à 01:17
Bon les enfants, vous avez vu l'heure ? J'espère que vous êtes couchés, là maintenant.

@Garfield : (si ton pseudo n'est pas complet, au moins, ça fait pas d'erreur)... Euh bon sérieusement...
Je suis partiellement d'accord avec toi, pour la gestion des erreurs. Seulement, parfois, au lieu de tester avant si ça va passer, on peut présumer que ça va passer, et voir ensuite pourquoi ça a chié.
Je suis d'accord, c'est pas la meilleure solution. Pour moi, le plus important concernant les erreurs, c'est de les gérer. Là, il s'agit d'une classe qui a vocation à être utilisée par des développeurs. Elle ne traite aucune information saisie par un internaute. Le développeur est supposé faire en sorte que dans son code, il n'ait pas d'erreur. Seulement, ça peut toujours arriver...
Il a copié ses fichiers sur un nouveau serveur, et les permissions ne sont pas gérées de la même manière, le fichier de template n'est plus accessible en lecture par le serveur : c'est une erreur qui n'est pas censée arriver. Si le développeur fait son boulot correctement, il cherche des fichiers qui existent, il ne les supprime pas, etc.
Maintenant, c'est pas une méthode que je préconise dans tous les cas. Pour le traitement de données qui proviennent de $_POST ou $_GET, je dis pas : il faut forcément vérifier avant. Mais parfois, je pense qu'on peut se permettre quelques libertés. Dans ce cadre là, ça ne me choque pas vraiment. On évite 2 tests de fichiers avant de lire le contenu.

Pour le cache, ton point de vue est tout à fait pertinent. Tellement pertinent, qu'il va me falloir discuter de ça avec mon chef/collègue (patron, t'es dans l'coin ?).
Du coup, la mise en cache de HTML peut être intéressante pour, par exemple, des boucles : une liste d'articles qui ne change pas souvent, la liste des membres, etc. Parser à chaque fois alors que le contenu est rigoureusement identique, ça me parait lourd et inutile. Mettre le contenu du template de cette liste en cache ne me parait pas absurde : même si le contenu est mis en cache, si on peut éviter de faire 200 remplacements de variables avant d'afficher, c'est toujours ça de gagné, surtout si le site a pas mal de hits.

Bref, ça se discute...
En tout cas, je pensais pas que ma source provoquerait autant de commentaires. Mais c'est intéressant tout ça. Merci à tous les participants :)
codefalse Messages postés 1123 Date d'inscription mardi 8 janvier 2002 Statut Modérateur Dernière intervention 21 avril 2009 1
15 avril 2008 à 00:14
Pour le cache je suis d'accord avec toi.
Pour les erreurs, je pense que ca devrait plus dépendre du type d'usage en fait. Si c'est pour lire un fichier, on peux tester une fois que l'ouverture ait échoué. Si c'est pour faire une insertion dans une sgbd par exemple, là vaut mieux tester avant ! ;)
cs_garfield90 Messages postés 388 Date d'inscription lundi 7 juillet 2003 Statut Webmaster Dernière intervention 10 février 2009
14 avril 2008 à 23:32
ouaip, concernant les erreurs je suis pas tellement d'accord avec toi :
- le @ est chronophage (enfin un peu, le @ est juste bon pour les email ou pour délimiter les patterns regex :P)
- si tu testes les erreurs après c'est que tu en as eu, ce qui n'est pas normal :D (enfin, c'est mon humble avis), le fait de tester avant évite justement de l'avoir.
- quand tu parles d'un systeme de cache, c'est une couche supplemtaire, pas une fonctionnalité supplémentaire?

Je pense pas qu'un moteur de template est a gerer du cache :
soit ta donnée est valide et tu associe la donnée en cache a ton template
soit tu génère tes données caché et tu associe la donnée en cache a ton template

ton cache est externalisé a ton systeme de template, de plus ca te permet de le factorisé pour pouvoir l'utilisé pour autre chose (cache SQL, cache JSON, ... )
codefalse Messages postés 1123 Date d'inscription mardi 8 janvier 2002 Statut Modérateur Dernière intervention 21 avril 2009 1
14 avril 2008 à 23:18
Franchement, Neige, c'est absolument pas con ton idée !!!!
On y pense jamais mais en effet, l'erreur, tu la cherche seulement s'il y a un probleme !!!

Bravo et merci beaucoup ! j'y avais jamais pensé :)
neigedhiver Messages postés 2480 Date d'inscription jeudi 30 novembre 2006 Statut Membre Dernière intervention 14 janvier 2011 19
14 avril 2008 à 22:36
@Codefalse : Ben perso, je préfère laisser aux développeurs qui le souhaitent le soin d'étendre cette classe pour en faire ce qu'ils veulent. Pour l'alternance des couleurs, par exemple, si l'idée de Malalam est loin d'être mauvaise, c'est encore le genre de truc qui va servir une fois tous les 107 ans.
A moins que...
Vais y réfléchir quand même... Soit une méthode spécifique pour gérer une alternance quelconque (simplement, comme le suggérais Malalam, un tableau de remplacement que le développeur et le designer utilisent comme bon leur semble) lors d'une itération...
Bon, ben ce sera pour la prochaine version alors... Après le cache... (chaque chose en son temps, hein).

@Garfiled : T'as raison de vouloir checker... Moi aussi, j'ai tendance à le faire. Mais je cherche toujours (oui, oui, toujours toujours) si un test peut être évité malgré tout (en faisant les opérations dans un certain ordre par exemple, en faisant attention aux valeurs de retour et aux erreurs levées, etc).
Tiens par exemple, une petit optimisation que j'ai faite pour la version 0.3 : je récupère le contenu d'un fichier avec @file_get_contents. Si le retour est false, alors seulement je cherche pourquoi ça a échoué, au lieu de vérifier avant que le fichier existe et est accessible en lecture. Les erreurs, c'est ce qui se passe, normalement, le moins souvent...

Sinon, je donnais cet exemple là, mais bon, c'est un exemple à la con. Effectivement, c'est moins lourd que d'instancier un nouvel objet. Mais c'est pas forcément plus facile de s'y retrouver dans ses templates si de l'un à l'autre le format des variables change...
C'est pour ça que ton message m'a fait m'interroger sur la possibilité de passer, comme pour fetchLoop(), un tableau de valeurs spécifiques pour un template, avec la possibilité de mélanger ou non avec les variables globales. Et plus j'y pense, plus je me dis que c'est indispensable...

Donc, mise à jour très prochaine, avec :
- foreach() au lieu de array_map()
- type hinting qui économisera des tests
- possibilité de passer des variables locales.
- correction de la méthode assign() selon les conseils de Malalam
- euh ça fait déjà pas mal...

Puis faudra que j'y mette du cache...
codefalse Messages postés 1123 Date d'inscription mardi 8 janvier 2002 Statut Modérateur Dernière intervention 21 avril 2009 1
14 avril 2008 à 22:23
Eyh les gars, quand meme, 24 mails vous avez abusé ! :p

@Malalam : Je vois pas ce que tu voulais dire quand tu me répondais à propos des moteurs de templates ? je suis tout à fait d'accord d'alterner en css, mais comme c'est pas encore trop ca le css3, je proposais de le faire en code. D'ailleur ton idée de tableau n'est vraiment pas mal ! :)
cs_garfield90 Messages postés 388 Date d'inscription lundi 7 juillet 2003 Statut Webmaster Dernière intervention 10 février 2009
14 avril 2008 à 21:35
ok,

pour le unset, je savais pas, je dormirai moins *** ce soir :P (ah, cette habitude de tout vouloir checker)

concernant le 2eme point, tu dois donc t'amuser a redéfinir pour chaque template un pattern pour ta variable (pas tres pratique comme truc), mais (peut etre|surement) moins gourmand que d'instancier un autre template.
neigedhiver Messages postés 2480 Date d'inscription jeudi 30 novembre 2006 Statut Membre Dernière intervention 14 janvier 2011 19
14 avril 2008 à 21:25
Salut,

- Non, unset() fonctionne très bien quand la variable n'existe pas. Il se contente de ne rien faire.

- Tous les templates parsés bénéficient des variables assignbées via assign(), sauf pour les boucles, où l'on peut utiliser des variables spécifiques.
En gros, si j'ai une variable {_id_} dans plusieurs templates et que je les inclus sans jamais redéfinir la variable à chercher, les variables {_id_} seront toutes remplacées par la même variable.
C'est pour cela qu'on peut modifier le format des variables, qu'on peut passer des tableaux de variables différents. Remarque, je devrais peut-être permettre le passage de tableau de valeurs dans fetch(), afin que pour un template, il n'utilise que ces variables là.
cs_garfield90 Messages postés 388 Date d'inscription lundi 7 juillet 2003 Statut Webmaster Dernière intervention 10 février 2009
14 avril 2008 à 21:14
juste quelques petits trucs en passant :

- Tu ne vérifies pas l'existance de la clé dans clearVar(), ca risque de poser quelques soucis si la clé n'existe pas :'(
- Que ce passe t'il si tu incorpore plusieurs templates avec des variables identiques ? ( a moins que ce soit gerer au moment de l'incorporation).

Tout ca pour dire que les moteurs de templates se suivent mais ne se ressemble pas.(cf le mien : http://www.phpcs.com/codes/MOTEUR-TEMPLATE-PHP5_45263.aspx, un petit peu de pub ne fait pas de mal, d'autant plus qu'il n'est pas/peu commenter)
malalam Messages postés 10839 Date d'inscription lundi 24 février 2003 Statut Membre Dernière intervention 2 mars 2010 25
14 avril 2008 à 21:03
Si j'ai eu l'idée, mais je me suis dit que tu me demanderais ;-) (en fait sur le coup j'avais la flemme de regarder parce que j'avais encore envie d'un café lol).
Ici, sous XP : 5.2.5
Au taf , 2 Debians, une en 5.0.4 et une en 5.2.5 aussi.
J'ai aussi un poste sous XP avec wamp mais je ne sais plus quelle version...5.2 tout court je pense, suis pas très sûr. Ou 5.2.3 aussi, mais pas la 5.2.5 en tous cas.
neigedhiver Messages postés 2480 Date d'inscription jeudi 30 novembre 2006 Statut Membre Dernière intervention 14 janvier 2011 19
14 avril 2008 à 20:48
Ah tiens, c'est pas con ça... Du coup, t'aurais pas eu l'idée de dire dans un même message quelle version tu as, toi...

Moi, je suis avec PHP 5.2.3
et mon dédié est en 5.1.4 (putain, vais p'têt' penser à faire une mise à jour...)

"Ouais, moi aussi, c'est le genre de discussions que j'aime : quand je gagne ;-) Chuis d'accord, faudra que ce soit tout pareil!!"
PTDR

Ben voyons !! Surtout que si c'est la version de PHP, pour le coup, on aurait raison tous les deux lol
malalam Messages postés 10839 Date d'inscription lundi 24 février 2003 Statut Membre Dernière intervention 2 mars 2010 25
14 avril 2008 à 20:42
Nan ceci dit ça peut aussi être dû à différentes versions de PHP hein. Ils ont tendance à essayer d'optimiser les fonctions quand même, par moment.
malalam Messages postés 10839 Date d'inscription lundi 24 février 2003 Statut Membre Dernière intervention 2 mars 2010 25
14 avril 2008 à 20:40
"P.S. : tu vois, c'est exactement ce genre de discussion que j'imagine, quand je te parlais de débats... Mais pas uniquement, hein... Juste pour illustrer..."
Puis
"Conclusion : je vais p'têt' mettre un foreach, hein... T'as gagné..."

Ouais, moi aussi, c'est le genre de discussions que j'aime : quand je gagne ;-) Chuis d'accord, faudra que ce soit tout pareil!!
malalam Messages postés 10839 Date d'inscription lundi 24 février 2003 Statut Membre Dernière intervention 2 mars 2010 25
14 avril 2008 à 20:36
Bah fais voir ton code (pas ta classe hein lol), que je fasse la même chose.
neigedhiver Messages postés 2480 Date d'inscription jeudi 30 novembre 2006 Statut Membre Dernière intervention 14 janvier 2011 19
14 avril 2008 à 20:36
Bon alors sur mon dédié, c'est pas le même résultat mdr

Array_map() est carrément plus lent :-(

100000 iterations
Foreach : 6.09541702271
Array Map : 7.51797103882

Mince alors... Mon pc est une vraie daube !!
Comme quoi... C'est vraiment urgent que je trouve du boulot... Ca peut plus durer... Firefox et Amarok en même temps => quanta qui rame... :/

Conclusion : je vais p'têt' mettre un foreach, hein... T'as gagné...
neigedhiver Messages postés 2480 Date d'inscription jeudi 30 novembre 2006 Statut Membre Dernière intervention 14 janvier 2011 19
14 avril 2008 à 20:31
Oui, mon code, sous une xUbuntu (base debian donc).
J'vais bencher le tien pour voir...
Sinon, j'ai peut-être un processeur tellement pourri qu'il est pas optimisé pour les foreach()...
Ce serait alors pas qu'il est plus rapide avec array_map(), mais plus lent avec foreach() lol

Vais tester sur mon dédié (gentoo) pour voir si c'est pareil (ton code et le mien).
Ca m'intrigue cette histoire..

P.S. : tu vois, c'est exactement ce genre de discussion que j'imagine, quand je te parlais de débats... Mais pas uniquement, hein... Juste pour illustrer...
malalam Messages postés 10839 Date d'inscription lundi 24 février 2003 Statut Membre Dernière intervention 2 mars 2010 25
14 avril 2008 à 20:25
Là sous Windows XP, et au taf sous Une distrib Debian. Même combat lol.
T'as benché quoi et comment ? Ton code ?
neigedhiver Messages postés 2480 Date d'inscription jeudi 30 novembre 2006 Statut Membre Dernière intervention 14 janvier 2011 19
14 avril 2008 à 20:20
Ben désolé...

100000 itérations
Foreach : 13.798568964
Array Map : 13.0512681007

100000 itérations
Foreach : 13.9519181252
Array Map : 13.1476869583

Tu benches sur quel OS ?

Chez moi, plus je benches, plus array_map est rapide...

500000 itérations
Foreach : 69.0398550034
Array Map : 65.3533668518
malalam Messages postés 10839 Date d'inscription lundi 24 février 2003 Statut Membre Dernière intervention 2 mars 2010 25
14 avril 2008 à 20:17
chuis quand même étonné, j'ai refait un tout petit test sur 1000 itérations :
<?php
$a = range(0, 1000);
/*
function add($v) {
return ++$v;
}
*/
$iStart = microtime(true);
foreach($a as $i => $v) {
$a[$i] = ++$v;
}
//$a = array_map('add', $a);
echo microtime(true) - $iStart;
?>

je suis en moyenne à 0,008 avec le foreach, et à 0,010 avec le array_map() moi.
malalam Messages postés 10839 Date d'inscription lundi 24 février 2003 Statut Membre Dernière intervention 2 mars 2010 25
14 avril 2008 à 20:06
Ah oui mais quand je benche, moi, je fais ça sur 100000 voire 1000000 itérations, et array_map est largement distancé dans ces cas-là. J'ai fait le test récemment pour une application dédié à mon taf, où les rendements seront conséquents (justement, plusieurs centaines de millier d'itérations en un coup). Mais bon, si pour de plus petits rendements, array_map() s'en sort mieux, ma foi...un moteur de template ne devrait pas avoir à bosser énormément de toute manière :-)
neigedhiver Messages postés 2480 Date d'inscription jeudi 30 novembre 2006 Statut Membre Dernière intervention 14 janvier 2011 19
14 avril 2008 à 20:00
Bon alors je viens de bencher. Désolé Patron, mais ta cote de popularité vient de baisser dans les sondages...

Si j'exécute une fois un foreach() et une fois array_map(), la différence est insignifiante (de l'ordre 0,00002 sec) :

Foreach : 0.000134944915771
Array Map : 0.000115156173706

Si je les mets dans une boucle for pour 5000 itérations, array_map éclate litéralement foreach() :

Foreach : 0.673834085464
Array Map : 0.615473031998

En réalité, parfois foreach() est plus rapide, parfois c'est array_map(). C'est très aléatoire. J'en déduis que c'est kiff-kiff les deux... Donc je vais garder mon array_map(), hein, si tu veux bien ;)

Pour rebondir sur ta réponse à Codefalse :
"Mais rien n'empêche de prévoir un petit ajout à la classe permettant de déclarer une alternance sur une variable particulière"

En réalité, rien n'empêche personne de modifier la classe comme il l'entend (GPLv3), ou de l'étendre pour ses besoins. Après tout, un développeur sait aussi adapter du code à ses besoins, surtout quand c'est aussi "simple" que cette classe (en comparaison avec des packags comme Smarty ou PEAR) ^^
malalam Messages postés 10839 Date d'inscription lundi 24 février 2003 Statut Membre Dernière intervention 2 mars 2010 25
14 avril 2008 à 19:41
__construct() : oui mais avant de le vérifier, tu l'assignes à une propriété. Autant le vérifier de suite parce que si le répertoire n'est pas valide, inutile de faire quoi que ce soit.

- assign() : j'aime bien les constantes de classe lol. Ca ne coûte rien, et c'est plus lisible puisque déclaré dans ta classe. Mais en effet, dans ce cas précis, vu que ce ne sera qu'une valeur booléenne, et pas plusieurs valeurs différentes possibles, oui, un booléen fera l'affaire.

Pour array_map(), benche donc :-) Tu verras, c'est plus que flagrant, en plus.
Et je t'en prie ;-) Je continuerai après l'avoir testée.
neigedhiver Messages postés 2480 Date d'inscription jeudi 30 novembre 2006 Statut Membre Dernière intervention 14 janvier 2011 19
14 avril 2008 à 19:32
Salut patron lol,

- __contruct() : Justement, je vérifie que le répertoire de template existe : c'est la fonction realpath qui le fait pour moi, c'est pour ça que je teste ensuite avec === false. J'utilise realpath parce que.... C'est peut-être idiot, remarque, c'est une habitude que j'ai de bosser avec des chemins absolus, par précaution. Je me suis donc pas creusé la cervelle : j'ai utilisé realpath, qui retourne false si le chemin/fichier n'existe pas.

- parse() : ah ben ouais... C'est carrément vrai, ça évite de faire un test...

- display() et displayLoop() : elles servent juste à afficher le résultat... C'est pas utile, mais ça bouffe pas spécialement de ressources et c'est plus lisible... à mon avis...
Cela dit, il faut bien avouer qu'elles ne font pas grand chose... Elles peuvent être supprimées... C'est vrai que si je force le dév à passer un array() à parse(), il peut aussi bien se mettre un echo sur le résultat de fetch()...
Vais les virer.

- fetchLoop() : ah ! array_map() est plus lent que foreach()... Merde alors ! Vais bencher, parce que dans mon esprit, il était évident que c'était plus rapide... Pas que je te crois pas, juste que j'aime bien vérifier avec mes noeils.

- assign() : très juste... Un petit paramètre en plus, ça ferait pas de mal. Une constante de classe, c'est vraiment nécessaire ? Un ptit booléen c'est pas suffisant ?

En tout cas merci pour tes commentaires. Je pensais pas avoir laissé passer tout ça !
malalam Messages postés 10839 Date d'inscription lundi 24 février 2003 Statut Membre Dernière intervention 2 mars 2010 25
14 avril 2008 à 19:30
Pour répondre à CodeFalse, au fait, ça me semble relativement simple, moi.
Tout d'abord : un template HTML, c'est quoi ? De la description de contenu, comme le serait un flux XML ? (par opposition ensuite au moteur de template PHP versus XSL). Nan...XML, c'est du descriptiof, et c'est bien XSL qui va se charger de la mise en page.
Mais HTML c'est DEJA de la mise en page. En même temps que du descriptif hein (bla

indique que bla est un paragraphe...c'est descriptif...mais ça met aussi bla en forme comme un paragraphe).
Donc en effet...je penche pour CSS. Mais rien n'empêche de prévoir un petit ajout à la classe permettant de déclarer une alternance sur une variable particulière (le nom d'une classe CSS par exemple). {__CLASSNAME__} => array({__CLASS1__}, {__CLASS2__}) (en plus fouillé hein là c'est juste un exemple...parce que si toi tu veux une alternance sur 2 couleurs, je suis sûr que d'autres en voudront 3...!), et avec les itérateurs (et un itérateur dédié de préférence, du coup), il serait facile d'alterner entre les 2 pour cette variable.
malalam Messages postés 10839 Date d'inscription lundi 24 février 2003 Statut Membre Dernière intervention 2 mars 2010 25
14 avril 2008 à 19:19
Hola,

bon, je vais faire du linéaire d'abord (enfin...en suivant quand même peu ou prou le déroulement de la classe). Et je préviens, je suis crevé (d'ailleurs, vais me faire couler un chtit expresso...).

- __construct() : moi, j'aurais d'abord testé si le répertoire templates passé en paramètre est un répertoire avant de faire le reste. C'est toujours ça de gagné si jamais ce n'est pas un répertoire valide.
- parse() : si tu comptes rester avec des tableaux en paramètre, autant typer tes paramètres : public function parse($sContents '', array $aSearch, array $aReplace, $bMerge false){}
Ca t'évite un contrôle et ça prévient le développeur qu'il s'est planté. Parce que là, si je passe une chaîne ou toute autre valeur scalaire, il ne se passe rien de visible (le parsing se fera avec l'existant, sans tenir compte de ce que j'ai passé en paramètres).

- display() et displayLoop() : elles servent à quoi ? Enfin, pourquoi avoir surchargé deux méthodes existantes qui sont en plus publiques ?

- fetchLoop() : array_map() est très pratique et clair, mais bien plus lent qu'un foreach(). Donc si tu veux optimiser...;-) Tu peux toujours tester en bouclant plutôt qu'en utilisant ton array_map(). Sans compter que si tu transformais d'abord ton tableau en ArrayIterator, ce serait peut-être encore plus rapide.
Ah j'avais pas vu que tu ne le transformais pas en ArrayIterator. Tu attends qu'on te passe un objet implémentant Iterator, ou un tableau. Ben pourquoi tu ne castes pas directement, donc ? Comme ça tu ne jongles qu'avec un seul type.

- assign() : moi, si j'étais toi, j'ajouterais un paramètre (constante de classe) indiquant si on veut ou non écraser un éventuel ancien couple. Une erreur est vite arrivée : par défaut, on n'écrase pas, on prévient (ou l'inverse hein, mais bon...). Un peu comme la fonction extract().

Bon à part ça, c'est une très bonne classe, légère et agréable :-) Et facile à utiliser.
Morphinof Messages postés 255 Date d'inscription vendredi 20 avril 2007 Statut Membre Dernière intervention 9 août 2013 4
14 avril 2008 à 16:05
Je pensais que sa serais plus utile que sa mais bon si sa sert que dans 1% des cas c'est pas la peine ;)
Du bon boulot ^^
neigedhiver Messages postés 2480 Date d'inscription jeudi 30 novembre 2006 Statut Membre Dernière intervention 14 janvier 2011 19
14 avril 2008 à 15:58
Moui. Et transtyper par défaut... pffffffffff Ca va servir une fois sur un million, très sincèrement...
En fait, j'hésitais même à changer la visibilité de la méthode parse() pour la mettre en protected.
Mais bon, des fois qu'on ait envie de parser un contenu qu'on a récupéré autrement qu'avec fetch()...
Très sincèrement, je préfère que le développeur se prenne par la main et transtype quand il en a besoin plutôt que de faire un traitement systématique inutile dans 99% des cas...
Morphinof Messages postés 255 Date d'inscription vendredi 20 avril 2007 Statut Membre Dernière intervention 9 août 2013 4
14 avril 2008 à 15:53
Oui c'est pas glop j'ai essayé de rester au près de la source originale sans trop l'alourdir, l'idée c'étais surtout de voir si le cas ou on change qu'une seule variable du template arrivais assez souvent pour gérer un transypage automatique ^^
Après il suffit de transtyper de base en sortant mes 2 test du elseif les paramètre pour que sa marche :p
neigedhiver Messages postés 2480 Date d'inscription jeudi 30 novembre 2006 Statut Membre Dernière intervention 14 janvier 2011 19
14 avril 2008 à 15:46
@Morphinof : Oui, bon, certes, c'est plus simple d'envoyer une chaine plutôt que de la transtyper. J'avoue. Mais je ne suis pas opposé à le permettre. Simplement, pas avec ton code qui laisse passer tout et n'importe quoi, y compris les variables de type int ou object... Et ça, c'est pas glop.
neigedhiver Messages postés 2480 Date d'inscription jeudi 30 novembre 2006 Statut Membre Dernière intervention 14 janvier 2011 19
14 avril 2008 à 15:44
Merci Putch,

Oui, ma méthode de Smarty est plus pratique. Mais elle est également beaucoup plus couteuse. Finalement, {include file='bidule.tpl'} dans Smarty, ça revient à assigner une variable contenant un fichier parsé.
C'est vraiment l'art de faire la même chose avec 50 méthodes différentes... Et tout cela a un coût et une incidence sur les performances.

Pour le $ manquant, je l'ai bien vu, mais j'ai la flemme de mettre à jour juste pour ça... Je corrigerai quand je mettrai la source à jour, des fois que j'arrive à gagner un peu sur les perfs...
Morphinof Messages postés 255 Date d'inscription vendredi 20 avril 2007 Statut Membre Dernière intervention 9 août 2013 4
14 avril 2008 à 15:37
Justement je trouvais que pour remplacer une seule variable du template c'était plus simple d'envoyer juste une chaine qu'un tableau avec un seul élément comme sa même pas besoin de transtyper puisque la fonction le ferais d'elle même ^^
Je me suis peu être mal exprimé :p
C'est pour sa que je mettais a voir si c'est mieu ou non ^^
neigedhiver Messages postés 2480 Date d'inscription jeudi 30 novembre 2006 Statut Membre Dernière intervention 14 janvier 2011 19
14 avril 2008 à 15:28
Ben non, ça n'a absolument aucun sens de passer des chaines : ça ne permet de remplacer qu'une seule variable de template...
Est-ce que tu as bien compris comment ça fonctionne ?On passe en argument des tableaux de valeurs : les clés à chercher, et leurs remplacements. A utiliser à la place des variables assignées ($bMerge false), ou à combiner avec ($bMerge true).
Finalement, si l'utilisateur n'a qu'une seule variable à remplacer, il lui suffit de la transtyper en tableau.
Reprends mon exemple : on passe à fetchLoop() un itérateur. Chaque élément de l'itérateur va renvoyer un tableau (asosciatif, par exemple, qui serait le résultat de mysql_fetch_assoc()). Le tableau contient alors les noms des champs dans la table, et les valeurs pour l'enregistrement.
On passe les clés du tableau comme premier argument, les valeurs en second. Ca permet d'utiliser directement les noms des champs de la table dans le template. C'est là tout l'intérêt de la chose...

Est-ce que c'est'y plus clair ? :o)
cs_putch Messages postés 624 Date d'inscription mardi 6 mai 2003 Statut Membre Dernière intervention 14 décembre 2009 1
14 avril 2008 à 15:25
exellente classe !

"l'inclusion de fichiers : que nenni => on peut récupérer un fichier parsé dans une variable et l'assigner à une variable de template"

ouai ok mais la méthode SMARTY est bien pratique aussi ^^

sinon dans ton exemple ligne 23
$news = LighTemplate -> fetch('no_news.html');

manque le $ devant LighTemplate :)

++
Morphinof Messages postés 255 Date d'inscription vendredi 20 avril 2007 Statut Membre Dernière intervention 9 août 2013 4
14 avril 2008 à 14:20
J'avais envisagé que éventuellement plutôt que d'envoyer un tableau il serait plus simple d'envoyer une chaine en paramètre ^^
Après reste à voir si c'est mieu ou non ;)
neigedhiver Messages postés 2480 Date d'inscription jeudi 30 novembre 2006 Statut Membre Dernière intervention 14 janvier 2011 19
14 avril 2008 à 11:28
Salut,

Merci pour ton commentaire.

J'ai eu du mal à comprendre l'intérêt de ce que tu me proposes, mais ça commence à venir (j'ai l'esprit un peu embrumé là).
En fait, à l'origine, les arguments $aSearch et $aReplace, sont là pour permettre de parser des boucles, c'est à dire en écrasant les variables du template (plus exactement, en ne les utilisant pas, au profit de variables spécifiques au template de la boucle).
Je ne m'étais pas posé la question de l'utilisation en dehors de ce contexte.
Dans l'absolu, tu as raison : $aSearch et $aReplace peuvent ne pas être des tableaux... Mais est-ce vraiment un problème si la fonction n'accepte que des tableaux ? Est-ce que c'est tellement plus compliqué pour le développeur de passer des tableaux plutôt que des chaines de caractères ? (quitte à ce que ce soit le développeur qui utilise le transtypage pour passer ses chaines en argument).
Parce que du coup, la faille dans le code que tu proposes, c'est que si $aSearch est un objet ou un nombre et que $bMerge est à false, alors str_replace risque de faire la tronche.
D'où la nécessité de vérifier dans le premier if le type des variables $aSearch et $aReplace.

Mais ça me fait réfléchir à l'intérêt qu'il peut y avoir à ce que $aSearch et $aReplace puissent être également des chaines.
Morphinof Messages postés 255 Date d'inscription vendredi 20 avril 2007 Statut Membre Dernière intervention 9 août 2013 4
14 avril 2008 à 10:42
Simple et efficace, rien à redire sur le code à part une chose ^^
Dans ta fonction parse tu fais ,if ($aSearch array() || $aReplace array() || !is_array($aSearch) || !is_array($aReplace)) {
$aSearch = $this -> aSearchVars;
$aReplace = $this -> aReplaceVars;
}
elseif ($bMerge) {
$aSearch = array_merge($this -> aSearchVars, $aSearch);
$aReplace = array_merge($this -> aReplaceVars, $aReplace);
}

En transtypant $aContents et $aSearch tu enlève 2 test et $aSearch, $aReplace peuvent ne pas être obligatoirement des tableaux ^^
public function parse($sContents '', $aSearch array(), $aReplace = array(), $bMerge = false) {if($aSearch array() || $aReplace array()){
$aSearch = $this -> aSearchVars;
$aReplace = $this -> aReplaceVars;
}elseif($bMerge) {
if(!is_array($aSearch)) $aSearch = (array)$aSearch;
if(!is_array($aReplace)) $aReplace = (array)$aReplace;
$aSearch = array_merge($this -> aSearchVars, $aSearch);
$aReplace = array_merge($this -> aReplaceVars, $aReplace);
}
return str_replace($aSearch, $aReplace, $sContents);
}
codefalse Messages postés 1123 Date d'inscription mardi 8 janvier 2002 Statut Modérateur Dernière intervention 21 avril 2009 1
14 avril 2008 à 10:19
en js pourquoi pas en effet, ensuite le css3 pour ma part je ne trouve pas que c'est à l'ordre du jour. pas que je suis contre en effet, jusque que trop de gens utilisent encore des navigateurs qui ne sont pas tous compatible css3 :p

En fait pour voir ce qui manquait à mon code, j'ai regardé du coté de TinyButStrong, leur exemple en ligne te montre plein de fonctionnalités que tu peux implémenter. Je ne peux que te conseiller d'y jeter un coup d'oeil :)

En tout cas ca mérite un 9/10 :)
neigedhiver Messages postés 2480 Date d'inscription jeudi 30 novembre 2006 Statut Membre Dernière intervention 14 janvier 2011 19
14 avril 2008 à 10:13
Salut,

Merci pour ton commentaire. Ta question est pertinente, et trouve sa réponse dans CSS3.
http://www.w3.org/TR/css3-selectors/#nth-child-pseudo
Sinon en JS... ?
codefalse Messages postés 1123 Date d'inscription mardi 8 janvier 2002 Statut Modérateur Dernière intervention 21 avril 2009 1
14 avril 2008 à 10:01
Franchement intéressant comme script, j'ai juste une petite question :p
J'avais commencé à m'en faire un et j'ai arreté quand je me suis rendu compte d'un truc :
Comment est-ce que tu fait si par exemple je veux avoir une ligne sur deux de telle couleur et une autre d'une autre couleur ? afin d'alterner ?

Je regarde encore et jte met une note :)
Rejoignez-nous