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 gość_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 gość_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 gość_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 gość_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 gość_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/

Odpowiedz

Ostatnio komentowane

  1. ShoutBox nospor
  2. ShoutBox Artur
  3. PHP South Coast conf... nospor
  4. PHP South Coast conf... srednioZaawansowanyPHPowiec
  5. Docker - podstawowy ... nospor
  6. Docker - podstawowy ... Leelum
  7. Pager nospor

Skrypty użytkowników

  1. Klasa obsługi szablo... Lirdoner
  2. Sekcje user76
  3. Klasa walidująca for... user76
  4. Licznik Gości online korey
  5. Form Builder Comandeer
  6. Dynamiczny licznik z... korey
  7. Captcha Comandeer