Partage
  • Partager sur Facebook
  • Partager sur Twitter

Ma classe de template

Ca faisait longtemps

    10 juillet 2006 à 17:54:06

    Hello les gens :)

    Après pleins d'autes zéros qui avaient postés leur classe de template, voici la mienne ! (j'en vois un déjà qui va criser : "php est déjà un système de template, blablabla", mais là c'est pas "inutile" ^^)
    Comme vous pouvez le voir, elle ne ressemble à aucune autre, mais en 72 lignes de codes (en enlevant les commentaires), elle gère les variables, blocs, et blocs infinis (sisi, je vous jure).
    Quand je dis : "elle ne ressemble à aucune autre", c'est surtout dans son utilisation en fait, qui est atypique. Regardez plutot l'exemple à la fin (désolé, mon anglais est horrible :s) :

    <?php

    // +----------------------------------------------------------------------+
    // | Copyright (c) Savageman 2006                                         |
    // +----------------------------------------------------------------------+
    // | Classe de gestion des templates.                                     |
    // |                                                                      |
    // | Veuillez me mailer pour toute suggestion ou amélioration à propos de |
    // | ce script. Merci!                                                    |
    // +----------------------------------------------------------------------+
    // | Author        : Savageman <savageman86@yahoo.fr>                     |
    // | Original      : Savageman <savageman86@yahoo.fr>                     |
    // | PHP Version   : PHP 5                                                |
    // | Created on    : July 10, 2006                                        |
    // | Last modified : July 10, 2006                                        |
    // +----------------------------------------------------------------------+

    /**
     *     How does it works ?
     *
     *  1. Load a template file (by calling the constructor).
     *  2. Assign vars to the template (by calling the <replace> method).
     *  3. You can make template as a block by calling the <next> method : you will be able to assign others vars to the template (without losing the precedent assignation).
     *  4. You can "continuate" (sorry, continue is a reserved keyword :s) which consist in insertion of text at the position of the continuation tag.
     *  5. You can assign the continuation tag by calling the <set_continuation> method.
     *  6. Once finished, call the <get> method to have the result returned (you can print it or insert it in a new template thanks to the continuation tag).
     *
     *  7. Hope you enjoy it (-:
     *
     */


    class Template {

        /**
         *     Publics vars
         */

            public  $delimitors = array();
            public  $continuation_tag;

            /**
         *     Privates vars
         */

            private $_template;             // Original template
            private $_current_text;         // Current occurence of the parsed template
            private $_final_text = array(); // Parsed template
           
            /**
         *     Constructor
         */

            public function __construct($filename = null, $vars = null) {
                    if (!empty($filename)) {
                            $this->load($filename);
                    }
                    if (!empty($vars)) {
                            $this->replace($vars);
                    }
              return true;
            }

            /**
         *     Publics methods
         */

            public function load($filename) {
                    if (!file_exists($filename) OR !is_file($filename)) {
                            trigger_error('template::load, file "'.$filename.'" not found.', E_USER_WARNING);
                      return false;
                    }
                    $this->delimitors = array('begin' => '£¤ ', 'end' => ' ¤£');
                    $this->continuation_tag = '¤£ continuation £¤';
                    $this->_template = file_get_contents($filename);
                    $this->_current_text = $this->_template;
              return true;
            }
           
            public function replace(array $vars = null, $append = false) {
                    if (!empty($vars)) {
                            $this->_current_text = str_replace(array_map(array($this, 'callback_var'), array_keys($vars)), array_values($vars), $this->_current_text);
                    }
                    if ((boolean)$append) {
                            $this->next();
                    }
              return true;
            }
           
            public function next() {
                    $this->_final_text[] = $this->_current_text;
                    $this->_current_text = $this->_template;       
            }
           
            public function continuate($text) {
                    // Gestion intellignete de l'indentation
                    $int1 = strpos($this->_current_text, $this->get_continuation_tag());
                    $int2 = strrpos($this->_current_text, "\n", $int1-strlen($this->_current_text));
                    $indent = substr($this->_current_text, $int2, $int1-$int2);
                    $text = str_replace("\n", $indent, $text);
                    $this->_current_text = str_replace($this->get_continuation_tag(), $text, $this->_current_text);
              return true;
            }
           
            public function set_continuation() {
                    $this->_final_text[] = $this->get_continuation_tag();
              return true;
            }
           
            public function get() {
              return preg_replace('`\s*'.preg_quote($this->delimitors['begin']).'.*?'.preg_quote($this->delimitors['end']).'`', '', implode("\n", $this->_final_text));
            }

            /**
         *     Privates methods
         */

            private function callback_var($varname) {
              return $this->delimitors['begin'].$varname.$this->delimitors['end'];
            }
           
            private function get_continuation_tag() {
              return $this->continuation_tag;
            }
    }

    /**
     *     Example
     */


    // Main template
    $main_view = new template('xhtml1.tpl');

    $main_view->replace(array('title'=>'Titre de ma page', 'author' => 'Moi :D'));

    // Another template
    $news_view = new template('news.tpl');

    $news_view->replace(array('news.titre'=>'titre 1', 'news.texte' => 'texte 1'));
    $news_view->next();
    $news_view->replace(array('news.titre'=>'titre 2', 'news.texte' => 'texte 2'));
    $news_view->next();
    //$news_view->set_continuation(); // Optional (non needed if you have nothing to insert)

    // We put the parsed news template in the main template (note that if we set the continuation tag, we should insert other parsed template in the main template)
    $main_view->continuate($news_view->get());

    // Be sure to ALWAYS call the <next> method before to call the <get> method
    $main_view->next();
    echo $main_view->get();

    ?>


    J'attend des remarques et commentaires :)

    [edit] les templates :

    xhtml1.tpl :
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">

    <html xmlns="http://www.w3.org/1999/xhtml" lang="fr" xml:lang="fr">

    <head>

            <title>£¤ title ¤£</title>

            <meta http-equiv="Content-Language" content="fr,en" />
            <meta http-equiv="Content-type"     content="text/html; charset=iso-8859-1" />

    £¤ rss ¤£

    £¤ icon ¤£

            <meta name="author"      content="£¤ author ¤£" />
            <meta name="description" content="£¤ description ¤£" />
            <meta name="keywords"    content="£¤ keywords ¤£" />

    £¤ css ¤£
    £¤ js ¤£
           
    £¤ extra ¤£

    </head>

    <body>

            ¤£ continuation £¤

    </body>

    </html>


    news.tpl :
    <div class="news">
            <h3>£¤ news.titre ¤£</h3>
            <p>
                    £¤ news.texte ¤£
            </p>
    </div>

    • Partager sur Facebook
    • Partager sur Twitter
      10 juillet 2006 à 17:56:48

      Il gere aps les multi fichiers ton truc :p
      • Partager sur Facebook
      • Partager sur Twitter
      Mon profil Github - Zeste de Savoir, pour la beauté du zeste
        10 juillet 2006 à 21:36:34

        Gestion de plusieurs fichiers : aps besoin d'instncier plusieurs fois le moteur.
        • Partager sur Facebook
        • Partager sur Twitter
        Mon profil Github - Zeste de Savoir, pour la beauté du zeste
          10 juillet 2006 à 21:42:57

          Ah bah c'est une petite classe, c'est pas fait pour...
          Le but d'une classe c'est pas d'avoir une seule instance, tu sais...
          • Partager sur Facebook
          • Partager sur Twitter
            10 juillet 2006 à 21:50:05

            Perso, je comprend pas l'utilité de la méthode next(), tu peux l'expliquer?
            • Partager sur Facebook
            • Partager sur Twitter
              10 juillet 2006 à 21:51:25

              J'a beau tourner la class dans tous les sens je vois aps commencer inserer un blo dans le tpl ???

              Tu Peux preciser stp :)
              • Partager sur Facebook
              • Partager sur Twitter
                10 juillet 2006 à 21:55:41

                How does it works ?
                Moi je veux juste savoir pourquoi ça "parles anglais" dans ce truc ? :(
                • Partager sur Facebook
                • Partager sur Twitter
                  10 juillet 2006 à 21:56:03

                  Bah en fait, une instance, c'est un bloc (ou c'est pas un bloc si tu ne veux pas que ça soit un bloc)

                  Dans l'exemple, c'est
                  "$news_view = new template('news.tpl');".

                  Puis en utilisant next(), tu peux répéter ce template (news.tpl ici) autant de fois que tu veux, mais avec des variables (des valeurs) différentes.

                  Ensuite, tu le parses et tu l'insères dans un autre :) (grâce au tag continuation, c'est un peu compliqué à comprendre quand on a pas créé le truc, même si j'ai essayé de l'expliquer en anglais dans les commentaires.

                  Ca me fait penser : il manque les fichiers .tpl, je vais les rajouter dans mon premier message.

                  [edit]

                  Citation : Bison

                  How does it works ?
                  Moi je veux juste savoir pourquoi ça "parles anglais" dans ce truc ?


                  Heu, c'est pour la distibution, l'international, toussa quoi. Mais bon, vu mon niveau d'anglais, je le ferai corriger avant, c'est certain !
                  • Partager sur Facebook
                  • Partager sur Twitter
                    10 juillet 2006 à 22:03:55

                    moi je dis il est pas courant le parsage des blocs ( qui parse pas les blocs du tout :-° mais les variables ^^ )

                    Tu peux nous en dire plus là dessus ? Merci d'Avance :)
                    • Partager sur Facebook
                    • Partager sur Twitter
                      10 juillet 2006 à 22:05:58

                      J'ai pas dit que ça "parsait" des bloc, mais que ca *gérait* les blocs, c'est assez différent...
                      Mon script ne parse effetivement que les variables.
                      Sinon j'ai mis les .tpl, comme ça vous pouvez le tester en live cherz vous ;) (PHP 5 requis)
                      • Partager sur Facebook
                      • Partager sur Twitter
                        10 juillet 2006 à 22:13:22

                        J'ai testé ....
                        Mais une classe qui gère uniquement les variables j'ai ça en une trentaine de lignes ( et encore c'est beaucoup ) :lol:

                        Jcherche toujours une class Simple Qui montre comment parser des blocs ( pour affichage multiple, ... ) ^^ Si quelqu'un pouvait me donner un exemple ou même l'idée ... merci :)
                        • Partager sur Facebook
                        • Partager sur Twitter
                          10 juillet 2006 à 22:22:26

                          Je connais ces classes mais le simple est pas inclus là :p sauf peut-être sur celle de bluestorm :p

                          EDIT : Enfin il n'y en a aucune qui soit assez simple a comprendre si on l'a pas codée et qui puisse s'integrer facilement dans ma classe de template ( c'est surtout pour les boucles ( un système de news par ex ) que je bloque :( )

                          Merci quand même ;)
                          • Partager sur Facebook
                          • Partager sur Twitter
                            10 juillet 2006 à 22:26:33

                            Oué, bah la mienne est simple, et me permet de gérer efficacement les blocks et variables et d'obtenir une bonne indetation dans le code final (html) : tout ce qu'il y a besoin.
                            Vu la façon dont c'est géré, ca ne doit franchement pas ralentir le script, et ca permet un certain confort d'utilisation !
                            J'ai rien d'aute pour toi, désolé...
                            • Partager sur Facebook
                            • Partager sur Twitter
                              10 juillet 2006 à 22:28:41

                              La tienne gère les blocs mais ne les parse pas
                              J'ai testé elle est assez rapide ;)

                              Mais je vois pas comment faire un affichage de news avec ta classe
                              • Partager sur Facebook
                              • Partager sur Twitter
                                10 juillet 2006 à 22:33:51

                                Avec le template news.tpl fournit :


                                $news_view = new template('news.tpl');

                                $news_view->replace(array('news.titre'=>'titre 1', 'news.texte' => 'texte 1'));
                                $news_view->next();
                                $news_view->replace(array('news.titre'=>'titre 2', 'news.texte' => 'texte 2'));
                                $news_view->next();

                                echo $news_view->get();


                                [edit] news.tpl n'est bien chargé qu'une fois, et on à affiché 2 news : il y a bien un "block" news, qui correpond à la classe complète.
                                • Partager sur Facebook
                                • Partager sur Twitter
                                  10 juillet 2006 à 22:47:20

                                  Ah Wé .... Je vois comment fonctionne ton système...
                                  Il fait un replace stocké dans une autre variable et reprend la variable avec le bloc...

                                  Je n'y Avais jamais pensé... Ingénieux ;)
                                  • Partager sur Facebook
                                  • Partager sur Twitter
                                    11 juillet 2006 à 11:13:00

                                    Ingénieux, en effet.

                                    JE tiens à preciser que mon moteur "PlatEngine !" est en refonte, enfin peut-etre ^^
                                    • Partager sur Facebook
                                    • Partager sur Twitter
                                    Mon profil Github - Zeste de Savoir, pour la beauté du zeste

                                    Ma classe de template

                                    × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
                                    × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
                                    • Editeur
                                    • Markdown