<?php// Template Engine// ---------------//// Tento modul zpracovává tmplejty a strká do nich dynamicky geenrované// informace a vytváří tak dynamické HTML stránky s oddělenou logikou// programu a vzhledu.//// Více viz popis činnosti v konentáři na začátku templejtu//// (c)miho www.mlab.cz 2007, free software//// Typické použití objektu je toto://// - Založ objekt templejtu (new)// - $Template = new TemplateEngine();//// - Načti templejt ze souboru do objektu (ošetři chybu!)// - $error = $Template->LoadTemplate($TemplateFile);//// - Tady se provádí generování masa, je možné použít proměnné,// - modifikovat proměnné a nechat provéstsubstituce v proměnných// - do řetězců.//// $Template->SetVariable('InfoTitle','Generovaný seznam');// - první parametr je jméno proměnné, druhý je jeho nový obsah//// $Line = $Template->SetVariable('InfoLine')// - vrací obsah proměnné nebo prázdný řetězec//// - Připrav si proměnné, které se budou strkat do vzorového řetězce// $Variables[InfoName] = 'nějaká informace pro proměnnou InfoName';// $Variables[InfoPicture] = 'jiná informace pro proměnnou InfoPicture';// - aplikuj (nahraď) proměnné na vzorový řetězec z propměnné 'InfoLine'// $Line = $Template->Substitute($Variables, $Template->GetVariable('InfoLine'));//// - Nakonec se naaplikují proměnné do nataženého templejtu a výsledek// - se pošle klientovi// echo $Template->GetPage();//// Objekt pro zpracování templejtuclass TemplateEngine{private $Page; // Sem se načte templejt a zde se provádí substituceprivate $Info; // Sem se načtou z templejtu proměnnéfunction ListInfo()// Vypíše nalezené proměnné a jejich hodnoty// Pouze pro ladění{echo "[ ListInfo:\n";print_r($this->Info);echo ']';}function LoadTemplate($TemplateFileName, $Lang)// Načte templejt ze souboru, při chybě vrací chybový řetězec// Snaží se rozumně využít informaci o jazyku k otevření správné verze// templejtu. Cesta se zadává bez jazykové části ale s příponou.{// Vlož zadaný jazyk do názvu souboru$TemplateFileName = LangFile($TemplateFileName, $Lang);// Načti template ze souboru (po řádcích do pole)$this->Page = @file($TemplateFileName);if ($this->Page=='')return 'Unable Open Template File';// Sestav z pole jeden retězec$this->Page = implode($this->Page);// Definice regulárních výrazů pro hledání// ---------------------------------------// Definice vzoru pro hledání komentáře ve tvaru <!-- -->// Komentář je nepojmenované pole// Před a za koentářem mohou být bílé znaky// Uvnitř komentáře nesmí být znak >$PatternComment = '(?:\s*<!--[^>]*--\s*>\s*)';// (?: nepojemnované pole// \s* volitelné bílé znaky před// <!-- začátek komentáře// [^>]* vniřek komentáře (neobsahuje >)// --\s*> konec komentáře// \s* volitelné bílé znaky za komentářem// ) tady končí komentář// Definice vzoru pro hledání proměnných ve tvaru $InfoXXX$PatternVar ='\$(?P<VarName>Info[a-z,A-Z,0-9,\-\_]+)';// \$ na začátku $// (?P<VarName> pojmenované pole VarName je (jméno proměnné bez dolaru)// Info[a-z,A-Z,0-9,\-\_]+ proměnná začíná Info a pak jsou písmena,// ) číslice, mínus a podtržítko// Definice vzoru pro hledání hodnot proměnných ve tvaru = " Hodnota "// Definice hodnot je ve tvaru $InfoXXX="YYY" a mohou být víceřádkové// ( a mohou obsahovat uvnitř další substituce uvozené $, které program// zpracovává ale ne tady)$PatternValue = '\s*=\s*"(?P<VarValue>[^"]*)"';// \s*=\s* rovná se volitelnými bílými znaky okolo// " hodnota v uvozovkách// (?P<VarValue> parametr s názvem VarValue// [^"]* hodnota nesmí obsahovat uvozovky// ) vracíme hodnotu bez uvozovek// " konec uvozovek// Zparacování vzoru// -----------------// Najdi na začátku stránky komentář a vykousni ho$pattern = '/^' .$PatternComment. '+/su';$this->Page = preg_replace($pattern, '', $this->Page);// / oddělovač// ^ od začátku řetězce (jen komentáře na začátku souboru)// $PatternComment komentář (<!-- -->) s bílými znaky okolo// + alespoň jeden komentář// /su modifikátor, . zastupuje i odřádkování, utf8// Najdi v templejtu substutuční proměnné a vytvoř v poli $Info// prázdné položky pro každou použitou proměnnou. Dělá se to proto,// aby se na konci nepoužité proměnné nahradily prázdným řetězcem.$pattern = '/' .$PatternVar. '/su';preg_match_all($pattern, $this->Page, $temp);// / oddělovač// .$PatternVar. proměnná ( $InfoXXX ) - parametr VarName// /su modifikátor zajistí, že . zastupuje i odřádkování, utf8foreach($temp['VarName'] as $key => $value)$this->Info[$value] = '';unset($temp);// Vytáhni proměnné a jejich hodnoty do pole $Info$pattern = '/' .$PatternVar.$PatternValue. '/su';// / oddělovač// .$PatternVar. proměnná ( $InfoXXX ) - parametr VarName// .$PatternValue. přiřazení ( = " Hodnota " ) - parametr VarValue// /su modifikátor, . zastupuje i odřádkování, UTF8preg_match_all($pattern, $this->Page, $temp);foreach($temp['VarName'] as $key => $value)$this->Info[$value] = $temp['VarValue'][$key];unset($temp);// Vykousej zpracované definice proměnných (a komentáře před nimi)$pattern = '/' .$PatternComment.'?'.$PatternVar.$PatternValue. '/su';// / oddělovač// .$PatternComment.'?' volitelný komentář před definicí// .$PatternVar. proměnná ( $InfoXXX )// .$PatternValue. přiřazení ( = " Hodnota " )// /su modifikátor, . zastupuje i odřádkování, UTF8$this->Page = preg_replace($pattern, '', $this->Page);}function Indent($StringData, $Indent)// Všechna odřádkování v řetězci $StringData odsadí o hodnotu $Indent pokud je// $Indent číslo nebo o déllku řetězce $Indent pokud je to řetězec{// Velikost odsazení (vyrob číslo)if (is_string($Indent))$Num = mb_strlen($Indent,'utf-8');else$Num = 0+$Indent;// Odsazeníreturn $StringData = $Indent.str_replace("\n", "\n".str_repeat(' ', $Num), $StringData);}/*function Substitute($Variables, $String)// Nahradí proměnné v řetězci $String obsahem proměnných z pole $Variables// a vrátí výsledný řetězec{if (is_array($Variables)){foreach($Variables as $Key => $Value){// Hledací vzor (hledáme proměnnou s názvem v $Key)$Pattern = '\$'.$Key.'(?=[^a-z,A-Z,0-9,\-\_])';// \$$Key hledáme $JmenoProměnné// (?= následuje něco, co nemůže být jménem// [^a-z,A-Z,0-9,\-\_] a nezajímá nás// )// Vkládáme více řádek?$IsMultiline = !(strpos($Value, "\n") === FALSE);if (!$IsMultiline){// Vkládáme jednoduchý řetězec$String = preg_replace('/'.$Pattern.'/su', $Value, $String);// /su víceřádkové v UTF8}else{// Vkládáme řetezec s odřádkováním - je třeba odsazovat$String = preg_replace('/(.*)'.$Pattern.'/ue',"\$this->Indent(\$Value, '\\1')",$String);// (.*) hledáme cokoli před vzorem -> první parametr// .$Pattern. proměnná// /ue UTF8, náhrada je php skriptem}}}return $String;}*/function Substitute($Variables, $String)// Nahradí proměnné v řetězci $String obsahem proměnných z pole $Variables// a vrátí výsledný řetězec{// Hledací vzor$Pattern = '/(.*?)\$(Info[a-z,A-Z,0-9,\-\_]+)(?=[^a-z,A-Z,0-9,\-\_])/ue';// Náhrada s kusem php kódu (nezapomeň, že preg_replace s přepínačem /e vrací oescapované řetězce)$String = preg_replace($Pattern,'isset($Variables[\'\2\'])? $this->Indent($Variables[\'\2\'], stripslashes(\'\1\')): stripslashes(\'\1\')',$String);return $String;}function SetVariable($VarName, $VarValue, $Wrap=0)// Nastaví hodnotu proměnné// Volitelně provede zálámání na zadaný počet znaků a odstranění nadbytečných mezer{// Volitelné zalámání a odstranění bílých znakůif ($Wrap!=0)$VarValue = WrapString($VarValue, $Wrap);// Uložení do proměnných$this->Info[$VarName] = $VarValue;}function GetVariable($VarName)// Vrátí hodnotu proměnné tak, jak je, včetně mezer a odřádkování{if (isset($this->Info[$VarName]))return $this->Info[$VarName];elsereturn '';}function GetString($VarName)// Vrátí parametr jako jeden řetězec s redukovanými bílými znaky// Tedy bez odřádkování a nadbytečných mezer{return WrapString($this->GetVariable($VarName), 0);}function GetPage()// Provede substituce ve stránce a vrátí ji jako řetězec// Substituce bere z proměnné $Info{// Proveď ve stránce substituce proměnných a vrať výsledekreturn $this->Substitute($this->Info, $this->Page);}}?>