/** * this variable holds the file system path to all our template files. */ $path = './templates/';
/** * create a template object for the outer template and set its variables. */ $tpl = & new template($path); $tpl->set('title', 'user list');
/** * create a template object for the inner template and set its variables. the * fetch_user_list() function simply returns an array of users. */ $body = & new template($path); $body->set('user_list', fetch_user_list());
/** * set the fetched template of the inner template to the 'body' variable in * the outer template. */ $tpl->set('body', $body->fetch('user_list.tpl.php'));
/** * echo the results. */ echo $tpl->fetch('index.tpl.php'); ?> 其中有两个值得注意的重要的概念。第一个就是内部和外部模板的概念。外部模板包含定义站点主要外观的html代码。而内部模板包含定义站点内容区域的html代码。当然,你能够在任意数目的层上有任意数目的模板。因为通常我们给每个区域使用不同的模板对象,所以没有名字空间的问题。例如,我能在内部和外部模板中都有变量叫"title",而不用害怕有什么冲突。
<?php /** * example of cached template usage. doesn't provide any speed increase since * we're not getting information from multiple files or a database, but it * introduces how the is_cached() method works. */
/** * first, include the template class. */ require_once('template.php');
/** * here is the path to the templates. */ $path = './templates/';
/** * define the template file we will be using for this page. */ $file = 'list.tpl.php';
/** * pass a unique string for the template we want to cache. the template * file name + the server request_uri is a good choice because: * 1. if you pass just the file name, re-used templates will all * get the same cache. this is not the desired behavior. * 2. if you just pass the request_uri, and if you are using multiple * templates per page, the templates, even though they are completely * different, will share a cache file (the cache file names are based * on the passed-in cache_id. */ $cache_id = $file . $_server['request_uri']; $tpl = & new cachedtemplate($path, $cache_id, 900);
/** * test to see if the template has been cached. if it has, we don't * need to do any processing. thus, if you put a lot of db calls in * here (or file reads, or anything processor/disk/db intensive), you * will significantly cut the amount of time it takes for a page to * process. * * this should be read aloud as "if not is_cached" */ if(!($tpl->is_cached())) { $tpl->set('title', 'my title'); $tpl->set('intro', 'the intro paragraph.'); $tpl->set('list', array('cat', 'dog', 'mouse')); }
/** * fetch the cached template. it doesn't matter if is_cached() succeeds * or fails - fetch_cache() will fetch a cache if it exists, but if not, * it will parse and return the template as usual (and make a cache for * next time). */ echo $tpl->fetch_cache($file); ?>
<?php /** * copyright (c) 2003 brian e. lozier ([email protected]) * * set_vars() method contributed by ricardo garcia (thanks!) * * permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "software"), to * deal in the software without restriction, including without limitation the * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the software, and to permit persons to whom the software is * furnished to do so, subject to the following conditions: * * the above copyright notice and this permission notice shall be included in * all copies or substantial portions of the software. * * the software is provided "as is", without warranty of any kind, express or * implied, including but not limited to the warranties of merchantability, * fitness for a particular purpose and noninfringement. in no event shall the * authors or copyright holders be liable for any claim, damages or other * liability, whether in an action of contract, tort or otherwise, arising * from, out of or in connection with the software or the use or other dealings * in the software. */
class template { var $vars; /// holds all the template variables var $path; /// path to the templates
/** * constructor * * @param string $path the path to the templates * * @return void */ function template($path = null) { $this->path = $path; $this->vars = array(); }
/** * set the path to the template files. * * @param string $path path to template files * * @return void */ function set_path($path) { $this->path = $path; }
/** * set a template variable. * * @param string $name name of the variable to set * @param mixed $value the value of the variable * * @return void */ function set($name, $value) { $this->vars[$name] = $value; }
/** * set a bunch of variables at once using an associative array. * * @param array $vars array of vars to set * @param bool $clear whether to completely overwrite the existing vars * * @return void */ function set_vars($vars, $clear = false) { if($clear) { $this->vars = $vars; } else { if(is_array($vars)) $this->vars = array_merge($this->vars, $vars); } }
/** * open, parse, and return the template file. * * @param string string the template file name * * @return string */ function fetch($file) { extract($this->vars); // extract the vars to local namespace ob_start(); // start output buffering include($this->path . $file); // include the file $contents = ob_get_contents(); // get the contents of the buffer ob_end_clean(); // end buffering and discard return $contents; // return the contents } }
/** * an extension to template that provides automatic caching of * template contents. */ class cachedtemplate extends template { var $cache_id; var $expire; var $cached;
/** * constructor. * * @param string $path path to template files * @param string $cache_id unique cache identifier * @param int $expire number of seconds the cache will live * * @return void */ function cachedtemplate($path, $cache_id = null, $expire = 900) { $this->template($path); $this->cache_id = $cache_id ? 'cache/' . md5($cache_id) : $cache_id; $this->expire = $expire; }
/** * test to see whether the currently loaded cache_id has a valid * corrosponding cache file. * * @return bool */ function is_cached() { if($this->cached) return true;
// passed a cache_id? if(!$this->cache_id) return false;
// can get the time of the file? if(!($mtime = filemtime($this->cache_id))) return false;
// cache expired? if(($mtime + $this->expire) < time()) { @unlink($this->cache_id); return false; } else { /** * cache the results of this is_cached() call. why? so * we don't have to double the overhead for each template. * if we didn't cache, it would be hitting the file system * twice as much (file_exists() & filemtime() [twice each]). */ $this->cached = true; return true; } }
/** * this function returns a cached copy of a template (if it exists), * otherwise, it parses it as normal and caches the content. * * @param $file string the template file * * @return string */ function fetch_cache($file) { if($this->is_cached()) { $fp = @fopen($this->cache_id, 'r'); $contents = fread($fp, filesize($this->cache_id)); fclose($fp); return $contents; } else { $contents = $this->fetch($file);
// write the cache if($fp = @fopen($this->cache_id, 'w')) { fwrite($fp, $contents); fclose($fp); } else { die('unable to write cache.'); }