title: if and foreach in a templating engine
body: <p>I'm working on a templating engine (I don't want to use an already existing one) and it works fine. This is the code I have now:</p>
  
  <pre><code>class template {
  
      private $vars = array();
      public $page;
  
      function __construct() {
      }
  
      public function render($render = false) {
              $page = $this-&gt;page . '.php';
              $content = file_get_contents($page);
  
              foreach ($this-&gt;vars as $key =&gt; $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-&gt;vars[$key] = $value;
          } else if (isset($this-&gt;vars[$key])) {
              echo 'this var already exists!';
          } else {
              $this-&gt;vars[$key] = $value;
          }
      }
  
      public function append($key, $value) {
          $this-&gt;vars[$key] .= $value;
      }
  
      public function setPage($page) {
          $this-&gt;page = $page;
      }
  
  }
  </code></pre>
  
  <p>but I was wondering how I could add if &amp; elses and foreach loops to the engine. I want it to look something like this in the html:</p>
  
  <pre><code>&lt;!DOCTYPE html&gt;
  &lt;html&gt;
      &lt;head&gt;&lt;/head&gt;        
      &lt;body&gt;
          [@if {bool} == true][ &lt;!-- different expressions like {int} &gt; 2 should work too --&gt;
              &lt;div&gt;{text}&lt;/div&gt;
          ]
          [@else][
              &lt;div&gt; error &lt;/div&gt;
          ]
  
          [@foreach {jsLinks} as {jsLink}][
              &lt;script type="text/javascript" src="{jsLink}"&gt;&lt;/script&gt;
          ]
      &lt;/body&gt;
  &lt;/html&gt;
  </code></pre>
  
  <p>the template files are saved as .php files, so I could do <code>&lt;?php if($bool == true){?&gt; some html &lt;?php  }?&gt;</code>,
  but I don't want to use php code in the templating files.
  Can anyone please help me with this?</p>
  
  <p><strong>EDIT</strong></p>
  
  <p>I added this code:</p>
  
  <pre><code>$content = preg_replace('~\{LOOP:(\w+)\}~', '&lt;?php foreach ($this-&gt;vars[\'$1\'] as $ELEMENT): $this-&gt;wrap($ELEMENT); ?&gt;', $content);
  $content = preg_replace('~\{ENDLOOP:(\w+)\}~', '&lt;?php $this-&gt;unwrap(); endforeach; ?&gt;', $content);
  </code></pre>
  
  <p>and these two functions:</p>
  
  <pre><code>private function wrap($element){
      $this-&gt;stack[] = $this-&gt;vars;
      foreach ($element as $k =&gt; $v) {
          $this-&gt;vars[$k] = $v;
      }
  }
  
  private function unwrap() {
      $this-&gt;vars = array_pop($this-&gt;stack);
  }
  </code></pre>
  
  <p>but this just echoes <code>&lt;?php foreach ($this-&gt;vars[\'$1\'] as $ELEMENT): $this-&gt;wrap($ELEMENT); ?&gt;</code> and <code>&lt;?php $this-&gt;unwrap(); endforeach; ?&gt;</code> literally in the browser. Any way to fix this?</p>
  
  <p><strong>EDIT: I did it!</strong></p>
  
  <p>I can now use foreach loops and ifs and elses in my templates. My template class:</p>
  
  <pre><code>&lt;?php
  
  class Template {
  
      private $vars = array();
      public $page;
      public $view;
      public $bDisplay = true;
  
      function __construct($view = false) {
          $this-&gt;view = $view;
      }
  
      public function render($render = false) {
          if ($this-&gt;bDisplay === true) {
              $page = PATH_VIEWS . $this-&gt;page . '.php';
              $page = (empty($this-&gt;page) ? ($this-&gt;view ? PATH_VIEWS . $this-&gt;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-&gt;replace($content, $this-&gt;vars);
  
              $content = preg_replace('~\{LOOP:(\w+)\}~', '&lt;?php foreach ($this-&gt;vars[\'$1\'] as $value){ echo  $this-&gt;replace(\'', $content);
              $content = preg_replace('~\{ENDLOOP:(\w+)\}~', '\', $value);} ?&gt;', $content);
  
              $content = preg_replace('~\{IF:([^\r\n}]+)\}~', '&lt;?php if ($1): echo \'', $content);
              $content = preg_replace('~\{ELSE\}~', '\'; else: echo \'', $content);
              $content = preg_replace('~\{ENDIF\}~', '\'; endif; ?&gt;', $content);
  
  
              if ($render)
                  eval('?&gt;' . $content . '&lt;?php');
              else
                  return $content;
          }
          else {
              return false;
          }
      }
  
      private function replace($content, $vars) {
          foreach ($vars as $key =&gt; $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-&gt;vars[$key] = $value;
          } else if (isset($this-&gt;vars[$key])) {
              echo 'this var already exists!';
          } else {
              $this-&gt;vars[$key] = $value;
          }
      }
  
      public function append($key, $value) {
          $this-&gt;vars[$key] .= $value;
      }
  
      public function addArray($array, $key, $value) {
          $this-&gt;vars[$array][][$key] = $value;
      }
  
      public function setPage($page) {
          $this-&gt;page = $page;
      }
  
  }
  
  ?&gt;
  </code></pre>
  
  <p>with as example template:</p>
  
  <pre><code>&lt;!DOCTYPE html&gt;
  &lt;html&gt;
      &lt;head&gt;&lt;/head&gt;
      &lt;body&gt;
          &lt;!-- foreach loops --&gt;
          {LOOP:js}
          &lt;script type="text/javascript" src="{link}"&gt;&lt;/script&gt;
          {ENDLOOP}
  
          &lt;!-- if statement --&gt;        
          {IF: {bool} === true}
          display some text
          {ENDIF}
  
          &lt;!-- if-else statement --&gt;        
          {IF: {number} &gt; 2}
          number is bigger than 2
          {ELSE}
          number is smaller than 2
          {ENDIF}
  
      &lt;/body&gt;
  &lt;/html&gt;
  </code></pre>