A、nVelocity是一个基于.NET的模板引擎(template engine)。它允许任何人仅仅简单的使用模板语言(template language)来引用由.NET代码定义的对象。页面设计人员可以只关注页面的显示效果,而由.NET程序开发人员关注业务逻辑编码。
B、模板引擎处理流程:编写模板->处理数据->渲染HTML。
C、Nvelocity下载地址:http://www.castleproject.org/download/
D、一个简单的示例:
新建一个Application,在项目中添加Nvelocity的引用,然后添加新建项,选择一般处理程序,命名为login.ashx,在ProcessRequest方法里写下面代码:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
public void ProcessRequest(HttpContext context) { context.Response.ContentType = "text/html"; //是否载入 string ispostback = context.Request["ispostback"]; if (string.IsNullOrEmpty(ispostback)) { //创建NVelocity实例对象 VelocityEngine vltEngine = new VelocityEngine(); vltEngine.SetProperty(RuntimeConstants.RESOURCE_LOADER, "file"); //模板存放目录 vltEngine.SetProperty(RuntimeConstants.FILE_RESOURCE_LOADER_PATH, HostingEnvironment.MapPath("/template")); vltEngine.Init(); //定义一个模板上下文 VelocityContext vltContext = new VelocityContext(); //传入模板所需要的参数 vltContext.Put("username", ""); vltContext.Put("password", ""); vltContext.Put("msg", "载入"); //获取我们刚才所定义的模板,上面已设置模板目录 Template vltTemplate = vltEngine.GetTemplate("login.htm"); //根据模板的上下文,将模板生成的内容写进刚才定义的字符串输出流中 StringWriter vltWriter = new StringWriter(); vltTemplate.Merge(vltContext, vltWriter); string html = vltWriter.GetStringBuilder().ToString(); context.Response.Write(html); } }
然后在项目里,添加一个文件夹并且命名为template,作为存放模板的目录,这与上面代码里设置的模板目录要对应一致,然后添加新建项,选择HTML页,命名为login.htm,代码:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
<html xmlns="http://www.w3.org/1999/xhtml" > <head> <title>登录</title> </head> <body> <form action="../login.ashx"> 用户名:<input type="text" name="username" value="$username" /><br /> 密 码:<input type="text" name="password" value="$password" /><br /> <input type="hidden" name="ispostback" value="true" /> <input type="submit" value="提交"/> <p>$msg</p> </form> </body> </html>
直接运行HTML肯定只能看到模板的效果而已,我们工作的原理是,在一般处理程序ashx中读取模板来生成HTML,并且输出给客户端浏览器,所以我们要访问的应该是一般处理程序ashx。
E、Nvelocity模板语法
后台代码基本就是那样了,对于Nvelocity的重点应该是如何去编写适合需求的模板,上面的例子Put的时候,都是以字符串为例的,那么,假如Put一个对象、集合呢?
1、基本用法
vltContext.Put("username", username);
在模板中可以通过$username来引用
<input type="text" name="username" value="$username" />
2、对象的属性
下面演示一些更加高级的用法,直接Put一个对象,然后在模版中引用其属性。Nvelocity还可以支持对象的属性是对象的调用方法,引用的时候就好比$p.Name。
先定义一个C#类,Person.cs
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
public class Person { public string name{ get; set; } public string age { get; set; } }
然后,在处理的.ashx文件中初始化模板与输入:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
Person p = new Person(); p.name = "Dragon"; p.age = "11111"; //传入模板所需要的参数 vltContext.Put("p", p);
在.htm文件中调用对象:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
用户名:<input type="text" name="username" value= "$p.name" /><br /> 年 龄:<input type="text" name="password" value= "$p.age" /><br />
3、对象的索引
在.ashx文件初始化模板与输入:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
Dictionary<string,string> dict = new Dictionary<string,string>(); dict["name"] = "Dragon"; dict["address"] = "guangxi"; //传入模板所需要的参数 vltContext.Put("dict", dict);
在.htm文件中调用对象:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
$dict.name<br /> $dict.address
4、ForEach遍历
用List方式
在.ashx文件初始化模板与输入:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
//List类型 List<Person> lstps = new List<Person>(); lstps.Add(new Person{ name = "Dragon",age = "30"}); lstps.Add(new Person{ name = "YYK", age = "28" });
格式:
#foreach($element in $list)
This is $element
#end
在.htm文件中调用对象:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
<ul> #foreach($p in $lstps) <li>$p.name,$p.age</li> #end </ul>
在前台的模版中,有关后台代码的编写,如果以#开头,比如#foreach ,因为没有大括号的约束,所以结束时以#end为标识,ForEach和If还可以嵌套使用,就像平时我们写后台代码的那样,只是语法稍稍有点不同而已。
5、IF判断
在.ashx文件初始化模板与输入:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
//数组 string[] strs = {"Dragon","guangxi","web"}; //传入模板所需要的参数 vltContext.Put("strs", strs);
在.htm文件中调用对象:
格式:
#if(condition)
#elseif(condition)
#else
#end
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
<ul> #foreach($str in $strs) #if ($str == "Dragon") <li>$str</li> #elseif($str == "guangxi") <li>$str</li> #end #end </ul>
6、Parse和Include
顾名思义,#include就是在模版中在将其他模版包括进来,就好比网站的头部,尾部,广告模版等等,这些内容都是相同的时候,就可以做成一个单独的模版供各处引用。
#parse的用法跟#include相类似,如果将上面的代码改成#parse之后,效果是一样的,#parse的特殊功能在于,它可以解析Nvelocity元素,比如,body.html 模版使用Nvelocity变量 $body ,如果使用#parse引用head.html和footer.html两个模版,则在head.html、footer.html模版中继续可以使用$body这个变量,而#include做不到,并且相关的Nvelocity元素(#foreach、#if)也不起效果,只能原样输出,所以#parse > #inclued。
7、使用#set
前台的Nvelocity代码中,根据需要,我们可以声明一个供前台使用的参数,这样就免得后台代码再次传递过来了,对于一些简单逻辑,我们可以这样实现
在.htm文件中调用对象:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#set($a=1+6) <p style="text-align:center">A的值是:$a</p>
使用匿名类来进行代码封装
对于Nvelocity我们的重点应该是放在编写适合需求的模板,后台的代码基本上是一次封装,多次调用即可了,只需要把要Put的对象做成一个可变参数,剩余的代码进行一个封装就行了,那么如何更好的调用,我建议使用匿名类,因为随着模板的编写,我们可能需要传递多种、多个数据,使用匿名类的好处就是,类属性自定义而不用像自定义一个类型那样,每次增加数据属性就得去修改一下类型,这样显得很优雅很随性简便。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
//匿名类 var models = new { head = new { title = "匿名类测试",head = "系统" }, foot = new { content = "技术支持:Dragon" } };