模板引擎
l 自己做字符串替换的方法实现模板的缺点:不利于美工修改;很
难实现复杂的要求(if、for)
l 模板引擎有很多:
Nvelocity(http://www.castleproject.org/download/)、
StringTemplate、RazorEngine等。用法大同小异:编写模板→
提供数据→渲染成HTML
l NVelocity基本用法代码见备注。
• 给模板设置的属性如果有属性,则还可以进一步的获取:
$data.Person.Name。
• 如果对象有一个字符串索引器,则还可以“$data.索引器值”的方
式通过索引器获取值。使用一个Dictionary测试(如果报错,说明用
错了版本了)
• (*)Nvelocity中解析jquery代码$.ajax()中的$.的时候把$理解成了
Nvelocity的$特殊符号,应对方法是用jQuery代替$
NVelocity深入
l 1、#foreach ($element in $list)
This is $element.
#end
l 测试:把一个Person数组的输出到界面上
l 2、条件语句
l #if (condition)
l #elseif (condition)
l #else
l #end
l 测试:如果年龄大于20则显示为红色
l 3、可以使用#include包含另一个文件# include("foot.htm"),文件内容会包含进来
,不会解析其中的NVelocity元素。#parse也可以包含另一个文件,但是会解析
其中的NVelocity元素,被包含的文件继承父模板中的参数。可以实现“网站头体
一致、左侧菜单”等效果。
C#和NVelocity更好的结合
l 如果模板上需要数据很多(比如填写个人信息),那么就需要传递很多
参数,这样很麻烦,可以把这些参数封装到一个类中,这样
$data.Name,$data.Age就可以了。不过每次写不同的页面都要写一个
这样的类太麻烦,C#3.0中提供了“匿名类”语法,var person =
new{Name="yzk",Age=25}; 相当于声明一个有Name、Age两个属性的
类,new这个类的一个实例,并且用变量person指向它,因为是匿名类
,没有确切的类型,所以把person变量声明为“自动推断”的变量var
。后面就可以这样用了int i= person.Age。属性是只读的。
l 把DataTable传递给NVelocity的时候要传递DataTable .Rows
l (*)为了减少每次解析模板的时间,建议启用NVelocity缓存
using System; using System.Collections.Generic; using System.Linq; using System.Web; using NVelocity.App; using NVelocity.Runtime; using NVelocity; using System.Collections; using System.Data; namespace ASPNetHttpHandler2 { /// <summary> /// Login3 的摘要说明 /// </summary> public class Login3 : IHttpHandler { public void ProcessRequest(HttpContext context) { context.Response.ContentType = "text/html"; Dictionary<string, string> dict = new Dictionary<string, string>(); dict["tom"] = "斯坦福"; dict["jim"] = "加里敦"; dict["yzk"] = "哈佛"; VelocityEngine vltEngine = new VelocityEngine(); vltEngine.SetProperty(RuntimeConstants.RESOURCE_LOADER, "file"); vltEngine.SetProperty(RuntimeConstants.FILE_RESOURCE_LOADER_PATH, System.Web.Hosting.HostingEnvironment.MapPath("~/templates"));//模板文件所在的文件夹 vltEngine.Init(); string[] strs = new string[] { "杨中科", "刘德华","阿信" }; List<Person> persons = new List<Person>(); persons.Add(new Person { Age = 30, Name = "杨中科" }); persons.Add(new Person { Age = 10, Name = "王二小" }); persons.Add(new Person { Age = 50, Name = "周扒皮" }); Person p = new Person(); p.Age = 30; p.Name = "yzk"; VelocityContext vltContext = new VelocityContext(); vltContext.Put("ps", dict);//设置参数,在模板中可以通过$data来引用 vltContext.Put("mingrens", strs); vltContext.Put("persons", persons); vltContext.Put("person",p); vltContext.Put("age", 3); Template vltTemplate = vltEngine.GetTemplate("test3.htm"); System.IO.StringWriter vltWriter = new System.IO.StringWriter(); vltTemplate.Merge(vltContext, vltWriter); string html = vltWriter.GetStringBuilder().ToString(); context.Response.Write(html); } public bool IsReusable { get { return false; } } } }
using System; using System.Collections.Generic; using System.Linq; using System.Web; namespace ASPNetHttpHandler2 { public class Person { public string Name { get; set; } public int Age { get; set; } public Person Father { get; set; } } }
using System; using System.Collections.Generic; using System.Linq; using System.Web; using NVelocity.App; using NVelocity.Runtime; using NVelocity; namespace ASPNetHttpHandler2 { /// <summary> /// DisplayNews 的摘要说明 /// </summary> public class DisplayNews : IHttpHandler { public void ProcessRequest(HttpContext context) { context.Response.ContentType = "text/html"; VelocityEngine vltEngine = new VelocityEngine(); vltEngine.SetProperty(RuntimeConstants.RESOURCE_LOADER, "file"); vltEngine.SetProperty(RuntimeConstants.FILE_RESOURCE_LOADER_PATH, System.Web.Hosting.HostingEnvironment.MapPath("~/templates"));//模板文件所在的文件夹 vltEngine.Init(); //把类的定义和对象的声明初始化放到一起 //匿名类 var news = new { Title = "特大喜讯",Author="杨中科",PostDate="2013-11-08",Msg="今天晚上会公布喜讯细节!" }; string s = news.PostDate; VelocityContext vltContext = new VelocityContext(); vltContext.Put("data", news); Template vltTemplate = vltEngine.GetTemplate("displayNews1.htm"); System.IO.StringWriter vltWriter = new System.IO.StringWriter(); vltTemplate.Merge(vltContext, vltWriter); string html = vltWriter.GetStringBuilder().ToString(); context.Response.Write(html); } public bool IsReusable { get { return false; } } } }
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <title>$data.Title</title> </head> <body> <h1>$data.Title</h1> <p>作者:$data.Author;发布日期:$data.Postdate</p> <p>$data.Msg</p> </body> </html>
#if($age<10) hahaha #end <p>本网站版权所有!盗版弄死你!$age</p> </body> </html>
<a href="http://www.sina.con">点击就不送屠龙宝刀</a>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <title></title> </head> <body> <p><h1>欢迎光临如鹏网$age</h1></p> #if($age>30) hahaha #end
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html><head></head><body><strong><font color=‘green‘>登录</font></strong><form action=‘Login.ashx‘><input type=‘text‘ name=‘username‘ value=‘$username‘/><input type=‘password‘ name=‘password‘ value=‘$password‘ /><input type=‘submit‘ value=‘登录‘/></form><p>$msg</p></body></html>
#include("head.htm") $ps.tom 1: <ul> #foreach($mr in $mingrens) <li>$mr</li> #end </ul> 2: <ul> #foreach($p in $persons) <li>$p.Name的年龄是$p.Age</li> #end </ul> 3: <ul> #foreach($p in $persons) #if($p.Age>20) <li style="color:Red">$p.Name的年龄是$p.Age</li> #else <li style="color:Green">$p.Name的年龄是$p.Age</li> #end #end </ul> <p> #if($age>10) 大于10 #else 小于等于10 #end </p> #parse("GG.htm") #parse("foot.htm")
#include("head.htm") 我就是这么点东西 #include("GG.htm") <ul> #foreach($p in $persons) <li><input type="text" value="$p.Name" /></li> #end </ul> #include("foot.htm")