lollipop

A PHP-framework
Log | Files | Refs

Template.php (3413B)


      1 <?php
      2 
      3 namespace Lollipop {
      4     use ErrorException;
      5 
      6     /// this is the templating engine
      7     /// syntax:
      8     /// {{ $var }} will be replaces with the variable or nothing if not existend
      9     /// {{ "value" !func }} func will be called, popping things from the stack and pushing the result
     10     /// {{ $var "exist: %%" "doesnt exist" !format_if }} is an example
     11     class Template
     12     {
     13         private TemplateMethods $methods;
     14 
     15         public function __construct(TemplateMethods $methods)
     16         {
     17             $this->methods = $methods;
     18         }
     19 
     20         public function template(string $uri, array $data): string
     21         {
     22             /* this function takes a uri and a string array data */
     23             /* opens a stream to the uri specified file and stores the content in $file*/
     24 
     25             return $this->insert_data(file_get_contents($uri), $data);
     26         }
     27 
     28         private function insert_data(string $file, array $data): string
     29         {
     30             $html = "";
     31             $filesize = strlen($file);
     32 
     33             for($i = 0; $i < $filesize-1; $i++) {
     34                 if ($file[$i] == '{' && $file[$i + 1] == '{') {
     35                     for ($j = $i; $j < $filesize-1; $j++) {
     36                         if ($file[$j] == '}' && $file[$j + 1] == '}') {
     37                             $html .= $this->parse_template(trim(substr($file, $i + 2, $j - $i - 2)), $data);
     38                             $i = $j + 1;
     39                             break;
     40                         }
     41                     }
     42                 } else {
     43                     $html .= $file[$i];
     44                 }
     45             }
     46             return $html;
     47         }
     48 
     49         private function parse_template(string $expr, array $data)
     50         {
     51             $tokens = [];
     52             $in_string = false;
     53             $buffer = '';
     54 
     55             foreach (str_split($expr) as $c) {
     56                 if ($c == '"' && !$in_string) { // string start
     57                     $in_string = true;
     58                 } elseif ($c == '"') { // string end
     59                     $tokens[] = $buffer;
     60                     $buffer = '';
     61                     $in_string = false;
     62                 } elseif ($c == ' ' && !$in_string) {
     63                     if ($buffer) {
     64                         $tokens[] = $buffer;
     65                         $buffer = '';
     66                     }
     67                 } else {
     68                     $buffer .= $c;
     69                 }
     70             }
     71             if ($buffer) {
     72                 $tokens[] = $buffer;
     73             }
     74 
     75             return $this->eval_tokens($tokens, $data);
     76         }
     77 
     78         private function eval_tokens(array $tokens, array $data)
     79         {
     80             $stack = [];
     81             foreach ($tokens as $token) {
     82                 if ($token && $token[0] == '!') {
     83                     $val = $this->methods->{substr($token, 1)}($stack);
     84                     if (!is_null($val)) {
     85                         $stack[] = $val;
     86                     }
     87                 } elseif ($token && $token[0] == '$') {
     88                     $stack[] = array_key_exists(substr($token, 1), $data) ? $data[substr($token, 1)] : "";
     89                 } else {
     90                     $stack[] = $token;
     91                 }
     92             }
     93 
     94             if (sizeof($stack) > 1) {
     95                 throw new ErrorException("Stack-size is not 1");
     96             }
     97             if (sizeof($stack) == 0) {
     98                 return "";
     99             }
    100             return $stack[0];
    101         }
    102     }
    103 }