Klasa obsługi szablonów

2012-01-05 16:24:02 Post #1 Lirdoner

 
Witam, napisałem swoją pierwszą klasę obsługi szablonów. Nigdy wcześniej tego typu klasy nie pisałem i prosiłbym o ewentualne wskazanie błędów lub co mógłbym zmienić/dodać/zrobić lepiej
Jak na razie wszystko działa - szablony się poprawnie kompilują i poprawnie są wyświetlane
Aktualnie zrobiona jest obsługa
{$zmienna},
{if $warunek}(...){elseif $warunek2}(...){else}(...){/if},
{foreach $instrukcja} (...) {/foreach}
oraz includowanie innych plików szablonu

<?php
	class template {
	   private $compileDir;
       private $templateDir;
       private $variables = Array();
       
       public function setCompileDir($dir) {
        $src = substr($dir, -1);
        $src == "/" ? $this->compileDir = $dir : $this->compileDir = $dir."/";
       }
       
       public function setTemplateDir($dir) {
        $src = substr($dir, -1);
        $src == "/" ? $this->templateDir = $dir : $this->templateDir = $dir."/";
       }
       
       public function assign($name, $value) {
            $this->variables[$name] = $value;
       }
       
       public function assigns($value) {
        if(is_array($value)) {
            foreach($value as $key => $result) {
                self::assign($key, $result);
            }
        }
       }
       
       private function includeFile($file) {
        foreach($this->variables as $key=>$result) {
             $$key = $result;
        }
        if(file_exists($this->compileDir."template.".$file.".php")) {
            require_once($this->compileDir."template.".$file.".php");
        } else {
            self::compile($file);
        }
       }
       
       private function compile($tpl_file) {
        $content = file_get_contents($this->templateDir.$tpl_file);
        if(!empty($content)) {
            $content = preg_replace("#{include file=\"(.*)\"}#", "<?php self::includeFile('$1') ?>", $content);
            $content = preg_replace("#{if (.*)}#", "<?php if($1) { ?>", $content);
            $content = preg_replace("#{else}#", "<?php } else { ?>", $content);
            $content = preg_replace("#{elseif (.*)}#", "<?php } elseif($1) { ?>", $content);
            $content = preg_replace("#{/if}#", "<?php } ?>", $content);
            $content = preg_replace("#{foreach (.*)}#", "<?php foreach($1) { ?>", $content);
            $content = preg_replace("#{/foreach}#", "<?php } ?>", $content);
            $content = preg_replace("#{(.*)}#", "<?php echo $1 ?>", $content);
            
            $header = '
            <?php
                $MD5_FILE = "'.md5_file($this->templateDir.$tpl_file).'";
            ?>
            ';
            
            file_put_contents($this->compileDir."template.".$tpl_file.".php",$header.$content);
            self::display($tpl_file);
        } else {
            trigger_error("Cannot get information from tpl file", E_USER_ERROR);
            die();
        }
       }
       
       public function display($tpl_file) {
        if(!file_exists($this->templateDir.$tpl_file)) {
            trigger_error("Template file does not found in ".$this->templateDir.$tpl_file, E_USER_ERROR);
            die();
        }
        
        if(file_exists($this->compileDir."template.".$tpl_file.".php")) {
            foreach($this->variables as $key=>$result) {
                $$key = $result;
            }
            require_once($this->compileDir."template.".$tpl_file.".php");
            if($MD5_FILE != md5_file($this->templateDir.$tpl_file)) {
                @unlink($this->compileDir."template.".$tpl_file.".php");
                self::compile($tpl_file);
            }
        } else {
            self::compile($tpl_file);
        }
       }
       
    }
?>

2012-01-05 20:57:01 Post #2 Lirdoner

 
Zmieniłem trochę system, proszę o ocenę tego kodu (sry za zamieszanie)
<?php
	class template {
	   private $compileDir;
       private $templateDir;
       private $variables = Array();
       
       public function setCompileDir($dir) {
        $src = substr($dir, -1);
        $src == "/" ? $this->compileDir = $dir : $this->compileDir = $dir."/";
       }
       
       public function setTemplateDir($dir) {
        $src = substr($dir, -1);
        $src == "/" ? $this->templateDir = $dir : $this->templateDir = $dir."/";
       }
       
       public function assign($name, $value) {
            $this->variables[$name] = $value;
       }
       
       public function assigns($value) {
        if(is_array($value)) {
            foreach($value as $key => $result) {
                self::assign($key, $result);
            }
        }
       }
       
       private function includeFile($file) {
        if(file_exists($this->compileDir."template.".$file.".php")) {
            require_once($this->compileDir."template.".$file.".php");
        } else {
            self::compile($file);
        }
       }
       
       private function compile($tpl_file) {
        $content = file_get_contents($this->templateDir.$tpl_file);
        if(!empty($content)) {
            $content = preg_replace("#{include file=\"(.*)\"}#", "<?php self::includeFile('$1') ?>", $content);
            $content = preg_replace('#{(if|elseif) \$(.*) (==|!=|<|>|<=|>=) \$(.*)#', '<?php $1($this->variables[\'$2\'] $3 $this->variables[\'$4\']) { ?>', $content);
            $content = preg_replace('#{(if|elseif) \$(.*) (==|!=|<|>|<=|>=) ([A-Za-z0-9\_-\s\"]+)#', '<?php $1($this->variables[\'$2\'] $3 $4) { ?>', $content);
            $content = preg_replace("#{else}#", "<?php } else { ?>", $content);
            $content = preg_replace("#{/if}#", "<?php } ?>", $content);
            $content = preg_replace('#{foreach \$(.*) as (.*)}\r\n{(.*)\.(.*)}\r\n{/foreach}#iu', '{foreach $$1 as $2}'."\n".'<?php echo $2[\'$4\'] ?>'."\n".'{/foreach}', $content);
            $content = preg_replace('#{foreach \$(.*) as (.*)}#', '<?php foreach($this->variables[\'$1\'] as $2) {  ?>', $content);
            $content = preg_replace("#{/foreach}#", "<?php } ?>", $content);
            $content = preg_replace('#{\$(.*)}#', '<?php echo $this->variables[\'$1\'] ?>', $content);
            
            $header = '
            <?php
                $MD5_FILE = "'.md5_file($this->templateDir.$tpl_file).'";
            ?>
            ';
            
            file_put_contents($this->compileDir."template.".$tpl_file.".php",$header.$content);
            self::display($tpl_file);
        } else {
            trigger_error("Cannot get information from tpl file", E_USER_ERROR);
            die();
        }
       }
       
       public function display($tpl_file) {
        if(!file_exists($this->templateDir.$tpl_file)) {
            trigger_error("Template file does not found in ".$this->templateDir.$tpl_file, E_USER_ERROR);
            die();
        }
        
        if(file_exists($this->compileDir."template.".$tpl_file.".php")) {
            require_once($this->compileDir."template.".$tpl_file.".php");
            if($MD5_FILE != md5_file($this->templateDir.$tpl_file)) {
                @unlink($this->compileDir."template.".$tpl_file.".php");
                self::compile($tpl_file);
            }
        } else {
            self::compile($tpl_file);
        }
       }
       
    }
?>

2012-01-05 20:57:38 Post #3 nospor

 
Pierwszy i podstawowy błąd jaki robisz to fakt, że piszesz własną klasę do szablonów. Na rynku jest takich wiele a Ty lepszej nie napiszesz. Jedyne co za tym przemawia to być może kwestia edukacyjna, choć i w tym przypadku jest to argument mocno naciągany.

Z racji powyższego napiszę ci podstawowe błędy, których robić nie powinno się niezależnie od klasy. Nad samą klasą jaką klasą szablonów rozwodzić mi się nie chce.

1) Nie: "tekst"
a: 'tekst'
Nie ma sensu parsować tekstów, jeśli nie masz w nich zmiennych. Zbędna praca dla kompilatora

2) Nie:
preg_replace()
preg_replace()
preg_replace()
.....
a:
jedno preg_replace z tablicą jako argumentem.

3)
trigger_error("Template file does not found in ".$this->templateDir.$tpl_file, E_USER_ERROR);
die();
Nie masz prawa kończyć mi całego skryptu bo masz taką zachciewajkę.... ok, możesz zwrócic error, ale nie kończ mi skryptu. Ja decyduje kiedy kończę a nie Ty. Rzuć lepiej wyjątkiem zamiast trigger_error

2012-02-03 18:26:26 Post #4 guest_xxdrago

 
Mógłbyś jakaś polecić?

2012-02-03 18:45:46 Post #5 nospor

 
Ogólnie nie.
Sam zmierzam do tego, by nie uzywać żadnej klasy szablonów, tylko czegoś bardziej na wzór tego co jest w ZendFramework.

Ale jeśli już ktoś chce czegoś używać to tylko nie smarty - zbędna kobyła.
Ponoć OPT Zyxa jest ciekawe no i naszego rodaka

2012-02-04 23:16:01 Post #6 guest_xxdrago

 
A na tej stronie masz korzystasz z autorskiego systemu?

2012-02-06 10:51:10 Post #7 nospor

 
Z szablonów? Nie.
Cała reszta - tak

2012-02-07 11:28:56 Post #8 guest_xxdrago

 
To znaczy jak tą stronę napisałeś?

2012-02-07 11:30:48 Post #9 nospor

 
Nie kumam pytania

2012-02-07 11:38:33 Post #10 guest_XxDrago

 
Chodzi mi o to, jaki system szablonów zastosowałeś, na tej stronce. Albo jak to zrobiłeś jeżeli ich nie używałeś

2012-02-07 11:53:38 Post #11 nospor

 
No niestety tu jest smarty

2012-02-07 14:41:08 Post #12 guest_xxdrago

 
A tak, ci powiem patrzyłem, na to OPT, Smarty i ani to ani to mi nie pasuje. Potrzebowałbym taką klasę jak kolega wyżej dał znasz może coś podobnego? , żeby to w miarę poste było.

2012-02-07 14:46:24 Post #13 nospor

 
Nie znam

2012-02-27 22:16:27 Post #14 Michał

 
Twig: http://twig.sensiolabs.org/

2018-02-26 20:43:55 Post #15 guest_freeboc

 
Bardzo proszę wrzucić to na "dowcipy" (o przepraszam: 'dowcipy'):

[P1]
Sam zmierzam do tego, by nie uzywać żadnej klasy szablonów, tylko czegoś bardziej na wzór tego co jest w ZendFramework.
Ale jeśli już ktoś chce czegoś używać to tylko nie smarty - zbędna kobyła.
[P2]
To znaczy jak tą stronę napisałeś?
[P1]
No niestety tu jest smarty

Answer

Categories

  1. wszystkie wszystkie komentarze all (1)