Template.php (3413B) download
1<?php
2
3namespace 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}