Rev Author Line No. Line
4985 kaklik 1 <?php
2  
3 // Template Engine
4 // ---------------
5 //
6 // Tento modul zpracovává tmplejty a strká do nich dynamicky generované
7 // informace a vytváří tak dynamické HTML stránky s oddělenou logikou
8 // programu a vzhledu.
9 //
10 // Více viz popis činnosti v konentáři na začátku templejtu
11 //
12 // (c)miho www.mlab.cz 2007, free software
13 //
14 // Typické použití objektu je toto:
15 //
16 // - Založ objekt templejtu (new)
17 // - $Template = new TemplateEngine();
18 //
19 // - Načti templejt ze souboru do objektu (ošetři chybu!)
20 // - $error = $Template->LoadTemplate($TemplateFile);
21 //
22 // - Tady se provádí generování masa, je možné použít proměnné,
23 // - modifikovat proměnné a nechat provéstsubstituce v proměnných
24 // - do řetězců.
25 //
26 // $Template->SetVariable('InfoTitle','Generovaný seznam');
27 // - první parametr je jméno proměnné, druhý je jeho nový obsah
28 //
29 // $Line = $Template->GetVariable('InfoLine')
30 // - vrací obsah proměnné nebo prázdný řetězec
31 //
32 // - Připrav si proměnné, které se budou strkat do vzorového řetězce
33 // $Variables[InfoName] = 'nějaká informace pro proměnnou InfoName';
34 // $Variables[InfoPicture] = 'jiná informace pro proměnnou InfoPicture';
35 // - aplikuj (nahraď) proměnné na vzorový řetězec z propměnné 'InfoLine'
36 // $Line = $Template->Substitute($Variables, $Template->GetVariable('InfoLine'));
37 //
38 // - Nakonec se aplikují proměnné do nataženého templejtu a výsledek
39 // - se pošle klientovi
40 // echo $Template->GetPage();
41 //
42  
43  
44 // Objekt pro zpracování templejtu
45 class TemplateEngine
46 {
47  
48 private $Page; // Sem se načte templejt a zde se provádí substituce
49 private $Info; // Sem se načtou z templejtu proměnné
50  
51  
4986 kaklik 52 function ListInfo(): void
4985 kaklik 53 // Vypíše nalezené proměnné a jejich hodnoty
54 // Pouze pro ladění
55 {
56 echo "[ ListInfo:\n";
57 print_r($this->Info);
58 echo ']';
59 }
60  
61  
62 function LoadTemplate($TemplateFileName, $Lang)
63 // Načte templejt ze souboru, při chybě vrací chybový řetězec
64 // Snaží se rozumně využít informaci o jazyku k otevření správné verze
65 // templejtu. Cesta se zadává bez jazykové části ale s příponou.
66 {
67 // Vlož zadaný jazyk do názvu souboru
68 $TemplateFileName = LangFile($TemplateFileName, $Lang);
69  
70 // Načti template ze souboru (po řádcích do pole)
71 $this->Page = @file($TemplateFileName);
72 if ($this->Page=='')
73 return 'Unable Open Template File';
74  
75 // Sestav z pole jeden retězec
76 $this->Page = implode($this->Page);
77  
78  
79 // Definice regulárních výrazů pro hledání
80 // ---------------------------------------
81  
82 // Definice vzoru pro hledání komentáře ve tvaru <!-- -->
83 // Komentář je nepojmenované pole
84 // Před a za koentářem mohou být bílé znaky
85 // Uvnitř komentáře nesmí být znak >
86 $PatternComment = '(?:\s*<!--[^>]*--\s*>\s*)';
87 // (?: nepojemnované pole
88 // \s* volitelné bílé znaky před
89 // <!-- začátek komentáře
90 // [^>]* vniřek komentáře (neobsahuje >)
91 // --\s*> konec komentáře
92 // \s* volitelné bílé znaky za komentářem
93 // ) tady končí komentář
94  
95 // Definice vzoru pro hledání proměnných ve tvaru $InfoXXX
96 $PatternVar ='\$(?P<VarName>Info[a-z,A-Z,0-9,\-\_]+)';
97 // \$ na začátku $
98 // (?P<VarName> pojmenované pole VarName je (jméno proměnné bez dolaru)
99 // Info[a-z,A-Z,0-9,\-\_]+ proměnná začíná Info a pak jsou písmena,
100 // ) číslice, mínus a podtržítko
101  
102 // Definice vzoru pro hledání hodnot proměnných ve tvaru = " Hodnota "
103 // Definice hodnot je ve tvaru $InfoXXX="YYY" a mohou být víceřádkové
104 // ( a mohou obsahovat uvnitř další substituce uvozené $, které program
105 // zpracovává ale ne tady)
106 $PatternValue = '\s*=\s*"(?P<VarValue>[^"]*)"';
107 // \s*=\s* rovná se volitelnými bílými znaky okolo
108 // " hodnota v uvozovkách
109 // (?P<VarValue> parametr s názvem VarValue
110 // [^"]* hodnota nesmí obsahovat uvozovky
111 // ) vracíme hodnotu bez uvozovek
112 // " konec uvozovek
113  
114 // Zparacování vzoru
115 // -----------------
116  
117 // Najdi na začátku stránky komentář a vykousni ho
118 $pattern = '/^' .$PatternComment. '+/su';
119 $this->Page = preg_replace($pattern, '', $this->Page);
120 // / oddělovač
121 // ^ od začátku řetězce (jen komentáře na začátku souboru)
122 // $PatternComment komentář (<!-- -->) s bílými znaky okolo
123 // + alespoň jeden komentář
124 // /su modifikátor, . zastupuje i odřádkování, utf8
125  
126  
127 // Najdi v templejtu substutuční proměnné a vytvoř v poli $Info
128 // prázdné položky pro každou použitou proměnnou. Dělá se to proto,
129 // aby se na konci nepoužité proměnné nahradily prázdným řetězcem.
130 $pattern = '/' .$PatternVar. '/su';
131 preg_match_all($pattern, $this->Page, $temp);
132 // / oddělovač
133 // .$PatternVar. proměnná ( $InfoXXX ) - parametr VarName
134 // /su modifikátor zajistí, že . zastupuje i odřádkování, utf8
135 foreach($temp['VarName'] as $key => $value)
136 $this->Info[$value] = '';
137 unset($temp);
138  
139 // Vytáhni proměnné a jejich hodnoty do pole $Info
140 $pattern = '/' .$PatternVar.$PatternValue. '/su';
141 // / oddělovač
142 // .$PatternVar. proměnná ( $InfoXXX ) - parametr VarName
143 // .$PatternValue. přiřazení ( = " Hodnota " ) - parametr VarValue
144 // /su modifikátor, . zastupuje i odřádkování, UTF8
145 preg_match_all($pattern, $this->Page, $temp);
146 foreach($temp['VarName'] as $key => $value)
147 $this->Info[$value] = $temp['VarValue'][$key];
148 unset($temp);
149  
150 // Vykousej zpracované definice proměnných (a komentáře před nimi)
151 $pattern = '/' .$PatternComment.'?'.$PatternVar.$PatternValue. '/su';
152 // / oddělovač
153 // .$PatternComment.'?' volitelný komentář před definicí
154 // .$PatternVar. proměnná ( $InfoXXX )
155 // .$PatternValue. přiřazení ( = " Hodnota " )
156 // /su modifikátor, . zastupuje i odřádkování, UTF8
157 $this->Page = preg_replace($pattern, '', $this->Page);
158 }
159  
160 function Indent($StringData, $Indent)
161 // Všechna odřádkování v řetězci $StringData odsadí o hodnotu $Indent pokud je
162 // $Indent číslo nebo o déllku řetězce $Indent pokud je to řetězec
163 {
164 // Velikost odsazení (vyrob číslo)
165 if (is_string($Indent))
166 $Num = mb_strlen($Indent,'utf-8');
167 else
168 $Num = 0+$Indent;
169  
170 // Odsazení
171 return $StringData = $Indent.str_replace("\n", "\n".str_repeat(' ', $Num), $StringData);
172 }
173  
174  
175 /*
176 function Substitute($Variables, $String)
177 // Nahradí proměnné v řetězci $String obsahem proměnných z pole $Variables
178 // a vrátí výsledný řetězec
179 {
180 if (is_array($Variables))
181 {
182 foreach($Variables as $Key => $Value)
183 {
184 // Hledací vzor (hledáme proměnnou s názvem v $Key)
185 $Pattern = '\$'.$Key.'(?=[^a-z,A-Z,0-9,\-\_])';
186 // \$$Key hledáme $JmenoProměnné
187 // (?= následuje něco, co nemůže být jménem
188 // [^a-z,A-Z,0-9,\-\_] a nezajímá nás
189 // )
190  
191 // Vkládáme více řádek?
192 $IsMultiline = !(strpos($Value, "\n") === FALSE);
193  
194 if (!$IsMultiline)
195 {
196 // Vkládáme jednoduchý řetězec
197 $String = preg_replace('/'.$Pattern.'/su', $Value, $String);
198 // /su víceřádkové v UTF8
199 }
200 else
201 {
202 // Vkládáme řetezec s odřádkováním - je třeba odsazovat
203 $String = preg_replace('/(.*)'.$Pattern.'/ue',
204 "\$this->Indent(\$Value, '\\1')",
205 $String);
206 // (.*) hledáme cokoli před vzorem -> první parametr
207 // .$Pattern. proměnná
208 // /ue UTF8, náhrada je php skriptem
209 }
210 }
211 }
212  
213 return $String;
214 }
215 */
216  
217  
218 function Substitute($Variables, $String)
219 // Nahradí proměnné v řetězci $String obsahem proměnných z pole $Variables
220 // a vrátí výsledný řetězec
221 {
222 // Hledací vzor
223 $Pattern = '/(.*?)\$(Info[a-z,A-Z,0-9,\-\_]+)(?=[^a-z,A-Z,0-9,\-\_])/ue';
224  
225 // Náhrada s kusem php kódu (nezapomeň, že preg_replace s přepínačem /e vrací oescapované řetězce)
226 $String = preg_replace($Pattern,
227 'isset($Variables[\'\2\'])
228 ? $this->Indent($Variables[\'\2\'], stripslashes(\'\1\'))
229 : stripslashes(\'\1\')
230 ',
231 $String);
232 return $String;
233 }
234  
235  
4986 kaklik 236 function SetVariable($VarName, $VarValue, $Wrap=0): void
4985 kaklik 237 // Nastaví hodnotu proměnné
238 // Volitelně provede zálámání na zadaný počet znaků a odstranění nadbytečných mezer
239 {
240 // Volitelné zalámání a odstranění bílých znaků
241 if ($Wrap!=0)
242 $VarValue = WrapString($VarValue, $Wrap);
243  
244 // Uložení do proměnných
245 $this->Info[$VarName] = $VarValue;
246 }
247  
248  
249 function GetVariable($VarName)
250 // Vrátí hodnotu proměnné tak, jak je, včetně mezer a odřádkování
251 {
252 if (isset($this->Info[$VarName]))
253 return $this->Info[$VarName];
254 else
255 return '';
256 }
257  
258  
259 function GetString($VarName)
260 // Vrátí parametr jako jeden řetězec s redukovanými bílými znaky
261 // Tedy bez odřádkování a nadbytečných mezer
262 {
263 return WrapString($this->GetVariable($VarName), 0);
264 }
265  
266  
267 function GetPage()
268 // Provede substituce ve stránce a vrátí ji jako řetězec
269 // Substituce bere z proměnné $Info
270 {
271 // Proveď ve stránce substituce proměnných a vrať výsledek
272 return $this->Substitute($this->Info, $this->Page);
273 }
274 }
275  
276  
277 ?>