手机浏览 RSS 2.0 订阅 膘叔的简单人生 , 腾讯云RDS购买 | 超便宜的Vultr , 注册 | 登陆
浏览模式: 标准 | 列表Tag:template

javascript模版系统

用javascript做模版的话,说来也算是比较方便的,特别是对于PHP开发来说,只要扔一个json数组过来。然后剩下的就可以让javascript来完成了。
搜索一下jQuery的plugin,可以找到大约5~6个模版程序。好象用的比较多的还是jTemplate,上一次司徒正美用javascript写了一个简单的例子,这次又写了一个比较详细的,说是v2,有兴趣的朋友可以尝试一下。。
--start--司徒正美认为模版要处理复杂的玩意,所以写的功能就强大了。
本版本主要是对原模板系统进行提速,去掉消耗巨大的辅助函数。本来想用它与John Resig的 Micro-Templating比较一下速度,发现对方无法处理复杂的模板,残念。

JavaScript代码
  1. //司徒正美 javascript template - http://www.cnblogs.com/rubylouvre/ - MIT Licensed  
  2.      (function () {  
  3.                if(!String.prototype.trim){  
  4.                    String.prototype.trim = function(str) {  
  5.                        return this.replace(/^[\s\xa0]+|[\s\xa0]+$/g, '');  
  6.                    }  
  7.                }  
  8.                var dom = {  
  9.                    quote: function (str) {  
  10.                        str = str.replace(/[\x00-\x1f\\]/g, function (chr) {  
  11.                            var special = metaObject[chr];  
  12.                            return special ? special : '\\u' + ('0000' + chr.charCodeAt(0).toString(16)).slice(-4)  
  13.                        });  
  14.                        return '"' + str.replace(/"/g, '\\"') + '"';  
  15.                    }  
  16.                },  
  17.                metaObject = {  
  18.                    '\b''\\b',  
  19.                    '\t''\\t',  
  20.                    '\n''\\n',  
  21.                    '\f''\\f',  
  22.                    '\r''\\r',  
  23.                    '\\': '\\\\' 
  24.                }, 
  25.                parser = document.createElement("div"), 
  26.                startOfHTML = "\t__views.push(", 
  27.                endOfHTML = ");\n"; 
  28.            
  29.                //onsite,可选,Boolean,是否就地替换掉模板容器,默认true,如果为false,则返回一个文档碎片,交由用户自己插入到需要的地方 
  30.                dom.ejs = function (obj) { 
  31.                    var onsite = obj.onsite === void 0 , 
  32.                    left = obj.left || "<%", 
  33.                    right =obj.right || "%>", 
  34.                    selector = obj.selector, 
  35.                    isLeft = true, 
  36.                    buff = ["var __views = [];\n"], 
  37.                    fragment = document.createDocumentFragment(), 
  38.                    el = document.getElementById(selector), 
  39.                    ejs = dom.ejs; 
  40.                    if (!el) throw "找不到目标元素"; 
  41.                    var str = el.text.trim(); 
  42.                    if(!ejs[selector]){ 
  43.                        while(str.length){ 
  44.                            var condition = isLeft ? left :right; 
  45.                            var index = str.indexOf(condition); 
  46.                            if(index !== -1){//取左边 
  47.                                var text = str.slice(0,index); 
  48.                                if(isLeft){ 
  49.                                    buff.push(startOfHTML, dom.quote(text.trim()), endOfHTML); 
  50.                                }else{ 
  51.                                    switch (text.charAt(0)) { 
  52.                                        case "#"://处理注释 
  53.                                            break; 
  54.                                        case "="://处理后台返回的变量(输出到页面的); 
  55.                                            buff.push(startOfHTML, text.slice(1), endOfHTML) 
  56.                                            break; 
  57.                                        default: 
  58.                                            buff.push(text, "\n") 
  59.                                    }; 
  60.                                } 
  61.                            }else{ 
  62.                                if(isLeft){ 
  63.                                    buff.push(startOfHTML, dom.quote(str), endOfHTML); 
  64.                                    break; 
  65.                                }else{ 
  66.                                    throw "在字符串{{ "+dom.quote(str)+" }}中找不到右界定符"+right 
  67.                                } 
  68.                            } 
  69.                            str = str.slice(index+2).trim(); 
  70.                            isLeft = !isLeft; 
  71.                        } 
  72.                        ejs[selector] = new Function("json", "with(json){"+buff.join("") + '};return __views.join("");')  
  73.                    }  
  74.                    parser.innerHTML = ejs[selector](obj.json || {});  
  75.                    while (parser.firstChild) {  
  76.                        fragment.appendChild(parser.firstChild)  
  77.                    }  
  78.                    return onsite ? el.parentNode.replaceChild(fragment, el) : fragment;  
  79.                };  
  80.                window.dom = dom;  
  81.   
  82.            })();  

这种使用原生代码写的例子,可以被任何代码所使用,如果你有兴趣也可以看看司徒正美的例子的。原文网址在javascript 模板系统 ejs v2,可以移步一观。

Tags: jquery, template, 模版, 模板

TP1.5版本中使用smarty模版引擎的技巧

从TP1.5开始,对于其他的模版引擎有了原生支持(不再是以前那种插件机制了)。
本文以使用smarty模版为例作点简单介绍,其他的,可以参考一下View.class.php中的fetch方法可知。

TP的SVN中已经含有smarty模版库,因此当你要使用的时候,只需要在项目的config.php里作一点简单的配置:

PHP代码
  1. 'TMPL_ENGINE_TYPE' => 'smarty',    //这个是设置引擎为smarty  


从2009-01-07下午的SVN版本里,流年为又增加了一个TMPL_ENGINE_CONFIG这个数组,即:

PHP代码
  1. 'TMPL_ENGINE_CONFIG'array(  
  2.         'template_dir' => TMPL_PATH , //这个就是tpl目录了  
  3.         'compile_dir'  => CACHE_PATH . "tplCompile/"//这是我自己设定的,模版编译缓存放在这个目录里  
  4.         'cache_dir'    => CACHE_PATH . "tplCache/",   //如果需要生成页面缓存,这个也是必须的  
  5.         'left_delimiter' => '{',  
  6.         'right_delimiter' => '}',  
  7.         'caching' => false,  
  8.         'force_compile' => true,  
  9.         'compile_check' => true,  
  10. ),  


备注:如果按照我这样的写法,请到cache目录里手动创建tplCompile和tplCache两个目录,否则程序会报错。
报错信息大致为:

XML/HTML代码
  1. Catchable fatal error: Object of class Smarty could not be converted to string in D:\local\htdocs\ThinkPHP\Album\Temp\~runtime.php on line 145  


如果出现这样的报错信息,请先检查这两个目录是否存在

在项目开发的时候,caching 最好设为false,否则你根本看不到效果。

如此设定完毕后,你就可以直接在项目中使用了,下面以Index模块的index方法进行举例:在IndexAction.class.php的index的方法里

PHP代码
  1. $this->assign("test" , "This is a test string");  
  2. $this->display();  

然后到模版里:

XML/HTML代码
  1. {$test} 

就可以看到输出了。不过,这里需要注意的是,如果你$this->display()没有指定文件名,那么默认的模版文件就是default/Index/index.html,这点和原先使用TP默认的模版引擎没有什么区别。
出现问题最大的应该是在include方法里,include的使用方法是:{include file="Public/header.html"},就象我前面所说,smarty的模版路径只指到了tpl目录,但实际上,我们是在默认的default目录下操作,因此正确的写法应该是{include file="default/Public/header.html"}
如果我们写的程序要对应多模版,那么,上面那种直接写死default的方法是不行的,还好,TP为我们留了一个常量:TEMPLATE_NAME,于是我们的写法就可以是现在这样:

XML/HTML代码
  1. {include file="`$smarty.const.TEMPLATE_NAME`/Public/header.html"}  

现在试一下,是否公用目录里的header.html被加载了?

最后再报一个warning。如果是在WINDOWS下面开发并且开启了DEBUG_MODE,那么你在读取模版的时候,页面的Trace信息里,偶尔会出现一个注意:

 

XML/HTML代码
  1. [ 09-01-08 14:36:02 ] 注意:[2] unlink(./Cache/tplCompile/\%%70^706^706C3AFE%%index.html.php) [function.unlink]: No such file or directory core.write_file.php 第 44 行.  


这些信息,可以被忽略掉。模版文件还是会正常的生成和编译的。它只会在第一次生成模版编译文件的时候出现

Tags: thinkphp, smarty, template

smarty3即将出来

PHP的模版里,smarty一直就是让人又爱又恨的,功能太强大了,以致于美工们看到他也会感觉头疼,毕竟是又要学一门新的语言了。
这么多年,smarty都是在2.x版本里面徘徊,如今,终于要出3了。
以下是官方的change log:

10/6/2008

- completed compilation of {include} tag, variable scoping same as in smarty2

- added compilation of {capture} tag.

- added error message on none existing template files.

10/4/2008
- added comments in the parser definition y file.

- added array of $smarty_token_names to lexer for use in trigger_template_error function

- change handling of none smarty2 style tags like {if}, {for}....

- lexer/parser optimization

10/3/2008

- create different compiled template files depending if caching and/or security is enabled

- cleaned up compiler

- lexer/parser optimization

10/2/2008

- new method trigger fatal error, displays massage and terminates smarty

- compile error status flag added
The compiler will in case of error continue to parse the template(s) to display all errors. No compiled
templates will be written, Smarty terminates after the compiler exits.

- added error message to function __call in Smarty.class.php

Tags: smarty, version, php, template, smarttemplate

解决使用ThinkPHP框架自带模版程序处理<??>出现的问题

使用ThinkPHP自带的模版引擎处理模版问题时,一般情况下不会有什么问题。

但是,在处理一些XHTML模版时,可能会遇到以下问题,比如,模版作者在制作模版时,为了规范页面,往往在文件头部加上<?xml version="1.0" encoding="utf-8"?>,表明文件是属于XML规范,所有的标签都必须遵循XML的相关规定。

然而,默认的ThinkPHP模版引擎在处理的时候会出现错误,处理这个错误的情况有以下几种办法。

第一种方法:你尝试关闭PHP的短标签功能
第二种方法:试着用<literal></literal>标签把XML的标签包含起来,即
<literal><?xml version="1.0" encoding="utf-8"?></literal>

 

第三种方法:修改ThinkPHP/Lib/Think/Template/ThinkTemplate.class.php的compiler函数,在函数的最后一行return $templContent;前加入

PHP代码
  1. // 将<?标签用echo方式输出   
  2. $tmplContent = preg_replace('/(<?(?!php|=|$))/i''<?php echo '\1'; ?>'."n"$tmplContent );   

任何一种方法理论上都可以,第一种第二种方法实在不行的时候,再用第三种,毕竟第三种方法是改动核心的,如果以后更新核心库,可能会不当心就覆盖掉了。

不过,流年说过了,他已经更新了模板引擎的解析类,并且专门判断了是否开启了短标签,如果开启的话会自动用第三种方法解析。更新下SVN的ThinkTemplate.class.php 文件就可以了(可能压缩包还没有同步更新[2008-04-22])。

 

Tags: thinkphp, template, 短标签