class.rFastTemplate.php(一) - 中国WEB开发者网络 (http://www.webasp.net) -- 技术教程 (http://www.webasp.net/article/) --- class.rFastTemplate.php(一) (http://www.webasp.net/article/6/5927.htm) |
| -- 作者:未知 -- 发布日期: 2003-07-26 |
| <?php // // Copyright ?2000-2001, Roland Roberts <roland@astrofoto.org> // 2001 Alister Bulman <alister@minotaur.nu> Re-Port multi template-roots + more // PHP3 Port: Copyright ?1999 CDI <cdi@thewebmasters.net>, All Rights Reserved. // Perl Version: Copyright ?1998 Jason Moore <jmoore@sober.com>, All Rights Reserved. // // RCS Revision // @(#) $Id: class.rFastTemplate.php,v 1.22 2001/10/18 21:36:53 roland Exp $ // $Source: /home/cvs/projects/php/tools/class.rFastTemplate.php,v $ // // Copyright Notice // // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; either version 2, or (at your option) // any later version. // // class.rFastTemplate.php is distributed in the hope that it will be // useful, but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU // General Public License for more details. // // Comments // // I would like to thank CDI <cdi@thewebmasters.net> for pointing out the // copyright notice attached to his PHP3 port which I had blindly missed // in my first release of this code. // // This work is derived from class.FastTemplate.php3 version 1.1.0 as // available from http://www.thewebmasters.net/. That work makes // reference to the "GNU General Artistic License". In correspondence // with the author, the intent was to use the GNU General Public License; // this work does the same. // // Authors // // Roland Roberts <roland@astrofoto.org> // Alister Bulman <alister@minotaur.nu> (multi template-roots) // Michal Rybarik <michal@rybarik.sk> (define_raw()) // CDI <cdi@thewebmasters.net>, PHP3 port // Jason Moore <jmoore@sober.com>, original Perl version // // Synopsis // // require ("PATH-TO-TEMPLATE-CODE/class.Template.php"); // $t = new Template("PATH-TO-TEMPLATE-DIRECTORY"); // $t->define (array(MAIN => "diary.html")); // $t->setkey (VAR1, "some text"); // $t->subst (INNER, "inner") // $t->setkey (VAR1, "some more text"); // $t->subst (INNER, ".inner") // $t->setkey (VAR2, "var2 text"); // $t->subst (CONTENT, "main"); // $t->print (CONTENT); // // Description // // This is a class.FastTemplate.php3 replacement that provides most of the // same interface but has the ability to do nested dynamic templates. The // default is to do dynamic template expansion and no special action is // required for this to happen. // // class.FastTemplate.php3 Methods Not Implemented // // clear_parse // Same as clear. In fact, it was the same as clear in FastTemplate. // clear_all // If you really think you need this, try // unset $t; // $t = new Template ($path); // which gives the same effect. // clear_tpl // Use unload instead. This has the side effect of unloading all parent // and sibling templates which may be more drastic than you expect and // is different from class.FastTemplate.php3. This difference is // necessary since the only way we can force the reload of an embedded // template is to force the reload of the parent and sibling templates. // // class.FastTemplate.php3 Methods by Another Name // // The existence of these functions is a historical artifact. I // originally had in mind to write a functional equivalent from scratch. // Then I came my senses and just grabbed class.FastTemplate.php3 and // started hacking it. So, you can use the names on the right, but the // ones on the left are equivalent and are the names used in the original // class.FastTemplate.php3. // // parse --> subst // get_assiged --> getkey // assign --> setkey // clear_href --> unsetkey // clear_assign --> unsetkey // FastPrint --> xprint // class rFastTemplate { // File name to be used for debugging output. Needs to be set prior to // calling anything other than option setting commands (debug, debugall, // strict, dynamic) because once the file has been opened, this is ignored. var $DEBUGFILE = '/tmp/class.rFastTemplate.php.dbg'; // File descriptor for debugging output. var $DEBUGFD = -1; // Array for individual member functions. You can turn on debugging for a // particular member function by calling $this->debug(FUNCTION_NAME) var $DEBUG = array (); // Turn this on to turn on debugging in all member functions via // $this->debugall(). Turn if off via $this->debugall(false); var $DEBUGALL = false; // Names of actual templates. Each element will be an array with template // information including is originating file, file load status, parent // template, variable list, and actual template contents. var $TEMPLATE = array(); // Holds paths-to-templates (See: set_root and FindTemplate) var $ROOT = array(); // Holds the HANDLE to the last template parsed by parse() var $LAST = ''; // Strict template checking. Unresolved variables in templates will generate a // warning. var $STRICT = true; // If true, this suppresses the warning generated by $STRICT=true. var $QUIET = false; // Holds handles assigned by a call to parse(). var $HANDLE = array(); // Holds all assigned variable names and values. var $VAR = array(); // Set to true is this is a WIN32 server. This was part of the // class.FastTemplate.php3 implementation and the only real place it kicks // in is in setting the terminating character on the value of $ROOT, the // path where all the templates live. var $WIN32 = false; // Automatically scan template for dynamic templates and assign new values // to TEMPLATE based on whatever names the HTML comments use. This can be // changed up until the time the first parse() is called. Well, you can // change it anytime, but it will have no effect on already loaded // templates. Also, if you have dynamic templates, the first call to parse // will load ALL of your templates, so changing it after that point will // have no effect on any defined templates. var $DYNAMIC = true; // Grrr. Don't try to break these extra long regular expressions into // multiple lines for readability. PHP 4.03pl1 chokes on them if you do. // I'm guessing the reason is something obscure with the parenthesis // matching, the same sort of thing Tcl might have, but I'm not sure. // Regular expression which matches the beginning of a dynamic/inferior // template. The critical bit is that we need two parts: (1) the entire // match, and (2) the name of the dynamic template. The first part is // required because will do a strstr() to split the buffer into two // pieces: everything before the dynamic template declaration and // everything after. The second is needed because after finding a BEGIN // we will search for an END and they both have to have the same name of // we consider the template malformed and throw and error. // Both of these are written with PCRE (Perl-Compatible Regular // Expressions) because we need the non-greedy operators to insure that // we don't read past the end of the HTML comment marker in the case that // the BEGIN/END block have trailing comments after the tag name. var $REGEX_DYNBEG = '/(<!--\s*BEGIN\s+DYNAMIC\s+BLOCK:\s*([A-Za-z][-_A-Za-z0-9.]+)(\s*|\s+.*?)-->)/'; // Regular expression which matches the end of a dynamic/inferior // template; see the comment about on the BEGIN match. var $REGEX_DYNEND = '/(<!--\s*END\s+DYNAMIC\s+BLOCK:\s*([A-Za-z][-_A-Za-z0-9.]+)(\s*|\s+.*?)-->)/'; // Regular expression which matches a variable in the template. var $REGEX_VAR = '/\{[A-Za-z][-_A-Za-z0-9]*\}/'; // // Description // Constructor. // function rFastTemplate ($pathToTemplates = '') { // $pathToTemplates can also be an array of template roots, handled in set_root global $php_errormsg; if (!empty($pathToTemplates)) { $this->set_root ($pathToTemplates); } $this->DEBUG = array ('subst' => false, 'parse_internal' => false, 'parse_internal_1' => false, 'parsed' => false, 'clear' => false, 'clear_dynamic' => false, 'load' => false); return $this; } // // Description // Set the name to be used for debugging output. If another file has // already been opened, close it so the next call to logwrite will // reopen under this name. // function debugfile ($name) { $this->DEBUGFILE = $name; } // // Description // Turn on/off debugging output of an individual member function. // function debug ($what, $on = true) { $this->DEBUG[$what] = $on; } // // Description // Turn on/off debugging output of all member functions. // function debugall ($on = true) { $this->DEBUGALL = $on; } // // Description // Turn on/off automatic dynamic template expansion. Note that a // template with an inferior dynamic template embedded will still // parse but only as if it were part of the main template. When this // is turned on, it will be parsed out as as if it were a full-blown // template and can thus be both parsed and appended to as a separate // entity. // function dynamic ($on = true) { $this->DYNAMIC = $on; } // // Description // Turn on/off strict template checking. When on, all template tags // must be assigned or we throw an error (but stilll parse the // template). // function strict ($on = true) { $this->STRICT = $on; } function quiet ($on = true) { $this->QUIET = true; } // // Description // For compatibility with class.FastTemplate.php3. // function no_strict () { $this->STRICT = false; } // // Description // Utility function for debugging. // function logwrite ($msg) { if ($this->DEBUGFD < 0) { $this->DEBUGFD = fopen ($this->DEBUGFILE, 'a'); } fputs ($this->DEBUGFD, strftime ('%Y/%m/%d %H:%M:%S ') . $msg . "\n"); } // // Description // This was lifted as-is from class.FastTemplate.php3. Based on what // platform is in use, it makes sure the path specification ends with // the proper path separator; i.e., a slash on unix systems and a // back-slash on WIN32 systems. When we can run on Mac or VMS I guess // we'll worry about other characters.... // // $root can now be an array of template roots which will be searched to // find the first matching name. function set_root ($root) { if (!is_array($root)) { $trailer = substr ($root, -1); if ($trailer != ($this->WIN32 ? '\\' : '/')) $root .= ($this->WIN32 ? '\\' : '/'); if (!is_dir($root)) { $this->error ("Specified ROOT dir [$root] is not a directory", true); return false; } $this->ROOT[] = $root; } else { reset($root); while(list($k, $v) = each($root)) { if (is_dir($v)) { $trailer = substr ($v,-1); if ($trailer != ($this->WIN32 ? '\\' : '/')) $v .= ($this->WIN32 ? '\\' : '/'); $this->ROOT[] = $v; } else $this->error ("Specified ROOT dir [$v] is not a directory", true); } } } // // Description // Associate files with a template names. // // Sigh. At least with the CVS version of PHP, $dynamic = false sets it // to true. // function define ($fileList, $dynamic = 0) { reset ($fileList); while (list ($tpl, $file) = each ($fileList)) { $this->TEMPLATE[$tpl] = array ('file' => $file, 'dynamic' => $dynamic); } return true; } function define_dynamic ($tplList, $parent='') { if (is_array($tplList)) { reset ($tplList); while (list ($tpl, $parent) = each ($tplList)) { $this->TEMPLATE[$tpl]['parent'] = $parent; $this->TEMPLATE[$tpl]['dynamic'] = true; } } else { // $tplList is not an array, but a single child/parent pair. $this->TEMPLATE[$tplList]['parent'] = $parent; $this->TEMPLATE[$tplList]['dynamic'] = true; } } // // Description // Defines a template from a string (not a file). This function has // not been ported from original PERL module to CDI's // class.FastTemplate.php3, and it comebacks in rFastTemplate // class. You can find it useful if you want to use templates, stored // in database or shared memory. // function define_raw ($stringList, $dynamic = 0) { reset ($stringList); while (list ($tpl, $string) = each ($stringList)) { $this->TEMPLATE[$tpl] = array ('string' => $string, 'dynamic' => $dynamic, 'loaded' => 1); } return true; } // // Description // Try each directory in our list of possible roots in turn until we // find a matching template // function FindTemplate ($file) { // first try for a template in the current directory short path for // absolute filenames if (substr($file, 0, 1) == '/') { if (file_exists($file)) { return $file; } } // search path for a matching file reset($this->ROOT); while(list($k, $v) = each($this->ROOT)) { $f = $v . $file; if (file_exists($f)) { return $f; } } $this->error ("FindTemplate: file $file does not exist anywhere in " . implode(' ', $this->ROOT), true); return false; } // // Description // Load a template into memory from the underlying file. // function &load ($file) { $debug = $this->DEBUGALL || $this->DEBUG['load']; if (! count($this->ROOT)) { if ($debug) $this->logwrite ("load: cannot open template $file, template base directory not set"); $this->error ("cannot open template $file, template base directory not set", true); return false; } else { $contents = ''; $filename = $this->FindTemplate ($file); if ($filename) $contents = implode ('', (@file($filename))); if (!($contents) or (empty($contents)) or (! $filename)) { if ($debug) $this->logwrite ("load: failed to load $file, $php_errormsg"); $this->error ("load($file) failure: $php_errormsg", true); } else { if ($debug) $this->logwrite ("load: found $filename"); return $contents; } } } // 未完待续 呵呵 ——————by 孤狼 |
| webasp.net |