分享
 
 
 

class.rFastTemplate

王朝other·作者佚名  2008-05-21
窄屏简体版  字體: |||超大  

<?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*BEGINs+DYNAMICs+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*ENDs+DYNAMICs+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 . "

");

}

//

// 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;

}

}

}

//

// Description

//

Recursive internal parse routine.

This will recursively parse a

//

template containing dynamic inferior templates.

Each of these

//

inferior templates gets their own entry in the TEMPLATE array.

//

function &parse_internal_1 ($tag, $rest = '') {

$debug = $this->DEBUGALL || $this->DEBUG['parse_internal_1'];

if (empty($tag)) {

$this->error ("parse_internal_1: empty tag invalid", true);

}

if ($debug)

$this->logwrite ("parse_internal_1 (tag=$tag, rest=$rest)");

while (!empty($rest)) {

if ($debug)

$this->logwrite ('parse_internal_1: REGEX_DYNBEG search: rest => ' . $rest);

if (preg_match ($this->REGEX_DYNBEG, $rest, $dynbeg)) {

// Found match, now split into two pieces and search the second

// half for the matching END.

The string which goes into the

// next element includes the HTML comment which forms the BEGIN

// block.

if ($debug)

$this->logwrite ('parse_internal_1: match beg => ' . $dynbeg[1]);

$pos = strpos ($rest, $dynbeg[1]);

// See if the text on either side of the BEGIN comment is only

// whitespace.

If so, we delete the entire line.

$okay = false;

for ($offbeg = $pos - 1; $offbeg >= 0; $offbeg--) {

$c = $rest{$offbeg};

if ($c == "

") {

$okay = true;

$offbeg++;

break;

}

if (($c != ' ') && ($c != "")) {

$offbeg = $pos;

break;

}

}

if (! $okay) {

$offend = $pos + strlen($dynbeg[1]);

} else {

$l = strlen ($rest);

for ($offend = $pos + strlen($dynbeg[1]); $offend < $l; $offend++) {

$c = $rest{$offend};

if ($c == "

") {

$offend++;

break;

}

if (($c != ' ') && ($c != "")) {

$offend = $pos + strlen($dynbeg[1]);

break;

}

}

}

// This includes the contents of the REGEX_DYNBEG in the output

// $part[] = substr ($rest, 0, $pos);

// This preserves whitespace on the END block line(s).

// $part[] = substr ($rest, 0, $pos+strlen($dynbeg[1]));

// $rest = substr ($rest, $pos+strlen($dynbeg[1]));

// Catch case where BEGIN block is at position 0.

if ($offbeg > 0)

$part[] = substr ($rest, 0, $offbeg);

$rest = substr ($rest, $offend);

$sub = '';

if ($debug)

$this->logwrite ("parse_internal_1: found at pos = $pos");

// Okay, here we are actually NOT interested in just the next

// END block.

We are only interested in the next END block that

// matches this BEGIN block.

This is not the most efficient

// because we really could do this in one pass through the

// string just marking BEGIN and END blocks.

But the recursion

// makes for a simple algorithm (if there was a reverse

// preg...).

$found

= false;

while (preg_match ($this->REGEX_DYNEND, $rest, $dynend)) {

if ($debug)

$this->logwrite ('parse_internal_1: REGEX_DYNEND search: rest => ' . $rest);

if ($debug)

$this->logwrite ('parse_internal_1: match beg => ' . $dynend[1]);

$pos

= strpos ($rest, $dynend[1]);

if ($dynbeg[2] == $dynend[2]) {

$found

= true;

// See if the text on either side of the END comment is

// only whitespace.

If so, we delete the entire line.

$okay = false;

for ($offbeg = $pos - 1; $offbeg >= 0; $offbeg--) {

$c = $rest{$offbeg};

if ($c == "

") {

$offbeg++;

$okay = true;

break;

}

if (($c != ' ') && ($c != "")) {

$offbeg = $pos;

break;

}

}

if (! $okay) {

$offend = $pos + strlen($dynend[1]);

} else {

$l = strlen ($rest);

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有