Location: PHPKode > scripts > Solace FastTemplate > solace-fasttemplate/sftemplate.php
<?

//==============================================================
//  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);
    }

}

?>
Return current item: Solace FastTemplate