浏览 4797 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2007-04-15
基本功能均已实现,但0.x版本不保证向前兼容,API结构可能会有大的调整, 将在1.0版开始保持API稳定。 虽然很多东西还没做好,但还是想在第一时间与JavaEye的朋友分享。 希望得到各位的支持和帮助,也希望JavaEye成为Meteor使用开发交流的主战场。 (重复发明轮子之类的争辩就不用帖了,相信每样东西的存在,总有它的价值。) 项目站点: http://www.meteortl.org http://meteortl.sourceforge.net (很多超链接是假的,还没做好,请别介意,只有download的超链接有效) 下面是为申请sourceforge.net写的,写的很空洞,也算个介绍吧。 Meteor Introduction 1. What's the Meteor? Meteor is kind of Template Language. It belongs to presentation layer. JSP, Velocity, and FreeMarker are some of the similar products. 2. Why Meteor? First of all, I've to announce that I'm not going to reinvent the wheel. As I could find no Template Language ideal enough, at least not ideal enough in my opinion, I created Meteor. Let's figure out what users want about Template Language: UI Developer: 1) Do not destroy the UI in editor, even in HTML editor such as Dreamweaver. No unknown tag or directive should be shown. 2) It's the best for even no “${}” will be shown in editor. Such a long placeholder “${myitem.item.user.name.firstname}” will destroy the UI in editor. Using real data instead of placeholder is the best. 3) The rules should be as few as possible. 4) It's easy to tell apart. In javascript, using “$()” would confuse the developer because of “${}” in the template. Program Developer: 1) Strong function. Do not put the formation or simple logic in the code. 2) It's easy and simple to use. 3) It's uncomfortable that too many files related to one template. The Architecture: 1) No business logic should be included in template for the goal of MVC 2) Well expansibility. It should deal with most of exceptions automatically. Comparing with 3 of the most famous template languages, the reason for creating Meteor is shown as follows. JSP: official standard template language Version 1.0 is very hard to maintain for the mixture of code and HTML tags. And it has too many functions to be limited in the boundary of presentation layer. What about EL of Version 2.0? “${bean.property}” EL is not allowed to call a function(this limitation could be changed by settings, but it's not advised to do so). But the extended format is something like “${namespace:method(param1, param2, param3)}”. A public static method will be called by setting signature of method in tld. You may compare “${bean.property}” with “${namespace:method(param1, param2, parm3)}”. What are the common things between them except the “${}”. The expansion of JspTag seems to make developer dance with a heavy load. The engine declared proudly that you just need to return EVAL_BODY_INCLUDE, EVAL_PAGE, SKIP_BODY and so on, and the engine will take charge of anything else. As the result, you are just allowed to return one of the these values without exceptions. And you have to look up the specification to find out which one you should return. The engine will take the action according to your returned value. And you are not able to do anything that the engine is not pre-designed for. Is that exactly what an engine ought to do? Why not better expansibility? All of the engine should do is just translating the template into directives. Such as SKIP_BODY job should be processed by directives. Velocity: A kind of traditional template language which has the most developer. I have mentioned the disadvantages of FreeMarker. Please refer to <<FreeMarker vs. Velocity>> at http://freemarker.org/fmVsVel.html for details. But in my opinion, Velocity is relatively abbreviated. I think Velocity is better than FreeMarker. FreeMarker: The most popular template language nowadays. FreeMarker includes too much syntax rules such as : ${expression} #{expression} ?built-in !format <#name></#name> <@name></@name> as well as some internal keywords such as “as”. There are too much restrictions. All the directives are treated differently, and internal directives such as “if” and “list” are tied to the engine. The expansibility of FreeMarker is not good enough, either, and too many functions should be re-modified(we don't when). With the advent of more and more new built-in restrictions, the core of FreeMarker is going to grow bigger. The “Macro”, by which FreeMarker is characterized, is kind of expansion rules(fragment definition). But “Macro” is treated differently from standard directives. So, it would destroy WYSWYG. Although, fragment definition is necessary and I'm thinking about something different to achieve it. All the three kinds of template languages mentioned above will destroy WYSWYG, and all of them are using unfriendly placeholders such as “${…}”. Especially, “<#name>” in FreeMarker is even worse than jsp tag. Neither any HTML editors nor XML editors can recognize it while Jsp tag would ignore the editors at least. The angles are totally useless but making the context more complex. Even “#name” in velocity is better relatively speaking. Let's think about how to make expansions on final class such as “String”, “Number”, “Date” and so on. Jsp uses static methods such as “StringUtils.html(String str); ${s:html(str)}”, which are common in Java. FreeMarker uses built-in methods such as “${str?html}”. Actually, there is a better one called “open class”. Please think about what we will do to add attributes, which does not exists, to javascript and ruby. We could use all the attributes including additional ones with no differences. The engine should allow developers to do this instead of built-in methods or restrictions. 3. The advantages of Meteor. 1) There is only one thing “@name{expression”} including directives and expressions. Actually, expression is a kind of special directives. 2) WYSWYG in Dreamweaver and syntax coat is extensible. 3) Microkernel. Everything is additional except core API. Standard directives such as “for” and “if” could be replaced. Even the engine could be replaced partly. 4) Better extensibility. The engine is just on the duty of translating the template into directive-tree. The directives will finish the rest of the job by themselves. 5) “Open class” for final class as prototype in java instead of built-in in FreeMarker 6) Both implementations in java and .NET are available. 7) Web pages could be tested separately. 4. An example in Meteor: <table> <!--@for{users, "user", "status"}--> <tr> <td> <span id="@{status.index + 1}">1</span> </td> <td> <a href="detail.jsp?userid=@{user.id}"> <span id="@{user.name}">james</span> </a> </td> </tr> <!--@end--> </table> “<!--@{}-->” and “<span id="@{}"></span>” are syntax coat, and both of them will be recognized as “@{}” for WYSWYG in Dreamweaver. The parameters in the “for” expression are not traditional parameter-lists. They are just normal expressions containing commas (a standard expansion of operation which has two operands) 5. Progress report The last version is 0.1.18. The basic functions are completed including the engine and standard expansion. ---------------- I expect that Meteor could be released at your platform. thanks! 声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |
发表时间:2007-04-15
期待有兴趣的朋友参与。
项目分三个模块: 1.核心引擎模块:保持Microkernel理念,尽可能小,并且不与具体语法关联,语法是可以自定义的。 2.标准实现模块:定义标准语法,实现常用指令,表达式等的标准实现。 3.扩展模块:与各框架,平台集成相关模块。 一些原则: 1.必需保证模板编辑时WYSWYG(对美工的承诺)。 2.必需保证语法统一,不出现大堆的语法规定。 3.核心引擎必需尽可能小(Microkernel理念)。 4.保证尽可能的可扩展性,并且不出现常量契约,契约均以接口实现。 5.整个指令树必需线程安全,不维持任何状态。 当然还包括其它通用原则:如:OCP,IoC/DI,Liskov,Lod... 以后会整理成开发规范。 计划完成: 帮助文档完善,现在缺太多,没有文档的功能等于没有, 开发管理,保证构想、节奏、预见、协作、简化五原则的顺利进行, 发布站点制作,现在meteortl.org还是个空架子, 宏实现,可以用模板本身定义指令, XSLT解析实现, 核心模块简化, API结构调整(向前不兼容的调整), 有限状态自动机算法优化(语法解析), 语法使用习惯调查分析, 确定是否需要实现类似Tapestry的特殊属性标记(此方法也可以保护界面), 完善单元测试,突变测试,并发测试,性能测试, 友好异常,错误准确定位,以及异常信息国际化, 引擎生命周期管理,AOP事件回调, 配置管理,增强扩展性(首先保证可编程完成所有配置), 与各流行框架集成(Struts,WebWork,Spring,Ant,JSP等), 支持集群(序列化,Clone等慎重实现), 指令树冻结成.ser,以保持重用, Eclipse及NetBeans编辑器plug-in, 使用测试数据打开*.mtl的exe工具(通过改注册表的文件关联,双击*.mtl的文件,就会用测试数据解释成模板,并用IE显示出来), C#.NET引擎实现,保证多平台支持, 开发简易论坛进行实践, 希望参与者至少看过《设计模式》《重构》《Effective Java》《编译原理》等,但这不是要求。 QQ: 229056138 MSN/Email: liangfei0201 AT 163 DOT com |
|
返回顶楼 | |
发表时间:2007-04-15
文档还不是很完善,先发上来预览下。
Meteor 标准实现 使用指南 参见标准实现配置template-config.xml (位于meteor-x.x/standard/org/meteortl/standard/) 一、 语法: @name{expression} 二、 特殊符转义: 使用 \@ 输出非指令 @ 符 三、 指令扩展: (1) 输出:@out{user.name} 或 @{user.name} (2) 结束:@end{"first if"} 或 end{} 或 @end (3) 判断: @if{user.name == "james"} Content1 @elseif{ user.name == "kent"} Content2 @else Content3 @end (4) 迭代: @for{users, "user", "status"} @beak{status.count > 5} @{user.name} @end (5) 包含:@include{"common.mtl"} 四、 表达式扩展: (1) getter: . 属性取值,如:@{user.name} [] 其它取值,如:@{user["name"]} @{items[1]} @{items[1..2]} @{items[1,2,4]} (2) sequence: .. 序列生成,如:@{1..2} @{"Sunday".."Saturday"} , 列表,如:@{1,2,5,7} ,: Map生成,如:@{"a" : 100, "b": 2 , "c" : 7} (3) object: + toString字符串连接,如:@{user.firstname + user.lastname} == 值相等比较 ,如:@{user1 == user2} != 值不相等比较 ,如:@{user1 != user2} | 非空对象选择 ,如:@{user1 | user2} (4) boolean: && 逻辑与,如:@{user1.agree && user2.agree} || 逻辑或,如:@{user1.agree || user2.agree} ! 逻辑非,如:@{! user1.agree} ?: 逻辑选择,如:@{user1.agree ? "yes" : "no"} (5) number: + 加法运算,如:@{user1.coins + user2.coins} - 减法运算,如:@{user1.coins - user2.coins} * 乘法运算,如:@{user.coins * 2} / 除法运算,如:@{user.coins / 2} % 求模运算,如:@{user.coins % 2} > 数字大于比较,如:@{user1.coins > user2.coins} < 数字小于比较,如:@{user1.coins < user2.coins} >= 数字大于等于比较,如:@{user1.coins >= user2.coins} <= 数字小于等于比较,如:@{user1.coins <= user2.coins} ~ 数字格式化,如:@{user1.coins ~ "###,##0.###"} (6) string: + 两个字符串相连,如:@{user.firstname + user.lastname} > 字符串大于比较,如:@{user1.name > user2.name} < 字符串小于比较,如:@{user1.name < user2.name} >= 字符串大于等于比较,如:@{user1.name >= user2.name} <= 字符串小于等于比较,如:@{user1.name <= user2.name} (7) date: + 日期天数后推,如:@{user.registerDate + 3} - 日期天数前推,如:@{user.registerDate - 3} > 日期大于比较,如:@{user1.registerDate > user2.registerDate} < 日期小于比较,如:@{user1.registerDate < user2.registerDate} >= 日期大于等于比较,如:@{user1.registerDate >= user2.registerDate} <= 日期小于等于比较,如:@{user1.registerDate <= user2.registerDate} ~ 日期格式化,如:@{user.registerDate ~ "yyyy-MM-dd"} (8) array,list,map: + 两个List或Map相连,如:${items + ("a","b")} 五、 属性扩展 (1) boolean:not (2) string:cap, date, datetime, html, integer, long, float, double (3) date:era, century, year, month, day, dayInYear, week, hour, minute, second, millisecond, computer, timezone, lenient 六、 序列扩展 (1) 数字:@{-12 .. 20} @{20 .. -12} (2) 字母:@{a .. z} @{z .. a} @{A .. Z} @{b .. k} (3) 季节:@{'Spring' .. 'Winter'} (4) 月份:@{'January' .. 'December'} (5) 星期:@{'Sunday' .. 'Saturday'} 七、 Html语法扩展 (1) <span id="@name{expression}">XXX</span> 一般用于输出指令 (2) <!--@name{expression}--> 一般用于控制指令 八、 默认根属性: Servlet各范围属性取值:parameter, header, request, session, cookie, application 国际化信息:msg Action输出:model 九、 举例: <!--@for {users, "user", "status"}--> <span id="@{status.index}">1</span>. <a href="detail.jsp?userid=@{user.id}"> <span id="@{user.name}">james</span> </a> <!--@if {status.first.not}-->,<!--@end--> <!--@end--> |
|
返回顶楼 | |
发表时间:2007-04-15
当前版本的标准配置:
均可以自定义。 <template> <!-- engine setting --> <setting encoding="utf-8" functionAvailabled="true" /> <syntax begin="@" expressionBegin="{" end="}" escape="\" /> <!-- syntax cost --> <syntaxCoat left="<!--" right="-->" /> <syntaxCoat left="<span\s+id="" right="">.*</span>" /> <!-- directive define --> <directive name="" class="org.meteortl.standard.directive.output.OutDirective" /> <directive name="include" class="org.meteortl.standard.directive.include.IncludeDirective" /> <directive name="end" class="org.meteortl.standard.directive.GeneralEndDirective" /> <directive name="if" class="org.meteortl.standard.directive.condition.IfDirective" /> <directive name="elseif" class="org.meteortl.standard.directive.condition.ElseIfDirective" /> <directive name="else" class="org.meteortl.standard.directive.condition.ElseDirective" /> <directive name="for" class="org.meteortl.standard.directive.iteration.ForEachDirective" /> <directive name="break" class="org.meteortl.standard.directive.iteration.BreakDirective" /> <directive name="continue" class="org.meteortl.standard.directive.iteration.ContinueDirective" /> <directive name="comment" class="org.meteortl.standard.directive.comment.CommentDirective" /> <directive name="block" class="org.meteortl.standard.directive.comment.BlockCommentDirective" /> <!-- directive aop interceptor --> <directiveInterceptor class="org.meteortl.standard.directive.LocalContextDirectiveInterceptor" /> <!-- binary operator --> <binaryOperator name="." priority="10"> <handler>org.meteortl.standard.expression.operator.ObjectPropertyHanlder</handler> <handler>org.meteortl.standard.expression.operator.StringPropertyHanlder</handler> <handler>org.meteortl.standard.expression.operator.NumberDotHandler</handler> <handler>org.meteortl.standard.expression.operator.ObjectFunctionHandler</handler> <handler>org.meteortl.standard.expression.operator.ListDotHandler</handler> <handler>org.meteortl.standard.expression.operator.MapDotHandler</handler> <handler>org.meteortl.standard.expression.operator.ListSubHanlder</handler> </binaryOperator> <binaryOperator name="[" priority="10"> <handler>org.meteortl.standard.expression.operator.ObjectPropertyHanlder</handler> <handler>org.meteortl.standard.expression.operator.StringPropertyHanlder</handler> <handler>org.meteortl.standard.expression.operator.NumberDotHandler</handler> <handler>org.meteortl.standard.expression.operator.ObjectFunctionHandler</handler> <handler>org.meteortl.standard.expression.operator.ListDotHandler</handler> <handler>org.meteortl.standard.expression.operator.MapDotHandler</handler> <handler>org.meteortl.standard.expression.operator.ListSubHanlder</handler> </binaryOperator> <binaryOperator name="==" priority="1"> <handler>org.meteortl.standard.expression.operator.ObjectEqualHandler</handler> </binaryOperator> <binaryOperator name="!=" priority="1"> <handler>org.meteortl.standard.expression.operator.ObjectNotEqualHandler</handler> </binaryOperator> <binaryOperator name=">" priority="1"> <handler>org.meteortl.standard.expression.operator.ComparableGreaterThanHandler</handler> </binaryOperator> <binaryOperator name=">=" priority="1"> <handler>org.meteortl.standard.expression.operator.ComparableGreaterEqualHandler</handler> </binaryOperator> <binaryOperator name="<" priority="1"> <handler>org.meteortl.standard.expression.operator.ComparableLessThanHandler</handler> </binaryOperator> <binaryOperator name="<=" priority="1"> <handler>org.meteortl.standard.expression.operator.ComparableLessEqualHandler</handler> </binaryOperator> <binaryOperator name="+" priority="2"> <handler>org.meteortl.standard.expression.operator.NumberAddHandler</handler> <handler>org.meteortl.standard.expression.operator.DateAddHandler</handler> <handler>org.meteortl.standard.expression.operator.CollectionAddHandler</handler> <handler>org.meteortl.standard.expression.operator.MapAddHandler</handler> <handler>org.meteortl.standard.expression.operator.StringConcatenateHandler</handler> </binaryOperator> <binaryOperator name="-" priority="2"> <handler>org.meteortl.standard.expression.operator.NumberSubtractHandler</handler> <handler>org.meteortl.standard.expression.operator.DateSubtractHandler</handler> </binaryOperator> <binaryOperator name="*" priority="3"> <handler>org.meteortl.standard.expression.operator.NumberMultiplyHandler</handler> </binaryOperator> <binaryOperator name="/" priority="3"> <handler>org.meteortl.standard.expression.operator.NumberDivideHandler</handler> </binaryOperator> <binaryOperator name="%" priority="3"> <handler>org.meteortl.standard.expression.operator.NumberModulusHandler</handler> </binaryOperator> <binaryOperator name="||" priority="2"> <handler>org.meteortl.standard.expression.operator.BooealnOrHandler</handler> </binaryOperator> <binaryOperator name="&&" priority="3"> <handler>org.meteortl.standard.expression.operator.BooealnAndHandler</handler> </binaryOperator> <binaryOperator name="?" priority="1"> <handler>org.meteortl.standard.expression.operator.BooleanSelectHandler</handler> </binaryOperator> <binaryOperator name=":" priority="3"> <handler>org.meteortl.standard.expression.operator.ObjectEntryHandler</handler> </binaryOperator> <binaryOperator name="," priority="2"> <handler>org.meteortl.standard.expression.operator.ObjectListHandler</handler> </binaryOperator> <binaryOperator name=".." priority="1"> <handler>org.meteortl.standard.expression.operator.NumberSequenceHandler</handler> <handler>org.meteortl.standard.expression.operator.StringSequenceHandler</handler> </binaryOperator> <binaryOperator name="|" priority="1"> <handler>org.meteortl.standard.expression.operator.NotNullSelectHandler</handler> </binaryOperator> <binaryOperator name="~" priority="1"> <handler>org.meteortl.standard.expression.operator.DateFormatHandler</handler> <handler>org.meteortl.standard.expression.operator.NumberFormatHandler</handler> </binaryOperator> <!-- unary operator --> <unaryOperator name="!"> <handler>org.meteortl.standard.expression.operator.BooleanNotHandler</handler> </unaryOperator> <unaryOperator name="+"> <handler>org.meteortl.standard.expression.operator.NumberPositiveHandler</handler> </unaryOperator> <unaryOperator name="-"> <handler>org.meteortl.standard.expression.operator.NumberNegativeHandler</handler> </unaryOperator> <!-- property extend --> <propertyGetter class="java.lang.Boolean"> <handler property="not">org.meteortl.standard.expression.getter.BooleanNotHandler</handler> </propertyGetter> <propertyGetter class="java.lang.String"> <handler property="cap">org.meteortl.standard.expression.getter.StringCapitalHandler</handler> <handler property="date">org.meteortl.standard.expression.getter.StringDateHandler</handler> <handler property="datetime">org.meteortl.standard.expression.getter.StringDateTimeHandler</handler> <handler property="integer">org.meteortl.standard.expression.getter.StringIntegerHandler</handler> <handler property="long">org.meteortl.standard.expression.getter.StringLongHandler</handler> <handler property="float">org.meteortl.standard.expression.getter.StringFloatHandler</handler> <handler property="double">org.meteortl.standard.expression.getter.StringDoubleHandler</handler> <handler property="html">org.meteortl.standard.expression.getter.StringHtmlHandler</handler> </propertyGetter> <propertyGetter class="java.util.Date"> <handler property="era">org.meteortl.standard.expression.getter.DateEraHandler</handler> <handler property="century">org.meteortl.standard.expression.getter.DateCenturyHandler</handler> <handler property="year">org.meteortl.standard.expression.getter.DateYearHandler</handler> <handler property="month">org.meteortl.standard.expression.getter.DateMonthHandler</handler> <handler property="week">org.meteortl.standard.expression.getter.DateWeekHandler</handler> <handler property="day">org.meteortl.standard.expression.getter.DateDayHandler</handler> <handler property="hour">org.meteortl.standard.expression.getter.DateHourHandler</handler> <handler property="minute">org.meteortl.standard.expression.getter.DateMinuteHandler</handler> <handler property="second">org.meteortl.standard.expression.getter.DateSecondHandler</handler> <handler property="millisecond">org.meteortl.standard.expression.getter.DateMillisecondHandler</handler> <handler property="computerTime">org.meteortl.standard.expression.getter.DateComputerTimeHandler</handler> <handler property="timezone">org.meteortl.standard.expression.getter.DateTimezoneHandler</handler> <handler property="lenient">org.meteortl.standard.expression.getter.DateLenientHandler</handler> </propertyGetter> <!-- sequence --> <sequence>a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z</sequence> <sequence>A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z</sequence> <sequence cycle="true" ignoreCase="true">Spring,Summer,Autumn,Winter</sequence> <sequence cycle="true" ignoreCase="true">January,February,March,April,May,June,July,August,September,October,November,December</sequence> <sequence cycle="true" ignoreCase="true">Sunday,Monday,Tuesday,Wednesday,Thursday,Friday,Saturday</sequence> </template> |
|
返回顶楼 | |