一 模板编程编程综述
模板编程在MVC模型的WEB编程中占据着重要的地位,它具有将数据逻辑层次和用户界面层次分离的作用。它的使用能够让程序员能够减少了逻辑思维切换带来的内耗,保持逻辑思维的连贯性,同时有利于代码的模块化以及层次的抽象。但是从我个人观点来看模板编程在一个项目当中不应该成为核心角色,它只是一个辅助角色,也可以将它视作为逻辑层次所要实现的一个特性。
模板编程在实现上不是实现了一门编程语言,它更像是一个组合:
A) 作出一系列关于变量以及简单逻辑的宏定义,然后在模板中就使用这些宏定义来编写。
B) 在逻辑层次通过API等形式来将真正的变量去取代模板中的宏定义。
它的工作流程大体上是经历以下几个步骤:
1) 将数据按照某种组织形式组织起来。通常是生成一个数据对象。
2) 装载对应的模板,并且与数据对象相关联
3)完成变量替换,生成最终显示结果
PHP中常用的模板库有PEAR库中的Template类,Smarty...Perl中常用的模板库有HTML::Template,HTML::Template...等,他们适用于数据量不大,负载不是很高的应用。
二 clearsilver编程概述
下面介绍一种称之为clearsilver的模板编程。clearsilver实际上由c语言来提供对变量的替换,同时对各个语言(python, perl, c, java)进行了API封装。clearsilver适用于数据量很大的应用。
下面按照模板编程的工作层次介绍clearsiver的工作方式:
1) clearsilver引入了HDF格式的数据结构,
* HDF是一种文档格式,它是采用以下的格式来表现数据结构,如
key1 = val1
key2 {
item1 = val2
item2 = val3
}
在上面中涉及到HDF路径以及值的概念
如key1,key2, key2.item1,key2.item2就是HDF路径, val1, val2, val3就是分别与它们对应的值.而key2对应的就是如下一个子HDF对象:
item1 = val2
item2 = val3
下面为Perl的几个重要的数据组织接口:
$hdf = ClearSilver::HDF->new(); #初始化HDF对象
$hdf->readFile(STRING:$filename); #由指定的HDF格式的文件名设置数据
$hdf->setValue(STRING:$hdfpath,STRING:new_value); #设置$hdfpath的值
2) 在clearsilver中采用了称之为CS的对象来将模板引入,并且与HDF数据对象相关联。
如
$cs = Clearsilver::CS->new(HDF:$my_hdf);
完成上步以后就可以引入由字符串模板:
$cs->parseString(STRING:$cs_code_string);
或者引入文件模板:
$cs->parseFile(STRING:$cs_filename);
在这里,clearsilver的模板宏语法分为
变量替换,流程控制,迭代,宏。详情参见:
http://www.clearsilver.net/docs/man_templates.hdf
3) 在完成上述过程之后,可以使用
$cs->render(); 来生成最终的结果。
4) 除了上述的操作之外,clearsilver提供了许多便捷的高级属性的操作支持。
* 在HDF对象的操作中支持获取某个HDF路径对应的数值;能够将一个子HDF对象赋值给另外一个HDF路径,简化某些赋值操作。
* 可以使用CGI Tookit模块: 通过引入此命名空间,可所以在模板层次获得GET, COOKIE等数据而不需要通过逻辑层。
5) clearsiverl的一个“可能的缺点”
当前版本的clearsivler尚不支持在完成变量替换后此行为空行则自动删除此行的特性,它仅仅将自身的宏代码以变量置换。因为clearsilver对换行,tab等不可见字符和其他可见字符一视同仁。但是在编写模板时可以进行不换行的技巧来实现这点。
附录)
*) clearsiver的官方站点:
http://www.clearsilver.net/
*) 获取安装clearsilver:
http://www.clearsilver.net/downloads/
*) 范例
#!/usr/bin/perl
# Sample of clearsilver programming
use strict;
use ClearSilver;
# 模板,(此处的模板也可以写成模板文件,然后下面的载入模板的接口换成相对应的接口即可)
my $template = <<TEMPLATE;
Sample Of ClearSilver
<?cs if:key1 ?>
<?cs var:key1 ?>
<?cs else ?>
no key1
<?cs /if ?>
<?cs each:item=key2 ?>
<?cs var:item ?>
<?cs /each ?>
TEMPLATE
# 1) 准备数据
my $hdf = ClearSilver::HDF->new();
$hdf->setValue("key1", "val1");
$hdf->setValue("key2.item1", "val2");
$hdf->setValue("key2.item2", "val3");
# 2) 设置关联模板
my $cs = ClearSilver::CS->new($hdf);
$cs->parseString($template);
# 3) 输出数据
print $cs->render();
clearsilver-C-API文档(CS部分) cs_dump – 转存cs解析 NEOERR *cs_dump (CSPARSE *parse, void *ctx, CSOUTFUNC cb); Cs_destroy – 销毁创建的cs_parse tree void cs_destroy (CSPARSE *parse); cs_render – 渲染cs解析 NEOERR *cs_render (CSPARSE *parse, void *ctx, CSOUTFUNC cb); *cs_register_esc_strfunc – NEOERR *cs_register_esc_strfunc(CSPARSE *parse, char *funcname,CSSTRFUNC str_func); *cs_register_fileload – 注册一个加载文件函数 void cs_register_fileload(CSPARSE *parse, void *ctx, CSFILELOAD fileload); cs_init –创建初始化一个cs 类型 NEOERR *cs_init (CSPARSE **parse, HDF *hdf); *cs_register_strfunc – 注册一个字符串型函数 NEOERR *cs_register_strfunc(CSPARSE *parse, char *funcname, CSSTRFUNC str_func); Cs_parse_string – 解析一个CS模板字符串 NEOERR *cs_parse_string (CSPARSE *parse, char *buf, size_t blen); cs_parse_file –解析一个CS模板文件 NEOERR *cs_parse_file (CSPARSE *parse, const char *path); *cs_register_esc_function – NEOERR *cs_register_esc_function(CSPARSE *parse, const char *funcname,int n_args, CSFUNCTION function); dictDestroy -- 销毁一个字典
void dictDestroy(dictCtx dict); dictCleanup -- 清空一个字典
void dictCleanup(dictCtx dict, dictCleanupFunc cleanup, void *rock); dictReleaseLock -- 释放字典的锁
新市场营销法则 助推企业成长
电子商务营销 食品餐饮营销 建筑房产营销 消费品营销
void dictReleaseLock(dictCtx dict, void *lock); dictRemove -- 删除字典里的某个项目
BOOL dictRemove(dictCtx dict, const char *id); dictNext -- 获得字典里的下一个变量值
void *dictNext(dictCtx dict, char **id, void **plock); dictCreate -- 创建一个新字典
NEOERR *dictCreate(dictCtx *dict, BOOL threaded, UINT32 root,
UINT32 maxLevel, UINT32 flushLimit, BOOL useCase, dictFreeValueFunc freeValue,
void
*freeRock); dictSetValue -- 给字典里的项目设定值
NEOERR *dictSetValue(dictCtx dict, const char *id, void *value); dictModifyValue –创建或修改字典里的项目值 NEOERR *dictModifyValue(dictCtx dict, const char *id, dictNewValueCB new_cb, dictUpdateValueCB update, void *rock); dictSearch – 查找字典里的项目 void *dictSearch(dictCtx dict, const char *id, void **plock);