|
锁定老贴子 主题:介绍下简单模版eastm
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
|
|
|---|---|
| 作者 | 正文 |
|
最后更新时间:2005-06-15
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:1] <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:1] 上面的_students,_subjects都是在java中定义好的VarContext块 而student,subject还有first,subjectNumber则是其中的变量。 java代码大致是这样: [code:1] //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:1] 其中java代码主要演示如何定义变量和子VarContext,因为模版可以直接访问变量属性,所以这方面的java设置代码可以省略。注意subjectNumber定义在_students块,但其在模版的_subjects块可以访问。 以上大致演示了eastm的主要功能和使用方式。这也是eastm目前要实现的主要功能。 当然上面的例子是要计算页面跨行逻辑,所以有一定的代码量,对一些可以直接展示的POJO和Map,我会在engine实现以后做一些方便的方法,直接将这类对象和其List子对象附着到VarContext树上供页面展示,这样的话代码组装量会大大减少。 再往后,eastm模版还要做进对基础类型如数字,日期等的格式化展示。增强模版页面的展示能力. 如果顺利的话,自然以后还会做进对现有mvc web框架的支持。因为这也是我开发eastm的目的之一了。 欢迎buaawhl,庄表伟还有其他对简单模版有兴趣的人一起来讨论讨论 声明:JavaEye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
|
|
| 返回顶楼 | |
|
最后更新时间:2005-06-15
java的构造部分还是很麻烦阿。
麻烦程度和 fastm 的 valueset 一样。 那个 begin if 的优势没有体现出来。 多数情况下,fastm 1.0 M的OGNL不再需要这些麻烦的ValueSet/VarContext组装了。 |
|
| 返回顶楼 | |
|
最后更新时间:2005-06-15
buaawhl 写道 java的构造部分还是很麻烦阿。
麻烦程度和 fastm 的 valueset 一样。 那个 begin if 的优势没有体现出来。 多数情况下,fastm 1.0 M的OGNL不再需要这些麻烦的ValueSet/VarContext组装了。 首先我觉得使用简单模版,后台代码量比脚本模版大是一定的,我们要做的就是想办法使这些代码尽量少点。 begin if的优势体现在直接对变量或其属性的true/false判断(空或非空判断)而不用后台组装代码了。当然这里有跨行的页面逻辑,自然要计算一下。 fastm好像不支持对valueset中变量的属性访问吧? 我倒是觉得数据还是组装到VarContext上比较好,engine访问起来就比较统一了。否则fastm以后再要支持非Pojo,Map类型的数据,你又要对engine动手术了。至于节省代码,上面说过,我可以通过工具类将数据自动附着到VarContext上的。 |
|
| 返回顶楼 | |
|
最后更新时间:2005-06-18
再贴个代码擂台的例子(多个服务显示自动换行),其中考虑了模版中保持一行四列的布局:
[code:1] <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:1] [code:1] // 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()){ VarContext servContext = root.appendChildTo("_services"); servContext.defVar("service0",services.get(i)); if(i++ < service.size()) servContext.defVar("service1",services.get(i)); // else // servContext.defVar("service1",null); if(i++ < service.size()) servContext.defVar("service2",services.get(i)); // else // servContext.defVar("service2",null); if(i++ < service.size()) servContext.defVar("service3",services.get(i)); // else // servContext.defVar("service3",null); i++; } } [/code:1] |
|
| 返回顶楼 | |
|
最后更新时间:2005-06-16
几年前,我做过一个用JAVA实现PHP模板的功能.搞的跟PHP的TEMPLATE一模一样.当时在TOMCAT下使用.
由于JAVA的I/O先天不足,速度不快,所以象PHP一样的使用模板,性能有问题.后来在新版的TOMCAT上用,速度可以接受了,但是总是以为JAVA的I/O先天不足,不能适应广泛需要,所以不用了,现在 这些代码现在都不知道扔到哪里去了. 现在找个开源的来用用,适应了就好,没多少必要自已开发吧? |
|
| 返回顶楼 | |
|
最后更新时间:2005-06-16
dhj1 写道 现在找个开源的来用用,适应了就好,没多少必要自已开发吧? 我以前搜索过,只找到一个JDynamiTe,用法上比较麻烦。 PHP可以用 xxxx -> xxxx 这样的语句,而JDynamiTe只能 context.put, 然后evaluate, 然后add to result。valueSet一开始就是从jdynmiTe context上演化出来的。 dhj1 写道 由于JAVA的I/O先天不足,速度不快,所以象PHP一样的使用模板,性能有问题.后来在新版的TOMCAT上用,速度可以接受了,但是总是以为JAVA的I/O先天不足,不能适应广泛需要,所以不用了, 如果按照JDynamiTe那种顺序填充template的用法,和用xml dom差不多,直接修改了template 的内容。 fastm采用的思路是,template dom is read only. 外加object dom,就出来结果。 dhj1现在用的是什么template? 我以前在做fastm之前,找了好久适合的template,没有找到,才不得不自己写了个简单的实现。 |
|
| 返回顶楼 | |
|
最后更新时间:2005-06-16
buaawhl 写道 dhj1 写道 现在找个开源的来用用,适应了就好,没多少必要自已开发吧? 我以前搜索过,只找到一个JDynamiTe,用法上比较麻烦。 PHP可以用 xxxx -> xxxx 这样的语句,而JDynamiTe只能 context.put, 然后evaluate, 然后add to result。valueSet一开始就是从jdynmiTe context上演化出来的。 dhj1 写道 由于JAVA的I/O先天不足,速度不快,所以象PHP一样的使用模板,性能有问题.后来在新版的TOMCAT上用,速度可以接受了,但是总是以为JAVA的I/O先天不足,不能适应广泛需要,所以不用了, 如果按照JDynamiTe那种顺序填充template的用法,和用xml dom差不多,直接修改了template 的内容。 fastm采用的思路是,template dom is read only. 外加object dom,就出来结果。 dhj1现在用的是什么template? 我以前在做fastm之前,找了好久适合的template,没有找到,才不得不自己写了个简单的实现。 我没对fastm作过深入的了解,只是细细读过fastm的文档. 从你的贴子上看,你好象是fastm的作者. 如果以后fastm在升级中有以下功能了,请告诉我一下,我一定会喜欢fastm的. 1. 把数据放入STRING,或原始变量中,或LIST,SET,ARRAY,MAP等集合中,就可以方便的通过标签在表现层表现出来. 2.插入标签的模板文件,可以服务启动时,只读一次,就存在内存中,再也不需要从硬盘中读取,这能解决i/O的问题. FASTM开发了这么多功能,再加入这两点支持,应该不算难吧. |
|
| 返回顶楼 | |
|
最后更新时间:2005-06-16
dhj1 写道 我没对fastm作过深入的了解,只是细细读过fastm的文档. 从你的贴子上看,你好象是fastm的作者. 如果以后fastm在升级中有以下功能了,请告诉我一下,我一定会喜欢fastm的. 1. 把数据放入STRING,或原始变量中,或LIST,SET,ARRAY,MAP等集合中,就可以方便的通过标签在表现层表现出来. 2.插入标签的模板文件,可以服务启动时,只读一次,就存在内存中,再也不需要从硬盘中读取,这能解决i/O的问题. FASTM开发了这么多功能,再加入这两点支持,应该不算难吧. 第2点特性,fastm一开始出现的时候就具备。 :-) 一份Read Only Template, 多份不同的object dom 和 同一份template匹配,就出来结果。 第1点特性,fastm1.0M 具备了,支持OGNL。 fastm 1.0 Milestone 发布 http://forum.javaeye.com/viewtopic.php?t=13404 |
|
| 返回顶楼 | |
|
最后更新时间:2005-06-16
dhj1 写道 几年前,我做过一个用JAVA实现PHP模板的功能.搞的跟PHP的TEMPLATE一模一样.当时在TOMCAT下使用.
由于JAVA的I/O先天不足,速度不快,所以象PHP一样的使用模板,性能有问题.后来在新版的TOMCAT上用,速度可以接受了,但是总是以为JAVA的I/O先天不足,不能适应广泛需要,所以不用了,现在 这些代码现在都不知道扔到哪里去了. 现在找个开源的来用用,适应了就好,没多少必要自已开发吧? 我总觉得php那种模版还是过于简单,而页面的简单则意味着后台的复杂. 我打算把eastm做成更强大点的模版. |
|
| 返回顶楼 | |
|
最后更新时间:2005-06-16
goldrain 写道 dhj1 写道 几年前,我做过一个用JAVA实现PHP模板的功能.搞的跟PHP的TEMPLATE一模一样.当时在TOMCAT下使用.
由于JAVA的I/O先天不足,速度不快,所以象PHP一样的使用模板,性能有问题.后来在新版的TOMCAT上用,速度可以接受了,但是总是以为JAVA的I/O先天不足,不能适应广泛需要,所以不用了,现在 这些代码现在都不知道扔到哪里去了. 现在找个开源的来用用,适应了就好,没多少必要自已开发吧? 我总觉得php那种模版还是过于简单,而页面的简单则意味着后台的复杂. 我打算把eastm做成更强大点的模版. 对别人也许要功能强大,本人只是做一般WEB的应用程序,所以只是简单的模板就够用了. 我最关心是有几点: 1.节省学习源资,如果你做的用法跟PHP的TEMPLATE一模一样最好,无需再次学习使用方法. 2.高效,真正用于项目时,不会因为性能问题,访问的流量大问题,而导致整个项目的失败. 3.开发快速.方便易用.象PHP的模板一样简单好用. 4.稳定. 然后我才会考虑是否功能强大. 当然功能强大最好了. 希望看到你的eastm早日延生! |
|
| 返回顶楼 | |






