普通Replace模板做法

很多人在做邮件模板、短信模板的时候,都是使用特殊标识的字符串进行占位,然后在后台代码中进行Replace字符串,如果遇到表格形式的内容,则需要在后台进行遍历数据集合,进行字符串的拼接,继而Replace模板中的占位符,示例代码就像是这样:

<html>
<head>
<title>[title]</title>
</head>
<body>
<h1>[title]</h1>
<table>
<tr><td>姓名</td><td>专业</td></tr>
[TableContent]
</table>
</body>
</html>
  string templateStr = "xxxxx"; //这里读取模板,从数据库或者从文件中
StringBuilder sb=new StringBuilder();
sb.Append("<tr><td>小明</td><td>计算机专业</td></tr>");
sb.Append("<tr><td>小红</td><td>美术专业</td></tr>");
templateStr = templateStr.Replace("[title]", "给你一个标题").Replace("[TableContent]", sb.ToString());
return templateStr;

Nvelocity介绍

Nvelocity就像很多的模板引擎一样,以特定的语法编写好模板,然后为模板提供数据源,最终就会渲染生成出HTML,优点是模板与代码分离,很多的Nvelocity博文都是以html文件作为模板来进行的,但是我发现,也可以使用字符串模板来使用,这样你的模板就不必要存在html文件中了,存储在数据库中也可以,这应该更适合于大多数的项目。

Nvelocity下载地址:http://www.castleproject.org/download/ 找到NVELOCITY这一项进行下载即可。

一个简单示例揭开Nvelocity的面纱

新建一个Application,在项目中添加Nvelocity的引用,然后添加新建项,选择一般处理程序,命名为basic.ashx,在ProcessRequest方法里填入下面代码

  public void ProcessRequest(HttpContext context)
{
context.Response.ContentType = "text/html";
//创建一个模板引擎
VelocityEngine vltEngine = new VelocityEngine();
//文件型模板,还可以是 assembly ,则使用资源文件
vltEngine.SetProperty(RuntimeConstants.RESOURCE_LOADER, "file");
//模板存放目录
vltEngine.SetProperty(RuntimeConstants.FILE_RESOURCE_LOADER_PATH, System.Web.Hosting.HostingEnvironment.MapPath("/template"));//模板文件所在的文件夹
vltEngine.Init();
//定义一个模板上下文
VelocityContext vltContext = new VelocityContext();
//传入模板所需要的参数
vltContext.Put("Title", "标题"); //设置参数,在模板中可以通过$Title来引用
vltContext.Put("Body", "内容"); //设置参数,在模板中可以通过$Body来引用
vltContext.Put("Date", DateTime.Now); //设置参数,在模板中可以通过$Date来引用
//获取我们刚才所定义的模板,上面已设置模板目录
Template vltTemplate = vltEngine.GetTemplate("basic.html");
System.IO.StringWriter vltWriter = new System.IO.StringWriter();
//根据模板的上下文,将模板生成的内容写进刚才定义的字符串输出流中
vltTemplate.Merge(vltContext, vltWriter);
string html = vltWriter.GetStringBuilder().ToString();
context.Response.Write(html);
}

然后在项目里,添加一个文件夹并且命名为template,作为存放模板的目录,这与上面代码里设置的模板目录要对应一致,然后添加新建项,选择HTML页,命名为basic.html,输入以下代码

<html>
<head>
<title></title>
</head>
<body>
<p>$Title</p>
<p>$Date</p>
<p>$Body</p>
</body>
</html>

F5运行,看看效果

直接运行HTML肯定只能看到模板的效果而已,我们工作的原理是,在一般处理程序ashx中读取模板来生成HTML,并且输出给客户端浏览器,所以我们要访问的应该是一般处理程序ashx。

成功了,并且值都是代码中我们设置的值。

以字符串为模板源,不必新建HTML页

很多时候,我们的模板都是存放在数据库中的,而不是像上例那样以html文件的形式存放,Nvelocity也为我们提供这种形式的模板源,直接上代码就行了。

public void ProcessRequest(HttpContext context)
{
context.Response.ContentType = "text/html"; //字符串模板源,这里就是你的邮件模板等等的字符串
string templateStr = "$Title,$Body,$Date"; //创建一个模板引擎
VelocityEngine vltEngine = new VelocityEngine();
//文件型模板,还可以是 assembly ,则使用资源文件
vltEngine.SetProperty(RuntimeConstants.RESOURCE_LOADER, "file");
vltEngine.Init();
//定义一个模板上下文
VelocityContext vltContext = new VelocityContext();
//传入模板所需要的参数
vltContext.Put("Title", "标题"); //设置参数,在模板中可以通过$Title来引用
vltContext.Put("Body", "内容"); //设置参数,在模板中可以通过$Body来引用
vltContext.Put("Date", DateTime.Now); //设置参数,在模板中可以通过$Date来引用
//定义一个字符串输出流
StringWriter vltWriter = new StringWriter();
//输出字符串流中的数据
vltEngine.Evaluate(vltContext, vltWriter, null, templateStr);
context.Response.Write(vltWriter.GetStringBuilder().ToString());
}

Nvelocity模板语法

关于后台代码基本就是那样了,对于Nvelocity的重点应该是如何去编写适合需求的模板,上面的例子Put的时候,都是以字符串为例的,那么,假如Put一个对象、集合呢?Nvelocity都可以轻松解决,为了演示,下面的例子只贴出重点部分的代码。

1、基本用法

vltContext.Put("Title", "标题"); //设置参数,在模板中可以通过$Title来引用
vltContext.Put("Body", "内容"); //设置参数,在模板中可以通过$Body来引用
vltContext.Put("Date", DateTime.Now); //设置参数,在模板中可以通过$Date来引用

<html>
<body>
<p>$Title</p>
<p>$Date</p>
<p>$Body</p>
</body>
</html>

2、NVelocity中输出对象的属性

如果只能像上面那样子的基本用法的话,那简直太渣了,还不如直接IO读取模版直接Replace,下面演示一些更加高级的用法,直接Put一个对象,然后在模版中引用其属性,那样子就更加碉堡了,Nvelocity还可以支持对象的属性是对象的调用方法,引用的时候就好比$p.Son.Name

//定义一个模板上下文
VelocityContext vltContext = new VelocityContext();
Person p = new Person()
{
Name = "dotnetgeek",
Age =
};
//传入模板所需要的参数
vltContext.Put("p", p); //设置参数为对象,在模板中可以通过$p.Name 来引用
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<title></title>
</head>
<body>
姓名:$p.Name,年龄:$p.Age
</body>
</html>

3、NVelocity对象的索引

 //定义一个模板上下文
VelocityContext vltContext = new VelocityContext();
Dictionary<string, string> dic = new Dictionary<string, string>();
dic["dudu"] = "博客园";
dic["Jimmy"] = "softcomz";
//传入模板所需要的参数
vltContext.Put("dic", dic); //设置参数为对象,在模板中可以通过$dic.dudu 来引用
<html>
<body>
$dic.dudu
$dic.Jimmy
</body>
</html>

4、NVelocity中的ForEach遍历和If判断

 VelocityContext vltContext = new VelocityContext();
List<string> lstSite = new List<string>(){"博客园","微博"};
//传入模板所需要的参数
vltContext.Put("lst", lstSite);
<html>
<body>
<ul>
#foreach($s in $lst)
<li>$s</li>
#end
</ul> #if(1==1)
一等于一
#else
一不等于一
#end
</body>
</html>

在前台的模版中,有关后台代码的编写,如果以#开头,比如#foreach 、#if(condition),因为没有大括号的约束,所以结束时以#end为标识,ForEach和If还可以嵌套使用,就像平时我们写后台代码的那样,只是语法稍稍有点不同而已,有了这样的高级特性,这对于编写模版来说就能做很多的事情了。

5、NVelocity中Parse和Include

#parse("head.html")

<p>$body</p>

#include("footer.html")

顾名思义,#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

6、前台声明变量使用#set

在前台的Nvelocity代码中,根据需要,我们可以声明一个供前台使用的参数,这样就免得后台代码再次传递过来了,对于一些简单逻辑,我们可以这样实现

#if(1<10)

#set($nextnum=+++)
//下面的逻辑就可以使用nextnum这个变量了。
#end

建议使用匿名类来进行代码封装

上面提过,对于Nvelocity我们的重点应该是放在编写适合需求的模板,后台的代码基本上是一次封装,多次调用即可了,只需要把要Put的对象做成一个可变参数,剩余的代码进行一个封装就行了,那么如何更好的调用,我建议使用匿名类,因为随着模板的编写,我们可能需要传递多种、多个数据,使用匿名类的好处就是,类属性自定义而不用像自定义一个类型那样,每次增加数据属性就得去修改一下类型,这样显得很优雅很随性简便。

  var model = new { ID = "dudu", PersonLaoPo = new Person() { Name = "冰冰", Age =  } };
vltContext.Put("Model", model);

Demo下载

如果下次做模板,我就使用Nvelocity的更多相关文章

  1. 强大的模板引擎开源软件NVelocity

    背景知识NVelocity(http://sourceforge.net/projects/nvelocity )是从java编写的Velocity移植的.net版本,是java界超强的模版系统,.n ...

  2. asp.net对word文档进行修改 对于使用word文档做模板编辑比较适用

    最近做项目,需要多word文档进行编辑并导出一个新的word,在最初的word编辑中留下特定的字符串用来替换,然后在本地生成一个新的word文档,并且不修改服务器中的word文档,这样才能保证服务器中 ...

  3. SRM 449 DIV 1 总结(550p标记下,下次做)

    今天的250p搞得有点久了,500p是个类似铺瓷砖的dp题,这样先占个坑,给个poj的这类题列表,下次刷完了回来做! POJ 相关DP列表 http://blog.csdn.net/jayye1994 ...

  4. hdu2586&&poj1330 求点间最短距&&最近公共祖先(在线&&离线处理):::可做模板

    How far away ? Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)To ...

  5. 利用模板生成html页面(NVelocity)

    公司的网站需要有些新闻,每次的新闻格式都是一样的,而不想每次都查询操作,所以想把这些新闻的页面保存成静态的html,之后搜索了下就找到了这个模板引擎,当然其他的模板引擎可以的,例如:Razor,自己写 ...

  6. Codeforces Round #578 (Div. 2) 二维差分 可做模板

    题意: 在n*n的矩阵中,你可以选择一个k*k的子矩阵,然后将这个子矩阵中的所有B全部变为W,问你怎么选择这个子矩阵使得最终的矩阵中某一行全是W或者某一列全是W的个数最多 题解:考虑每一行和每一列,对 ...

  7. ACM/ICPC 之 Dinic+枚举最小割点集(可做模板)(POJ1815)

    最小割的好题,可用作模板. //Dinic+枚举字典序最小的最小割点集 //Time:1032Ms Memory:1492K #include<iostream> #include< ...

  8. ACM/ICPC 之 有流量上下界的网络流-Dinic(可做模板)(POJ2396)

    //有流量上下界的网络流 //Time:47Ms Memory:1788K #include<iostream> #include<cstring> #include<c ...

  9. ACM/ICPC 之 卡卡的矩阵旅行-最小费用最大流(可做模板)(POJ3422)

    将每个点拆分成原点A与伪点B,A->B有两条单向路(邻接表实现时需要建立一条反向的空边,并保证环路费用和为0),一条残留容量为1,费用为本身的负值(便于计算最短路),另一条残留容量+∞,费用为0 ...

随机推荐

  1. Hibernate之jpa实体映射的三种继承关系

    在JPA中,实体继承关系的映射策略共有三种:单表继承策略(table per class).Joined策略(table per subclass)和Table_PER_Class策略. 1.单表继承 ...

  2. PHP的轻量消息队列php-resque使用说明

    日志未经声明,均为AlloVince原创.版权采用『 知识共享署名-非商业性使用 2.5 许可协议』进行许可. 消息队列处理后台任务带来的问题 项目中经常会有后台运行任务的需求,比如发送邮件时,因为要 ...

  3. supervisor 配置

    1. 生成配置文件$ echo_supervisord_conf > /etc/supervisord.conf 2.修改配置文件vi /etc/supervisord.conf找到[inclu ...

  4. 《Linux内核设计与实现》读书笔记 第十七章 设备与模块

    一.设备类型 1. Unix系统 - 块设备 - 字符设备 - 网络设备 2. 块设备 通常缩写为blkdev,它是可寻址的,寻址以块为单位,块大小随设备不同而不同:块设备通常支持重定位操作,也就是对 ...

  5. 循序渐进Python3(五) -- 初识模块

    什么是模块? 模块,用一组代码实现了某个功能的代码集合. 类似于函数式编程和面向过程编程,函数式编程则完成一个功能,其他代码用来调用即可,提供了代码的重用性和代码间的耦合.而对于一个复杂的功能来,可能 ...

  6. Python-类的继承

    类的继承 面向对象的编程带来的主要好处之一是代码的重用,实现这种重用的方法之一是通过继承机制.继承完全可以理解成类之间的类型和子类型关系. 需要注意的地方:继承语法 class 派生类名(基类名):/ ...

  7. Python学习笔记-Day5

    冒泡算法: 实现1: a = [,,,,,,,,,,,,,,] def bubble(badlist): sort = False while not sort: sort = True ): ]: ...

  8. fail2ban 原理 安装 使用

    cd fail2ban python setup.py install /etc/fail2ban/ 为配置文件目录; /usr/lib/pythonx.x/site-packages/fail2ba ...

  9. Two Sum & Add Two Numbers

    Two Sum 题目:https://leetcode.com/problems/two-sum/ class Solution(object): def twoSum(self, nums, tar ...

  10. 深入理解C语言的函数调用过程

    本文主要从进程栈空间的层面复习一下C语言中函数调用的具体过程,以加深对一些基础知识的理解.     先看一个最简单的程序: 点击(此处)折叠或打开 /*test.c*/ #include stdio. ...