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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
<?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_fileE_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)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
<?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_fileE_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

Odpowiedz