Web开发过程中使用模板为了更好的将Web设计人员和业务开发人员的聚焦点分开,然后各自聚焦一点,Web设计者做漂亮的网站,业务开发者写一等的代码。而在项目实践中,这点要求的无法兑现,让人格外沮丧,实际并没能真正将设计者和开发者的焦点分开,实际也是不能分开的,设计者和开发者必须相互了解对方的工作,才能对项目有更好的把握,更好的合作。

  

   Java Web开发的开源模板引擎很多,很多开源项目在做了集成比如:Velocity, Freemarker等。

 

   个人感觉MVC中的V一直困扰着Web开发,视图的展现和设计一直是设计者和开发者之间的伤痛,改了又换,换了又改的视图,数据的前端校验,后端校验,格式格式,数据组成等等。


   经历着Web项目的开发,不由得思考着如何能够很好的Web设计者的合作?

   1.懂Web设计

   2.懂前端开发技术

   3.懂网站建设

   。。。

   吾生有涯,而知无涯,做到掌握流程,规则,领悟其中思想做到Web设计者无障碍的专业沟通,估计这个时候就不用穷困与各种视图引擎,各种视图展示技术。


 上面,纯属感慨,不是本文重点,下面主要记录一下使用velocity模板引擎。


 1.阅读velocity的User Guide, 了解模板语言的基本语法;

 2.通过搜索引擎,找一些示例学习;

 3.下面要谈到的注意事项;

 

   模板引擎通常做的事情原理很简单:数据+模板=视图结果

  

  1. 创建模板引擎

  2. 创建数据

  3. 创建模板

  4. 合并数据和模板输入结果


     创建模板引擎主要有两种方式:一种是Velocity单例对象,一种是VelocityEngine实例对象。


一:

下面是一个简单的代码片段,然后说明整个流程:


   模板引擎+数据+渲染:


 

@Test
	public void test1() throws IOException {
		Velocity.init(properties);
		VelocityContext context = new VelocityContext();
		Template template = Velocity.getTemplate("/com/vm/test_velocity.vm",
				"utf-8");
		context.put("title", "测试Singleton Model Velocity Object");
		context.put("test", "test1");
		context.put("list", new String[] { "I 老虎 U!", "Jack", "Tom" });
		FileWriter fileWriter = new FileWriter(new File(directory
				+ "\\test1.html"));
		template.merge(context, fileWriter);
		fileWriter.flush();
		fileWriter.close();
	}

 

     模板内容:


<!DOCTYPE html><html>	
<head>		
    <meta charset="utf-8">
    <title>${title}</title>
</head>	
<body>		
    <h3>${test}<h3>
    #foreach($name in $list)
    	#if($foreach.index % 2 ==0 )
    	    <font color='red'>$name</font>
    	#else
    	    $name
    	#end
    #end
 </body>
 </html>



  最后将输出:test1.html文件。

 注意:

    1. 配置velocity.properties文件,定义模板加载路径,这里采用类路径。如何去编写可以看考两个地方:User Guide和org.apche.velocity.runtime.defaults.velocity.properties 文件.

  2.获取模板时模板名是相对于模板加载目录的文件路径

    3.API是个好帮手,虽然英文的,ASF的工程文档还是比较容易阅读

 

二:

   动态构建模板,并且进行数据模板合并。


@Test	public void test5() {		
    VelocityEngine ve = new VelocityEngine(properties);		
    ve.init();		
    VelocityContext context = new VelocityContext();		
    String tpl = "#set($name='Java with Velocity')"
        + "${name.toUpperCase()}";
    StringWriter out = new StringWriter();
    ve.evaluate(context, out, "test-tpl", tpl);
    System.out.println(out);
 }

 

  如上:tpl是一个字符串,但是字符串是由Velocity语法指令构成。

   注意:

       1.模板引擎使用VelocityEngine实例

       2.使用evaluate方法动态进行数据和模板的合并(也称:渲染)

       3.velocity.properties属性参数配置可以有模板引擎对象动态设置

三:

  创建宏并使之共用。

  创建了如下tablerows宏(关于如何创建以及语法规则参见文档:http://velocity.apache.org/engine/releases/velocity-1.7/user-guide.html  )

#macro( tablerows $color $somelist ) 	
    #foreach( $something in $somelist )
    <tr><td bgcolor=$color>$something</td></tr>
    #end
#end

  然后在模板中使用宏

  

#set( $greatlakes = ["Superior","Michigan","Huron","Erie","Ontario"] ) 
#set( $color = "blue" ) 

<table>
 	#tablerows( $color $greatlakes ) 
</table>

  然后进行渲染:

  

@Test	public void test9() {		
    
    VelocityEngine ve = new VelocityEngine(properties);		
    ve.init();		
    VelocityContext context = new VelocityContext();		
    context.put("name", "Velocity");		
    Template template = ve.getTemplate("com/vm/define.vm", "utf-8");		
    StringWriter writer = new StringWriter();		
    ArrayList<String> list = new ArrayList<String>();		
    list.add("com/vm/VM_global_library.vm");		
    template.merge(context, writer, list);		
    System.out.println(writer);	
    
 }

  

  问题来了:

  1.这个宏的定义放置到哪了模板文件呢?

       答案是:

       放置到使用宏的模板(将不能共享),

       放置到全局的模板库中(VM_global_library.vm)文件,首先要确保VM_global_library.vm文件在模板加载目录下。当然这一切不是死的,灵活的配置更符合Velocity的灵活,自由。可以参看velocity.properties中的配置:


# velocimacro.library = VM_global_library.vm

   

   2.merge方法的第三个参数macroLibraries 模板文件集合,在merge的时候,模板使用的宏定义库文件集合。从这一点就可以看出velocimacro.library是可以定义多个文件的,特别说明,用“逗号”分割宏定义库文件即可。


四:

  输入,输出编码格式,坚持一种编码,走哪转哪。


  通过快速学习Velocity之后,作文以记录之。掌握模板引擎可以在好多地方获得有力的帮助,格式化输出内容,文档转换,Struts视图,普通应用,Web应用等。


  Velocity网上的资料并不是特别多,大多都是对User Guide的简单翻译,确实Velocity简单,灵活,学习容易。

  详细学习可以查看User GuideDeveloper Guide.