改进ASP语法打造更高效的模板语言
写过动态模板(包括ASP、JSP等)的人都知道一个动态模板有两个基础部分,静态部分和动态部分。静态部分就是我们想输出的静态内容,这部分内容是永远都不会变的,动态部分含有可执行代码,会在运行时得到不同的输出。比如如下ASP代码会根据人名的不同输出不同的内容:
如何将静态与动态这两部分很好的混合在一个模板中一直是动态模板的易用性关键,比如如果我想输出从1到5,以逗号分隔这样的文字时我可以用以下写法:
int length = 5;
%>
<%
for (int i = 1; i <= length; i++) {
if (i < length) {
%><%=i%>, <%
} else {
%><%=i%><%
}
}
%>
输出为: 1, 2, 3, 4, 5
我们可以通过指定length变量来调节到底输出多少个数字,这就是动态模板的优势:含有动态代码。在这个例子中,我们将动态部分作为阅读主体,将静态部分作为辅助,这样可以写出来的模板才是可读的。但问题是以上ASP语法对初看ASP的人来说实在不习惯,因为ASP语法中是不可以在动态代码中嵌套静态文字的,所以我们才需要调整动态标签的位置,使整体看起来像是动态部分为主体,静态部分为辅助一样。
实际情况中,有时以静态部分为主看的要更清晰些,有时以动态部分为主看的更清晰些,没有绝对的情况。在这个比较简单的例子中ASP语法的可读性还不算太差,但是如果换个稍微复杂点的你就会觉得ASP语法写出来的模板几乎无法阅读。示例如下:
情况1
void Foo() {
string name1;
// Do the right job
}
情况2
void Foo() {
// Erase your hard disk
}
ASP语法的动态模板
void Foo() {
<%
if (case1) {
%>string name1;
// Do the right job<%
} else {
%>// Erase your hard disk<%
}
%>
}
就像上面例子中你所看到的,ASP语法的可读性很差,尤其当我有一个动态部分中嵌套静态部分,而被嵌套的静态部分中又嵌套有动态部分这样的情况下尤为突出。那么能不能有一种语法可以让我做到静态与动态之间的嵌套呢?回答是肯定的!
DCG (Dynamic Code Generator) 是我在去年开始的一个个人项目,简单地说,它就是一个提供了动态模板引擎的dll。1.x版本采用了ASP语法作为模板语言,并且提供了一些相关使用工具。在2.0版本中,我的目标是更强更易扩展的引擎与更易使用与阅读的模板语言。现很荣幸地告诉大家,我于昨天发布了DCG 2.0的Alpha版本,实现了我的初期目标,更强更易扩展的引擎,更易使用的模板语言:DTL。
DTL是基于ASP语法的一个语法扩展,完全兼容ASP。刚刚我们谈到,是否可以在静态于动态部分之前嵌套的问题,现在让我们来看看使用DTL是如何写上面那个示例的。
void Foo() {
<%
if (case1) {
<%!
string name1;
// Do the right job
!%>
} else {
<%!
// Erase your hard disk
!%>
}
%>
}
<%! !%>标签是用来在一个动态标签内标明一段静态文字。注意静态内容的每一行开始都是与<%!标签对齐的,当输出时,结果会输出到<%!标签所属的<%标签的位置去。
现在有了静态标签,我们就可以随意的做嵌套了,如:
if (condition) {
<%!
Content is:
<%
if (condition2) {
<%!
Content1.
!%>
} else {
<%!
Content2.
!%>
}
%>
!%>
}
%>
这可要比等价的ASP写出来的好看多了,最重要的是在编写模板的过程中利用DTL很直观,不会因为ASP语法的限制打断你的思路,从而提高你的效率,减少你的头疼率、压力,保护你的健康!:D
DTL还有一项语法增强,不过我会留到在下篇Blog中讲解,敬请关注!
如果你对此很感兴趣,想自己试验一下的话那么还等什么,赶快去下载Alpha版本吧,任何反馈都是受欢迎的。^_^
二进制下载页面
http://dcg.tigris.org/servlets/ProjectDocumentList
源代码获取方式
建议使用TortoiseSVN获取:
Repository src dir
http://dcg.tigris.org/svn/dcg/trunk
用户名
guest
密码
guest
目前还没有充分的整理文档,使用请参考单元测试项目中的测试用例,另外请看生成的SDK文档,如果你获取源码编译,可以用NAnt使用项目中的default.build编译,你可能需要在这个文件中手动设置一下编译相关工具的路径。任何使用问题请用此Blog与我联系,任何bug或建议请使用项目首页中的Issue Tracker(可能需要你在Tigris注册,Tigris是一个面向开发人员的开源平台)。
DCG的license为LGPL,请尊重软件,尊重license!