2014-04-06 2 views
0

템플릿 엔진에서 작업하고 있습니다. (기존 템플릿을 사용하고 싶지는 않습니다.) 제대로 작동합니다. 이것은 내가 지금 가지고있는 코드입니다 :if 및 foreach가 템플릿 엔진

class template { 

    private $vars = array(); 
    public $page; 

    function __construct() { 
    } 

    public function render($render = false) { 
      $page = $this->page . '.php'; 
      $content = file_get_contents($page); 

      foreach ($this->vars as $key => $value) { 
       $tag = '{' . $key . '}'; 
       $content = str_replace($tag, $value, $content); 
      } 

      if ($render) 
       echo $content; 
      else 
       return $content; 
    } 

    public function assign($key, $value, $overwrite = false) { 
     if ($overwrite) { 
      $this->vars[$key] = $value; 
     } else if (isset($this->vars[$key])) { 
      echo 'this var already exists!'; 
     } else { 
      $this->vars[$key] = $value; 
     } 
    } 

    public function append($key, $value) { 
     $this->vars[$key] .= $value; 
    } 

    public function setPage($page) { 
     $this->page = $page; 
    } 

} 

하지만 난 엔진에 & 경우를 elses와 foreach는 루프를 추가 할 수 있는지 궁금했다. 나는 그것이 HTML에서 같은 것을보고 싶지 :

<!DOCTYPE html> 
<html> 
    <head></head>   
    <body> 
     [@if {bool} == true][ <!-- different expressions like {int} > 2 should work too --> 
      <div>{text}</div> 
     ] 
     [@else][ 
      <div> error </div> 
     ] 

     [@foreach {jsLinks} as {jsLink}][ 
      <script type="text/javascript" src="{jsLink}"></script> 
     ] 
    </body> 
</html> 

템플릿 파일이 .PHP 파일로 저장됩니다, 그래서 <?php if($bool == true){?> some html <?php }?>, 을 할 수 있지만이 템플릿 파일에 PHP 코드를 사용하지 않으려는 . 아무도 도와 주실 수 있습니까?

$content = preg_replace('~\{LOOP:(\w+)\}~', '<?php foreach ($this->vars[\'$1\'] as $ELEMENT): $this->wrap($ELEMENT); ?>', $content); 
$content = preg_replace('~\{ENDLOOP:(\w+)\}~', '<?php $this->unwrap(); endforeach; ?>', $content); 

이러한 두 가지 기능 :

편집은이 코드를 추가

private function wrap($element){ 
    $this->stack[] = $this->vars; 
    foreach ($element as $k => $v) { 
     $this->vars[$k] = $v; 
    } 
} 

private function unwrap() { 
    $this->vars = array_pop($this->stack); 
} 

을하지만, 이것은 단지 브라우저에서 그대로 <?php foreach ($this->vars[\'$1\'] as $ELEMENT): $this->wrap($ELEMENT); ?><?php $this->unwrap(); endforeach; ?> 메아리. 이 문제를 해결할 방법이 있습니까?

편집 : 해냈어!

이제 내 템플릿에서 foreach 루프와 ifs 및 elses를 사용할 수 있습니다. 내 템플릿 클래스 : 예제 템플릿 등으로

<?php 

class Template { 

    private $vars = array(); 
    public $page; 
    public $view; 
    public $bDisplay = true; 

    function __construct($view = false) { 
     $this->view = $view; 
    } 

    public function render($render = false) { 
     if ($this->bDisplay === true) { 
      $page = PATH_VIEWS . $this->page . '.php'; 
      $page = (empty($this->page) ? ($this->view ? PATH_VIEWS . $this->view . DS . 'index.php' : PATH_VIEWS . 'index' . DS . 'index.php') : (file_exists($page) ? $page : PATH_VIEWS . 'index' . DS . 'index.php')); 
      $content = file_get_contents($page); 

      $content = $this->replace($content, $this->vars); 

      $content = preg_replace('~\{LOOP:(\w+)\}~', '<?php foreach ($this->vars[\'$1\'] as $value){ echo $this->replace(\'', $content); 
      $content = preg_replace('~\{ENDLOOP:(\w+)\}~', '\', $value);} ?>', $content); 

      $content = preg_replace('~\{IF:([^\r\n}]+)\}~', '<?php if ($1): echo \'', $content); 
      $content = preg_replace('~\{ELSE\}~', '\'; else: echo \'', $content); 
      $content = preg_replace('~\{ENDIF\}~', '\'; endif; ?>', $content); 


      if ($render) 
       eval('?>' . $content . '<?php'); 
      else 
       return $content; 
     } 
     else { 
      return false; 
     } 
    } 

    private function replace($content, $vars) { 
     foreach ($vars as $key => $value) { 
      if (!is_array($vars[$key])) { 
       $tag = '{' . $key . '}'; 
       $content = str_replace($tag, $value, $content); 
      } 
     } 

     return $content; 
    } 

    public function assign($key, $value, $overwrite = false) { 
     if ($overwrite) { 
      $this->vars[$key] = $value; 
     } else if (isset($this->vars[$key])) { 
      echo 'this var already exists!'; 
     } else { 
      $this->vars[$key] = $value; 
     } 
    } 

    public function append($key, $value) { 
     $this->vars[$key] .= $value; 
    } 

    public function addArray($array, $key, $value) { 
     $this->vars[$array][][$key] = $value; 
    } 

    public function setPage($page) { 
     $this->page = $page; 
    } 

} 

?> 

:

<!DOCTYPE html> 
<html> 
    <head></head> 
    <body> 
     <!-- foreach loops --> 
     {LOOP:js} 
     <script type="text/javascript" src="{link}"></script> 
     {ENDLOOP} 

     <!-- if statement -->   
     {IF: {bool} === true} 
     display some text 
     {ENDIF} 

     <!-- if-else statement -->   
     {IF: {number} > 2} 
     number is bigger than 2 
     {ELSE} 
     number is smaller than 2 
     {ENDIF} 

    </body> 
</html> 
+1

파서를 구현하거나 더 나은 변환기를 만들어 해당 템플릿 파일의 처리기로 등록해야합니다. 유닉스 시스템에서 일반적으로 볼 수있는 "컴파일러 컴파일러"인 bison과 yacc를 살펴볼 수 있습니다. – arkascha

답변

1

있는 유일한 방법은 컨버터를 작성하는 것입니다. 예를 들어, 템플릿을 구문 분석하고 [@if {bool} == true]<?php if ($bool == true): ?>으로 변환하십시오.

+0

그리고 어떻게해야합니까? 정규 표현식? – Jonan

+1

예, 정규식은 좋은 방법입니다. –

+1

또한 여기에서보십시오 https://github.com/fabpot/Twig/blob/master/lib/Twig/ExpressionParser.php 첫 번째 주석은 파서가 "선행 등반"알고리즘을 사용한다고 말합니다. –