###################### Template Class ####################
#
# Met de class Template is het mogelijk om in een template bestand bepaalde variable-waarden te plaatsen.
# dit maakt het makkelijker voor disgners om een layout te veranderen zonder php te hoeven gebruiken.
# De template file kan elk normaal ascii bestand zijn en kan bestaan uit HTML, gewone tekst etc etc.
# Het model wat word vervangen heeft het volgende formaat: %[(a-z)]%
#
# Vereiste variabelen:
# $vars -- Een array gevuld met sleutel waarden die in het template bestand moeten worden
# vervangen en de daarbijbehordende nieuwe waarden.
#
# Het systeem is:
# - Hoofdletter ongevoelig,
# - Alfanumerieke tekens en _ worden geaccepteerd,
#
# Vb.:
# $var = new Template("textfile.template.html");
# print $var->parse( // aanroep om "dailer.template.htm" te parsen
# array(
# "link" => $templateLink, // in het template bestand word "%[link]% vervangen door de waarde in $templateLink
# )
# );
#
######
# Door: Willem de Vries
# Date: 9 februari 2005
# Voor: Virtual Pc Services
# Versie: 2.2
#
######
# Changelog:
# 1.0 (WdV 7-11-2003): statische functie ombouwen naar object
# 1.1 (WdV 13-2-2004): parsen moet ook zonder parameters kunnen
# 1.2 (JF 15-2-2004): Set functie toegevoegd om variablen aan template toe te voegen, aaroep: set(variablenaam, value)
# 1.3 (JF 24-3-2004): Endless loop bug gefixed, bij openen van template kwam hij bij lege file of file zonder
# regeleinde niet bij eof bij lezen van filesize.
# 1.4 (WdV 04-3-2005): Nieuwe functie om default-waardes uit een HTML-comment veld te halen.
# 2.0 (WdV 09-2-2005): grotendeels herschreven refresh() en parse() routine. Nu 50% sneller!
# 2.1 (WdV 15-2-2005): Mogelijkheid om een template aan te maken vanuit een string ipv. een file uit te lezen
# 2.2 (WdV 28-10-2005): On-the-fly compressie om geheugen te sparen, kleinere array properties
# 2.3 (WdV 15-12-2005): Gebruik van de "TEMPLATE_SEARCH" superglobal om een (relatief) zoekpad op te geven waarin
# templates gezocht moeten worden.
###############################################################
function _slashjoin() {
$out = array();
foreach(func_get_args() as $param) {
if ($param)
$out[] = $param;
}
return preg_replace('#([/]+)#', '/', join('/', $out));
}
function _dirlist($str, $regex = '.*') {
$out = array();
$dh = (is_dir($str)) ? @opendir($str) : null;
while ($dh and $fil = readdir($dh)) {
$out[] = _slashjoin($str, $fil);
}
if ( !$out) return;
list($item) = array_values(preg_grep("|$regex|i", $out));
# error_log(__FUNCTION__ . " Matching items for |$regex|");
# error_log(__FUNCTION__ . " Subdirs in $str: " . join('|', $out));
# error_log(__FUNCTION__ . " Found dir '$item'");
return ($item) ? $item : $str;
}
class Template {
var $fn = null;
var $filename = null;
var $ch = null;
var $error = null;
var $searchpath = null;
var $searchdir = null;
var $inf = null;
var $def = null;
var $me = 'object';
var $vars = array();
function Template($name) {
# Compatibility
$this->filename =& $this->fn;
$this->me = strtoupper(get_class($this));
$this->searchpath = $GLOBALS[$this->me . "_SEARCH"];
if (defined($this->me . "_COMPRESS")) {
foreach(array(array('gzcompress', 'gzuncompress'), array('gzdeflate', 'gzinflate')) as $grp) {
if (function_exists($grp[0])) {
$this->def = $grp[0];
$this->inf = $grp[1];
break;
}
}
}
$this->fn = $name;
$this->refresh();
}
function set($varname, $value = ''){
$this->vars[$varname] = $value;
}
function get($varname) {
return $this->vars[$varname];
}
function refresh() {
if (!preg_match('/\.([^\.\/\s]+)$/', $this->fn, $found) ) {
$this->cached($this->fn);
$this->fn = null;
$this->error = null;
return;
}
# Implementatie zoekpad
$subdirs = preg_split('/([\s]*;[\s]*)/', $this->searchpath);
if (! $subdirs)
$subdirs = array('');
list($a, $up, $b, $path) = preg_match('/^(([\.]+\/)*)(.+)/', $this->fn, $found) ? $found : array('', '', '', $found[0]);
foreach($subdirs as $subdir) {
$sub = _slashjoin($up, $subdir);
# Wanneer de basis zoekdirectory niet bestaat, dan controleren we nog even
# of deze naam niet partieel voorkomt ergens in de boom. Zie functie _dirlist().
if ($subdir and !is_dir($sub)) {
$sub = _dirlist(dirname($sub), preg_replace('/([^0-9a-z]+)$/', '', $subdir) );
}
$this->searchdir = _slashjoin($sub, $path);
$exists = (file_exists($this->searchdir) and filesize($this->searchdir) > 0);
if ($exists) {
$this->searchpath = $sub;
break;
}
}
$readable = ($exists and is_readable($this->searchdir) );
$soort = ($readable) ? filetype($this->searchdir) : "";
if ($readable and $soort == "file") {
$this->cached( join('', file($this->searchdir)) );
$this->error = null;
} elseif (!$exists) {
$this->error( sprintf("'%s' bestaat niet.", $this->searchdir) );
} elseif (!$readable) {
$this->error( sprintf("'%s' kan niet worden gelezen.", $this->searchdir) );
} elseif ($exists && $soort != "file") {
$this->error( sprintf("'%s' is geen geldig bestand; %s", $this->searchdir, $soort) );
}
return;
}
function error($str) {
$text = sprintf('%s %s [in %s]', $this->me, $str, $_SERVER['SCRIPT_NAME']);
$this->error = $text;
if ($_SERVER['IS_DEVEL'] and $this->error) error_log($this->error);
}
function parse($vars = array()) {
$vars = $vars + $this->vars;
if ($this->searchpath)
# Voeg een slash toe aan het einde van het pad - templates verwachten dit!
$vars['_searchpath'] = trim(_slashjoin($this->searchpath, ' '));
$match = array();
$repl = array();
foreach(array_keys($vars) as $key){
$match[] = sprintf("/(%%\[%s\]%%)/i", preg_quote($key));
$repl[] = $vars[$key];
}
$match[] = '/%\[[^\[\]]+\]%/'; # Catch all
$repl[] = '';
return preg_replace($match, $repl, $this->cached());
}
function extractData() {
$reg = '/<\!--(\s*([^=\s\<\>]+)[\s=]+[\'"]?([^\'"\s\<\>]+))+\s*-->/';
$comment = '/<\!--\s*(.+)\s*-->/';
$fields = '/([^=\s<>]+)[\s=]+([\'\"])?([^\s<>\2]+)/';
if (! preg_match_all($comment, $this->cached(), $found) )
return false;
foreach($found[1] as $line) {
preg_match_all($fields, $line, $res);
for($i=0; $i < sizeof($res[0]); $i++) {
$this->vars[$res[1][$i]] = $res[3][$i];
}
}
return $this->vars;
}
function cached($str = null) {
if (is_null($str)) {
#request
$do = $this->inf;
return ($this->compressed() and $this->ch) ? $do($this->ch) : $this->ch;
}
$do = $this->def;
$this->ch = ($this->compressed()) ? $do($str, 9) : $str;
}
function compressed() {
return ($this->inf || $this->def);
}
}
# EOF
?>
Deze afbeelding is verkleind. Klik op het plaatje om de volledige afbeelding te bekijken.