<?
//==============================================================
// Solace FastTemplate v1.0
// (compatible remake of the original class.FastTemplate.php3)
//
// (c) Zilav <hide@address.com>
//
// Additional features:
// - unlimited nested dynamic blocks
// - enabled/disabled blocks
// - no templates definition
// - multiply templates extensions
// - assigned and parsed variables are the same
//==============================================================
// Use the same name for compatibility
class FastTemplate {
var $root = '';
var $cache = array();
var $extensions = array('htm');
var $vars = array();
var $dynamics = array(); // array of dynamic blocks:
// [dymamic block name] =>
// [tpl] => template's name,
// [var] => parsed block var's name,
// [txt] => block's content
var $strict = true;
// automatically detect dynamic blocks?
var $auto_dynamics = true;
var $last = '';
//=====================================================
// constructor (set path to templates)
function FastTemplate($path = './') {
$this->root = $path;
}
//=====================================================
// error handler
function error($msg, $abort = true) {
echo "SFTemplate error: ".$msg."<br>";
if ($abort) exit;
}
//=====================================================
// set template files extensions
function set_extensions($ext = array('htm')) {
if (is_array($ext))
$extensions = $ext;
else
$extensions = array($ext);
}
//=====================================================
// load template
function load($tplname) {
if (isset($this->cache[$tplname])) return true;
foreach ($this->extensions as $ext) {
$fname = $this->root."/$tplname.$ext";
if (file_exists($fname)) {
$f = fopen($fname, 'rb');
$content = fread($f, 1024*1024); // 1MB templates max, set more if you need
$this->cache[$tplname] = $content;
fclose($f);
break;
}
}
if (!isset($this->cache[$tplname])) {
$this->error("Unable to locate template '$tplname'");
}
// automatic detection of all dynamic blocks
if ($this->auto_dynamics) {
preg_match_all("/<!-- BEGIN DYNAMIC BLOCK: (\w+) -->/", $content, $out);
for ($i=0;$i<count($out[0]);$i++) {
$dyn = $out[1][$i];
if (preg_match("/<!-- BEGIN DYNAMIC BLOCK: $dyn -->(.+)<!-- END DYNAMIC BLOCK: $dyn -->/s", $content, $regs)) {
$this->dynamics[$dyn]['tpl'] = $tplname;
$this->dynamics[$dyn]['var'] = '';
$this->dynamics[$dyn]['txt'] = $regs[1];
}
}
}
}
//=====================================================
// parse text into variable
function parse_text($varname, $content, $add = false) {
// process enabled/disabled blocks
if (strpos($content, 'ABLED BLOCK:') !== false) {
preg_match_all("/<!-- BEGIN (EN|DIS)ABLED BLOCK: (\w+) -->/", $content, $out);
for ($i=0;$i<count($out[0]);$i++) {
$blck = $out[2][$i];
if (($out[1][$i] == 'DIS') and $this->enabled[$blck]) $enabled = true; else
if (($out[1][$i] == 'EN') and ($this->enabled[$blck] or !isset($this->enabled[$blck])))
$enabled = true;
else
$enabled = false;
while (preg_match("/<!-- BEGIN (EN|DIS)ABLED BLOCK: $blck -->(.+?)<!-- END (EN|DIS)ABLED BLOCK: $blck -->/s", $content, $regs))
if ($enabled) $content = str_replace($regs[0], $regs[2], $content);
else $content = str_replace($regs[0], '', $content);
}
}
// substitute variables
foreach ($this->vars as $name => $val) {
$content = str_replace('{'.$name.'}', $val, $content);
}
// substitute dynamic blocks
if (strpos($content, 'DYNAMIC BLOCK:') !== false) {
foreach ($this->dynamics as $dyn => $d) {
$p1 = strpos($content, "<!-- BEGIN DYNAMIC BLOCK: $dyn -->");
if ($p1 === false) continue;
$s = "<!-- END DYNAMIC BLOCK: $dyn -->";
$p2 = strpos($content, $s, $p1) + strlen($s);
$content = substr($content, 0, $p1).$this->vars[$d['var']].substr($content, $p2);
}
}
// delete unassigned variables
if (!$this->strict) {
$content = preg_replace("/\{\w+\}/", '', $content);
}
if ($add)
$this->vars[$varname] .= $content;
else
$this->vars[$varname] = $content;
}
//=====================================================
// parse template into variable
function parse($varname, $tplname) {
$varname = strtoupper($varname);
if ($tplname[0] <> '.') {
$this->load($tplname);
$content = $this->cache[$tplname];
$this->parse_text($varname, $content);
} else {
$dyn = substr($tplname, 1);
if (isset($this->dynamics[$dyn])) {
$content = $this->dynamics[$dyn]['txt'];
if (!$varname) $varname = strtoupper("dyn_$dyn");
$this->parse_text($varname, $content, true);
$this->dynamics[$dyn]['var'] = $varname;
} else
$this->error("Undefined dynamic block $dyn");
}
$this->last = $varname;
}
//=====================================================
// assign variable(s)
function assign($varname, $varvalue = '') {
if (is_array($varname)) {
foreach ($varname as $name => $val) {
$this->vars[strtoupper($name)] = $val;
}
} else
$this->vars[strtoupper($varname)] = $varvalue;
}
//=====================================================
// assign variables from array (with non-numeric keys), optionally add prefix
// for example to pass form values: assign_array($_REQUEST)
function assign_array(&$a, $prefix = '') {
if (!is_array($a)) return;
foreach ($a as $name => $val)
if (!is_numeric($name))
$this->vars[$prefix.strtoupper($name)] = $val;
}
//=====================================================
// enable/disable blocks
function enable_block($blck, $enabled = 1) {
$this->enabled[$blck] = $enabled;
}
//=====================================================
// enable/disable blocks
function disable_block($blck, $enabled = 0) {
$this->enabled[$blck] = $enabled;
}
//=====================================================
// set strict
// replace all unassigned variables with empty strings
function strict() {
$this->strict = true;
}
//=====================================================
// set no strict
function no_strict() {
$this->strict = false;
}
//=====================================================
// define template (absent, no need in definition)
// use load() instead
function define($param) {
return true;
}
//=====================================================
// define dynamic blocks
function define_dynamic($dyn, $tplname) {
if ($this->auto_dynamics) return true;
/* // Uncomment this if you want
if (isset($this->dynamics[$dyn])) {
$this->error("Dynamic block $dyn already defined", false);
return false;
}
*/
// compatibility fix, original FastTemplate doesn't have manual load()
// so this is a good place to prepare template
$this->load($tplname);
if (!preg_match("/<!-- BEGIN DYNAMIC BLOCK: $dyn -->(.+)<!-- END DYNAMIC BLOCK: $dyn -->/s", $this->cache[$tplname], $regs))
$this->error("Dynamic block $dyn not found");
$this->dynamics[$dyn]['tpl'] = $tplname; // not used now
$this->dynamics[$dyn]['var'] = '';
$this->dynamics[$dyn]['txt'] = $regs[1];
return true;
}
//=====================================================
// get var's value
function fetch($varname) {
return $this->vars[strtoupper($varname)];
}
//=====================================================
// clear var's value
function clear($varname) {
$this->vars[strtoupper($varname)] = '';
}
//=====================================================
// clear dynamics definitions
function clear_define() {
$this->dynamics = array();
}
//=====================================================
// print variable
function FastPrint($varname = '') {
if ($varname == '') $varname = $this->last;
echo $this->fetch($varname);
}
}
?>