介绍下简单模版eastm

2008-02-23 09:42:37来源:互联网 阅读 ()

新老客户大回馈,云服务器低至5折

eastm是受fastm的启发而产生的一个简单模版引擎项目。eastm继承了其他一些简单模版的优点如类似PHP模版使用html注释做标签,所见即所得;及fastm的只读模版树和数据树通过引擎进行匹配提高解析效率。其中溶入了我自己的一些想法。目前还在实现阶段。

应该说简单模版概念是非常有前景的:页面容易维护,页面逻辑重用,当然还有一个优点:引擎实现相对容易,咱也能做一个:)。现在简单模版的主要问题是和一些脚本模版如velocity等相比,后台组装页面数据的Java代码量偏多。eastm打算在这方面做些努力。我试图使eastm拥有更强大的数据访问能力,同时就能减少大量的后台java组装代码。

大致做法是:
为加强数据访问能力,模仿脚本模版语法中的变量作用方式,页面上所有数据打印都是访问已定义和计算好的变量及属性,在子块中能访问父块的变量。这很容易理解,比如:
//root块
var a = new Object;
print(a);

if(...){ //if块
print(a);
}
for b in blist{ //list块
print(a.prop1);
print(b);
}

以上的代码就是a在变量作用的if,list子块都能被访问。
不同的是,eastm虽然模仿这种变量和属性的访问方式,但所有的变量计算和定义都放在java中做。以保持html模版页面的整洁。
同样,也是从语法树的概念,eastm抽象出了三个实现动态内容的标签:list,if(是分支判断),not(非分支判断)

后台组装代码一次性将一个完整的语法树运行完,并用树状VarContext保存所有分支和循环中运算好的变量,然后和html模版树进行匹配,eastm使用el表达式打印变量及属性。而VarContext的概念就是上面例子中的块的概念,其中的root块,if块,list块就都是VarContext,后两者是root块的子。而list块因为会运行多次,所以会有多个VarContext保存其运行过程中的变量。

下面是一个典型的eastm模版(是代码擂台学生科目跨行的例子):
[code]
<table border=1>
<!-- begin list: _students --> 
<!-- begin list: _subjects -->
<tr>
<!-- begin if: first -->
<td rowspan="${subjectNumber}">${student.name}</td>
<td rowspan="${subjectNumber}">${student.average_score}</td>
<!-- end if: first -->
<td> ${subject.name} </td>
<td> ${subject.score} </td>
</tr>
<!-- end list: _subjects -->
<!-- end list: _students -->
</table>

[/code]
上面的_students,_subjects都是在java中定义好的VarContext块
而student,subject还有first,subjectNumber则是其中的变量。
java代码大致是这样:

[code]
//data:students:student1,student2
//data:student1
// student1.subjects:subject11,subject12;
//data:student2
// student2.subjects:subject21,subject22,subject23;

VarContext root = VarContext.createRoot();

for(Iterator ite=students.iterator();ite.hasNext;){

Student stu = (Student)ite.next();
//学生
VarContext student = root.appendChildTo("_students");
student.defVar("student",stu);
student.defVar("subjectNumber",stu.getSubjects().size());
//学生的功课
for(int i=0;i<stu.getSubjects().size();i ){
VarContext subject = student.appentChildTo("_subjects");
subject.defVar("subject",stu.getSubjects().get(i));
if(i=0)
subject.defVar("first",true);
}

}
//构造模版
...
//模版匹配数据
template.toString(root);

[/code]

其中java代码主要演示如何定义变量和子VarContext,因为模版可以直接访问变量属性,所以这方面的java设置代码可以省略。注意subjectNumber定义在_students块,但其在模版的_subjects块可以访问。

再贴个代码擂台的例子(多个服务显示自动换行),其中考虑了模版中保持一行四列的布局:

[code]
<table border=1>
<!-- begin list: service_categorys -->
<tr>
<td colspan="4">${category.name}</td>
</tr>
<!-- begin list: _services -->
<tr>
<td>
${service0.name}
</td>
<td>
<!-- begin if:service1 -->${service1.name}<!-- end if:service1 -->
<!-- begin not:service1 -->&<!-- end not:service1 -->
</td>
<td>
<!-- begin if:service2 -->${service2.name}<!-- end if:service2 -->
<!-- begin not:service2 -->&<!-- end not:service2 -->
</td>
<td>
<!-- begin if:service3 -->${service3.name}<!-- end if:service3-->
<!-- begin not:service3 -->&<!-- end not:service3 -->
</td>
</tr>
<!-- end list: _services -->
<!-- end list : service_categorys -->
</table>
[/code]
[code]
// data : serviceCategorys (List of Category)
// data : category.services (List of Service)

VarContext root = VarContext.createRoot();
for(Iterator ite=serviceCategorys.iterator();ite.hasNext();){

Category category = (Category)ite.next();
VarContext cateContext = root.appendChildTo("service_categorys");
cateContext.defVar("category",category);

List services = category.getServices();
int i = 0;
while(i<service.size()){

标签:

版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com
特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有

上一篇:初学Java注意什么?

下一篇:Antlr--看Hibernate3如何解释HQL语言(上)