+ -
当前位置:首页 → 问答吧 → 最小,最精,没有一个正则表达式,只有30行的摸板类

最小,最精,没有一个正则表达式,只有30行的摸板类

时间:2007-01-31

来源:互联网

最小,最精悍,没有一个正则表达式的模版类
代码量只有1K,实际代码只有30行。
以前用了很多的模板,用得最多的是phplib
和smarty。
模版的好处显而易见,用于应用和显示分离,特别是对于大型程序,由于美工和程序员对互相的工作并不是十分熟悉,在进行合作的过程中需要用一种约定的"语言"进行交流。这种约定的语言就是标签。
  在项目的开发中我用了很长时间的smarty
和phplib,但是最近的一个项目使我放弃了这两种模版。
    原因有:
    1.smarty的标签对美工来说看起来很怪异,不接受,而实际上开发过程中,排版效果非常差。
    2.美工往往看不懂模版的逻辑,里面的逻辑太多了。
    3.对程序员来说,smarty也很复杂,以至于有一本smarty 手册。一段时间没有用,想重拾smarty,发现似乎是去学一门新语言。
    4.phplib简单,标签看起来一目了然。
不过实际用起来还是不怎么好用。
    鉴于以上缺点:写了一个非常非常简单的模版。既然简单,所以就不强调它的功能,而是易用易学,高效,稳定,并省下了启动正则的开销。不过广大phper增加额外的负担,
php本身也是一个模版语言,不想把复杂的逻辑写在模版里面,对于实际项目中你会发现用php这些会更简单。
   《注:转载本文章请保持完整性,作者:[email protected]>
   使用教程
核心代码template.php
引用:
<?php
/* @author: [email protected] */
class Template{
        var $code;
        function Template($template){
            $this->code = implode('', @file($template));
        }
        function assign($name,$var=null){
    if(is_string($name) && is_string($var)){
     $this->code = str_replace('{'.$name.'}', $var, $this->code);
    } else if(is_array($var)){
     list($this->code,$tmp,$end)=explode('<!--'.$name.'-->',$this->code);
     while(list(,$v)=each($var)){
      $t=$tmp;$k2=$v2='';
      while(list($k2, $v2) = each($v)){
           $t = str_replace('{'.$k2.'}', $v2,$t);
      }
      $this->code .= $t;
     }
     $this->code .= $end;     
    } else {     
     while (list ($k2, $v2) = each($name)){
           $this->code = str_replace('{'.$k2.'}', $v2, $this->code);
     }
    }
        }
        function display(){
                echo $this->code;
        }
}
?>
最简单的hello_world
准备一个php模版文件hello_world.html
<html>
<head>
<meta http-equiv="Content-Type" c />
<title>{title}</title>
</head>
<body>
<h1>{title}</h1>
</body>
</html>
接下来就是模版的翻译工作了
<?php
include('../include/template.php'); //包含模版核心类文件
$tpl=new Template('hello_world.html'); //参数为模版路径和文件名,可以使用相对路径,也可以使用绝对路径
$tpl->assign('title',"hello world!"); //将标签{title} 替换成hello world
$tpl->display();
?>

模版中使用数组
test_array.html
<html>
<body>
<h3>{user} {email}</h3>
<h3>{user1} {email1}</h3>
</body>
</html>
模版处理文件
<?php
include('../include/template.php');
$tpl=new Template('test_array.html');
$user=array('user'=>'yubing','email'=>'[email protected]');
$tpl->assign($user);
$tpl->assign('user1','jack');
$tpl->assign('email1','[email protected]');
$tpl->display();
?>
简单的区块处理
block.html
<table width="400" border="1">
  <tr>
    <td>User Name</td>
    <td>E-Mail</td>
  </tr>
  <!--users-->
  <tr>
    <td>{name}</td>
    <td>{email}</td>
  </tr>
  <!--users-->
</table>
区块处理程序
block.php
<?php
include('../include/template.php');
$tpl=new Template('block.html');

$users=array(
  array('name'=>'jack','email'=>'[email protected]'),
  array('name'=>'tom','email'=>'[email protected]')
  );   
$tpl->assign('users',$users);
$tpl->display();
?>
模版包含测试
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" c />
<title>{title}</title>
</head>
<body>
<h1>{title}</h1>
    <p>{block}</p>
</body>
</html>
模版包含处理程序
<?php
include('../include/template.php');
$tpl=new Template('block.html');
$users=array(
array('name'=>'jack','email'=>'[email protected]'),
array('name'=>'tom','email'=>'[email protected]'),
);
$tpl->assign('users',$users);
$block=$tpl->code;
$tpl->Template('main.html');
$tpl->assign('block',$block);
$tpl->assign(array('title'=>'测试多模版文件'));
$tpl->display();
?>

[ 本帖最后由 robinhunan 于 2007-1-31 11:49 编辑 ]

作者: robinhunan   发布时间: 2007-01-31

哈哈,淘到宝贝了!第一个下

[ 本帖最后由 gently 于 2007-1-31 14:11 编辑 ]

作者: gently   发布时间: 2007-01-31

这种模版有比较严重的问题是只适合逻辑简单的页面。
我很早以前用过PEAR::ITX,它也是完全将代码从template中隔离,但是当深入应用的时候,你发现可能为了实现一些简单的功能,你需要增加相应的render代码。实际上你是把逻辑全部扔到模版的处理文件中了。在开发一些比较复杂和需要运行期能够定制的时候,这种方式就是可怕的噩梦,比如3列还是2列,带不带图,页面的layout的变动,你也需要更新相应的php代码。

smarty相比就伸缩性很大,你可以像flickr那样,有几千个help函数,也可以就用内置的。

很多人认为smarty很难,其实就是几个规则,一些内置函数而已。

作者: nightsailer   发布时间: 2007-01-31



[ 本帖最后由 luzhou 于 2008-1-31 19:04 编辑 ]

作者: luzhou   发布时间: 2007-01-31

楼主还是很有实力的

作者: leehui1983   发布时间: 2007-02-01

做个小站足够了!

作者: 野草   发布时间: 2007-02-01

帮你代码加亮一下:
复制PHP内容到剪贴板
PHP代码:

<?php
/* @author: [email][email protected][/email] */
class Template{
        var $code;
        function Template($template){
            $this->code = implode('', @file($template));
        }
        function assign($name,$var=null){
    if(is_string($name) && is_string($var)){
     $this->code = str_replace('{'.$name.'}', $var, $this->code);
    } else if(is_array($var)){
     list($this->code,$tmp,$end)=explode('<!--'.$name.'-->',$this->code);
     while(list(,$v)=each($var)){
      $t=$tmp;$k2=$v2='';
      while(list($k2, $v2) = each($v)){
           $t = str_replace('{'.$k2.'}', $v2,$t);
      }
      $this->code .= $t;
     }
     $this->code .= $end;     
    } else {     
     while (list ($k2, $v2) = each($name)){
           $this->code = str_replace('{'.$k2.'}', $v2, $this->code);
     }
    }
        }
        function display(){
                echo $this->code;
        }
}
?>

作者: ysixin   发布时间: 2007-02-01

另外也提一下,换个方式,连str_replace的开销也可以省下来

作者: ysixin   发布时间: 2007-02-01

学习了  很不多的

作者: 小竣   发布时间: 2007-02-01

弱弱的问一声,楼主怎么实现循环?

作者: 书生   发布时间: 2007-02-05

引用:
原帖由 书生 于 2007-2-5 16:53 发表
弱弱的问一声,楼主怎么实现循环?
他循环是通过数组替换过去的,不过不太灵活而已,呵呵。。
不过感觉已经够使了,哈

else if(is_array($var)){
     list($this->code,$tmp,$end)=explode('<!--'.$name.'-->',$this->code);

作者: Phzzy   发布时间: 2007-02-05

great ! I need it.Thanks.

作者: lifeibest   发布时间: 2008-01-31

作者: luzhou   发布时间: 2008-01-31

作者: MoHock   发布时间: 2008-01-31

弱弱的问一下您这个模板 效率好吗??连编译都没有????

作者: zshtom   发布时间: 2008-01-31

我贴一个我写的别骂 啊 哈哈
复制PHP内容到剪贴板
PHP代码:

<?php
/**
* @author zshtom
* @copyright zshtom [[email protected]][color=#003366][email protected][/color][/email] 2007-2008
*/
function zTemplate($filename, $templatedir='', $compliedir=''){
        $comtime = @filemtime($compliedir.md5($filename).".php");//编译时间
        $temtime = @filemtime($templatedir.$filename);//模板时间
        if($temtime > $comtime){//是否重新写入模板
                $str = file_get_contents($templatedir.$filename);
                $str = preg_replace('|<!--{if (.+)}-->|isU', '<?php if(\\1){ ?>', $str);
                $str = preg_replace('|<!--{/if}-->|isU', '<?php } ?>', $str);
                $str = preg_replace('|{\$(.*)}|isU', '<?php echo $\\1; ?>', $str);
                $str = preg_replace('|<!--{else}-->|isU', '<?php }else{ ?>', $str);
                $str = preg_replace('|<!--{elseif (.*)}-->|isU', '<?php }elseif(\\1){ ?>', $str);
                $str = preg_replace('|{eval (.*)}|isU', '<?php \\1; ?>', $str);
                $str = preg_replace('|{echo (.*)}|isU', '<?php echo \\1; ?>', $str);
                $str = preg_replace('|{include_php (.*)}|isU', '<?php if(is_file("\\1.php")){ include_once("\\1.php");} ?>', $str);
                $str = preg_replace('|{include_htm(.*) (.*)}|isU', '<?php if(is_file("\\2.htm\\1")){ $str = file_get_contents("\\2.htm\\1"); echo $str;} ?>', $str);
                $str = preg_replace('|<!--{loop (.*) (.*) (.*)}-->|isU', '<?php if(is_array(\\1)){ foreach(\\1 as \\2 => \\3){  ?>', $str);
                $str = preg_replace('|<!--{/loop}-->|isU', '<?php }} ?>', $str);
                $str = preg_replace('|{template (.*)}|isU', '<?php include_once(zTemplate("\\1", "'.$templatedir.'", "'.$compliedir.'")); ?>', $str);
                @file_put_contents($compliedir.md5($filename).'.php', $str);
        }
        return $compliedir.md5($filename).'.php';//返回模板结果
}
include_once(zTemplate('template.html','template/', 'templates/'));
?>

作者: zshtom   发布时间: 2008-01-31

作者: luzhou   发布时间: 2008-01-31

果然精悍  支持!

作者: phper1001   发布时间: 2008-02-01

作者: strongability   发布时间: 2008-02-02

直接嵌入不更好……
PHP本身就是模板引擎嘛……

作者: reus   发布时间: 2008-02-02

都是高手啊

作者: php?   发布时间: 2008-02-04

确实还是很不错的~

作者: luzhou   发布时间: 2008-02-04

还是没有摆脱:
只见结构,不见预览
TagFeather 能解决一个问题
2.美工往往看不懂模版的逻辑,里面的逻辑太多了。
TagFeather 能完全解决这个问题,美工只要按照指定的 class ,id  去做就行了,
甚至你可以很容易扩展: 【】里面的不要是要变化的,其他都可以.
1.smarty的标签对美工来说看起来很怪异,不接受,而实际上开发过程中,排版效果非常差。
3 动态排列表格  TagFeather 能实现,但目前还不够好用
    4.phplib简单,标签看起来一目了然。
php本身也是一个模版语言,不想把复杂的逻辑写在模版里面,对于实际项目中你会发现用php这些会更简单。
TagFeather 支持在模板里写 php (目前不能关闭此功能,但你可以写扩展关闭此功能)

作者: dvaknheo   发布时间: 2008-02-04

在开发一些比较复杂和需要运行期能够定制的时候,这种方式就是可怕的噩梦,比如3列还是2列,带不带图,页面的layout的变动,你也需要更新相应的php代码。

页面布局的变动只需要更改 class /id 的位置.TagFeather 目前就已经实现的功能.
2列或3列 只需要在代码里修改一个数字,这也是 TagFeather 目前已经实现的功能.
你可以扩展 TagFeather 达到 根据预览的列数 实际输出列数(TagFeather 下一版本的功能)

作者: dvaknheo   发布时间: 2008-02-04

数组循环很恐怖,不支持多层嵌套。只能应用在小型应用上,例如留言板。

如果写个留言板,使用模版又没太大必要。

纯属友情支持一下。

作者: smallwl   发布时间: 2008-02-12

楼主能不能提供下工作流程

作者: lions   发布时间: 2008-02-12

高手都是自己写模版呀!!!那在同一团队开发是谁去适合谁呢?

作者: yiqing666   发布时间: 2008-02-13

近来在网上看到的这个---》类,放出来高手点评一下。
核心文件VarPage.class.php

<?php
class VarPage {
   var $templatefile = "./template.html";
   var $varnamelist = "title,content";
   var $title = "Page Title Here";
   var $c;
   function VarPage(){
   }
   function display_page() {
      $vararray = explode(",",trim($this->varnamelist));
      $templatearray = file($this->templatefile);
      $template = join("",$templatearray);
      foreach ($vararray as $varname) {
         $template = str_replace("<!--$varname-->",$this->$varname,$template);
      }
      print $template;
   }
}
?>

处理文件
<?php
include("./VarPage.class.php");
$page = new VarPage;
$page->templatefile = "./template.html";
$page->varnamelist = "title,headline,content";
$page->title = "Welcome To My Page";
$page->headline = "What My Page Is About";
$page->content .= <<<EOD
<p>Some regular text on my page. <b>Bold Blah blah blah blah.</b>
Blah blah blah blah. Blah blah blah blah. Blah blah blah blah.
Blah blah blah blah. Blah blah blah blah. Blah blah blah blah.
Blah blah blah blah. Blah blah blah blah. Blah blah blah blah.
Blah blah blah blah. Blah blah blah blah. Blah blah blah blah.
Blah blah blah blah. Blah blah blah blah. Blah blah blah blah.
Blah blah blah blah. Blah blah blah blah. Blah blah blah blah.</p>
<p><a href="/">Back To Home Page</a></p>
EOD;
$page->display_page();
?>

点一下,这个会不会比楼主的强一点。我可是不太懂。呵呵!

高手点评啊

作者: bobby_lau   发布时间: 2008-02-15

强烈学习中!

作者: jemmy117   发布时间: 2008-02-15