JeuWeb - Crée ton jeu par navigateur

Version complète : [Tutoriel] Moteur de template
Vous consultez actuellement la version basse qualité d’un document. Voir la version complète avec le bon formatage.
Pages : 1 2 3 4
hello, je me suis mal fait comprendre pour l'histoire des moteurs de recherche :

dans la situation :

le serveur produit une page html avec template js (genre angular) et alimente ce template par de la données (genre json, en ajax, ou en include direct dans la page, etc...)

pour l'utilisateur c'est propre : affichage initial correct, se rafraichit rapidement, ...
pour le développeur c'est bien : bande passante réduite, séparation des données et de la vue, ...
pour le moteur de recherche, c'est la loose : il ne lit pas les données il lit uniquement la page avec le template js

si mavariable = "mon mot clef qui sert au référencement"
alors l'utilisateur verra affiché "mon mot clef qui sert au référencement"
et le moteur de template verra {{mavariable}} 

pas glop

(ex j ai pris le premier de la recherche google, c'est pas le plus pertinent je trouve http://blog.octo.com/seo-spa-angular/ )
Non, je parlais uniquement de ne pas gérer l'échappement dans le moteur de template si tu réutilises la syntaxe XML (car l'échappement est déjà géré par ce qui parse le XML). Dans les deux cas, il faut taper la séquence échappée dans le template.

Et ouep, du coup, je suis d'accord avec la remarque de Ter Rowan: une template JVS obligera à faire pointer l'URI sur le template lui-même, qui chargera les données, alors qu'XSL permet de faire pointer l'URI sur le document XML contenant les données, et c'est ce document qui va appeler le template. Effectivement, ainsi, le moteur de recherche index la page des données au lieu de la page de template.
ben c'est pas moi qui implémente le moteur de template ... dans les deux cas faut gérer l'échappement soi-même donc c'est la même chose. sauf que c'est un simple caractère pour blade ...
On peut très bien faire les 2..
Si tu echappes 1 seule variable ça va, si tu as un bloc de plusieurs lignes ( genre pour montrer un code source) alors la technique du @{{var}} devient plus lourde que des balises encadrantes.
Oui, ça ne change rien, XML n'apporte rien de mieux dans ces cas là.
J'ai commencé à implémenter le mien : https://github.com/Zest-Engined/ZestTpl

Faut que je commente et documente un peu, de plus je n'ai implémenté qu'un seul parser (les variables).
Si quelqu'un veut en savoir un peu plus, j'expliquerai volontiers Smile

Sinon le principe est simple : On créé un objet Tpl, et via cet instance on va pouvoir gérer et configurer le cache, assigner des variables etc
La classe Tpl ne fait que gérer les classes qui gravitent autour.

Le cache est modifiable (par défaut écriture dans un fichier), mais on peut très bien passer un objet Cache qui écrit en BDD ou autre.

Il est prévu d'implémenter un système pour implémenter automatiquement des parsers persos et des tags, et de le rendre aussi extensible que possible.
\{\{ ?(.*) ?\}\} sera peut-être une regex trop large, surtout avec le drapeau s (DOT_ALL).

Attention à ce genre de fonction niveau injection:
Code PHP :
<?php 
public function write($filename, $content)
{
$filename = $this->cache_dir . $filename . $this->cache_suffix;
file_put_contents( $filename, $content);
}

Si $filename provient de l'extérieur, tu donnes accès à tout le système de fichier (ou presque). Note que même s'il ne vient pas de l'extérieur, la lecture du code actuel ne permet pas de s'en assurer, en d'autres mots, même si la variable $filename est sécurisée ailleurs, elle ne l'est pas ici, et donc il arrivera un jour où l'injection aura lieu (pas sûr que je sois bien clair).
Pareil pour l'autre méthode de cette même classe.

Manque les getter/setter à cette FileCache. Note que l'héritage est moins souple que la composition.

C'est une bonne chose que d'avoir tout mis dans un namespace principal Smile
N'oublie pas de commenter tout ça pour que ce soit réellement utilisable sur le long terme.
Attention à la licence GPL, qui peut-être trop raide pour certains cas (de mémoire, le code source d'une appli utilisant du code GPL doit être aussi GPL "ou presque").

J'ai pas regardé la logique de fond du code, mais ça semble pas mal sinon Smile J'ai toujours un peu de mal avec les eval() en revanche...

[edit] le ob_start() dans le constructeur du Viewer me semble mal venu: il va créer des effets de bord indésirable. Le constructeur devrait avoir seulement la charge de créer l'objet, pas celle de faire des traitements annexes. Le ob_start() (précédé d'un ob_clean?!) serait mieux placé dans la méthode display().
Merci pour ces remarques Xenos, comme d'habitude Smile

-C'est vrai que la regex est peu regardante, mais je prévois l'utilisation de variables comme suit : {{mon_objet->id | int | esc }} donc je ne peux pas être restrictif :/
Mais je pourrai virer le 's' au moins.

- L'injection : filename provient du développeur, qui a également en charge de vérifier le dossier 'cache'. Si on ne peut pas faire confiance aux dévs.. ^^ Cette partie (comme beaucoup) doit encore évoluer.

- FileCache : C'est mon moteur de cache, qu'il est possible de substituer par un autre (héritier de AClass).
AClass, classe abstraite, permet de définir les options du cache avec 'configure'. Ainsi, même si le développeur n'a pas accès à l'objet Cache, il peut tout de même en définir les options grâce à 'cache_configure' dans la classe Tpl.
Moins souple que la composition ?

- Oui c'est prévu de commenter et documenter un minimum sur GitHub.
Pour la license, oui c'est à peu près ça. Je pensais à MIT aussi, à voir.

- eval(), c'est la seule manière que j'ai trouvé pour pouvoir évaluer le code compilé provenant de n'importe quelle source.
En l'état j'aurai pu faire un require sur le cache (s'il est actif), mais si le cache est écrit en DB par exemple, impossible. Il faut que je teste plusieurs méthodes d'injection mais ça revient de toute façon au même qu'un include.

- En effet pour ob_start.

J'ai essayé de faire ça simplement en appliquant le principe SOLID. En revanche, j'ai toujours un peu de mal avec le principe de responsabilité unique (où est-ce qu'on arrête de déléguer ??? ^^ ).
Il manque beaucoup de choses (surtout niveau sécurité) même si ça n'a plus rien à voir avec le code d'origine..

Merci ! Smile
Pour la regex, j'aurai quand même dit que {{ a un peu trop de chances d'apparaitre pour autoriser une regex laxiste, mais c'est perso Smile.

En revanche, quand tu dis "$filename provient du développeur", tu regardes les processus et non les états. Or, si tu fais de l'OO, tu ne doit regarder que l'état, pas les processus, en d'autres mots: C'est Quoi? (OO) et non Ca vient d'où? (Procédural). Ici, $filename est une chaîne de caractères, donc, dans l'état des choses, tenter d'accéder à des dossiers type "../../../etc/" est une feature...

ACache force la présence des deux méthodes configure() et get_config(), et même interdit leur surcharge. Ce sera donc moins souple qu'une interface, ou qu'une composition (on peut imaginer que la configuration du cache est un autre objet qui décore ton FileCache).

Je dirai que GPL est hyper-restrictive pour un moteur de template... Mais c'est toi qui décide.

A la limite, eval() ne poserai pas de soucis si le dev peut choisir un autre Viewer, mais
Code PHP :
<?php 
protected function render()
{
// Affichage
$viewer = new Viewer();
$viewer->display($this->parsed_content, $this->getDataManager());
}
Force un Viewer... mieux vaut laisser le dev passer le Viewer à utiliser en paramètre au tpl.

Je pense d'ailleurs qu'il ne faut pas instancier puis utiliser dans le même bloc, mis à part s'il s'agit d'un genre de "Macro" pour raccourcir certaines chaînes de code récurrentes. Dans les autres cas, cela contraint trop les choses.
J'affinerai peut-être la regex lorsque j'implémenterai la possibilité d'afficher des objets ou array et tags.

Je vois ce que tu veux dire, mais je ne vois pas comment y remédier.
Puis, dans toutes librairies, il y a forcément un moment où le développeur doit faire attention à ce qu'il fait. Avec un très bon ORM, rien n'empêche de pouvoir récupérer des données via un input non vérifié par exemple. C'est le boulot du dév, pas de la lib.
Ici c'est pareil, si le dév ne définit pas correctement la config du cache, rien n'empêche d’accéder à n'importe quel fichier. Comment puis-je vérifier si la config fournie est correcte ? Je ne trouve pas.

En effet, ACache définit la manière de configurer la classe de cache. Je pense que l'idée est bonne de créer une autre classe gérant la config du cache.

En fait, j'ai choisi la GPL3 rapidement car elle oblige quelqu'un qui modifie le code à le publier. Mais je n'ai pas regardé plus loin et ne suis pas borné à rester sur cette licence.

Pouvoir utiliser une autre classe d'affichage est prévu, mais pas une priorité car je n'arrive pas à trouver d'autre méthode d'affichage que celle mise en place. Peut-être parce que je n'en ai pas l'utilité. Si vous en voyez une, je prends avec plaisir Smile

Je ne suis pas fan non plus du code que tu cites. Je pense mettre en place le même système que le cache dans le cas où il s'avère qu'un autre moteur de rendu serait utile.Dans tous les cas, le code sera mis au propre.

Merci encore Xenos pour tes commentaires très constructifs. Pour un amateur (et les autres aussi d'ailleurs), il est toujours très intéressant de recevoir de telles remarques qui poussent à l'amélioration.
Pages : 1 2 3 4