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

Recently commented

  1. ShoutBox Podświadomość
  2. ShoutBox Trilux
  3. ShoutBox morelowy-dolomit
  4. ShoutBox Lucidoremi
  5. ShoutBox Goran Lezczek
  6. ShoutBox Ktos
  7. Opcje dwuwartościowe... gosc

Latest on forum

  1. Wykładziny dywanowe Wykładziny dywanowe
  2. Aparat ortodontyczny... Aparat ortodontyczny ceny
  3. Bonding zębów w Gdań... Bonding zębów w Gdańsku
  4. Podnośniki Podnośniki
  5. Podnośniki towarowe Podnośniki towarowe
  6. Podest roboczy Podest roboczy
  7. Naświetlacz LED 30W Naświetlacz LED 30W

Categories

  1. wszystkie wszystkie komentarze all (1)