本章开始将会为大家讲解NVelocity的用法,并带领大家实现一个简单的代码生成器。
NVelocity是一个基于.NET的模板引擎(template engine)。它允许任何人仅仅简单的使用模板语言(template language)来引用由.NET代码定义的对象。从而使得界面设计人员与.NET程序开发人员基本分离。
阅读目录
NVelocity的常用功能简介
1、 在页面中定义变量,并进行简单的运算。
2、 在页面中获得对后台程序实体对象的引用。
3、 在页面中迭代实体对象集合。
4、 在页面中获得实体对象的属性,及其方法。
5、 对逻辑判断语句的支持。
基本语法
1、特殊字符介绍
A、“#”:表示开始做什么事情。
B、“$”:表示用于获得什么。(以$开头的表示“引用”意思是取得一些东东.可引用变量,属性,方法)
C、“##“:单行注释。
D、 “#*… …*#”:多行注释。
2、关键字
A、 Set:开始做什么事情,比如定义变量,给变量重新赋值等。(注意:如果右边的操作数是一个属性或命令的引用而返回null,那么赋值将不会成功,且在随后的VTL中也不能再取出使用,如果要用做if条件,一个解决办法是,先给变量赋一个值,然后再将一个属性或命令的引用赋给该变量)
B、 Foreach:迭代语句
C、 If:条件判断语句
D、 Elseif
E、 Else
F、 Even:双数执行
G、 Odd :单数执行
K、 Each:每次都执行
(备注:所有变量在未定义之前不能使用(因为我们习惯了有全局变量的习惯),一个合法的VTL标示符是以一个字母开头的。.NET后台定义的对象除外。模板语言区分大小写,所有的关键字必须为小写,默认情况下,NVelocity解析是不分大小写的,当然可以通过设置runtime.strict.math=true,采用严格解析模式。)
3.使用示例
1、 在页面中使用变量
定义变量:#set($a = “CNF”)
引用变量:欢迎光临:$a
定义变量:#set($a = 1)
运算:#set($a = $a + 1)
输出:$a ##得:2
运算:#set($a = $a*5)
输出:$a ##得:10
#set( $criteria = ["name", "address"] )
#foreach( $criterion in $criteria )
#set( $result = false ) //先设置默认值
#set( $result = $query.criteria($criterion) )
#if( $result )
Query was successful
#end
#end
(备注:从以上可以看出nVelocity的替换顺序与.NET程序代码的执行基本一致,如果放在Foreach语句块中可以实现累加。并用If语句获得行号,对特殊行号的内容特殊处理。所有变量在未定义之前不能使用,.NET后台对象除外,最好采用正规引用格式,${a},正规引用格式一般用于在模板中直接调整字符串内容;静态引用输出:NVelocity遇到一个不能处理的引用时,一般他会直接输出这个引用$email的写法,页面上会看到的是$email,我们可以在$后面加上一个!号,那么就会输出空白.$!{email}如果不能处理会输出空白。如果email己定义了 (比如它的值是 foo),而这里你却想输出 $email. 这样一个字符串,就需要使用转义字符”\”,如:\$email)
2、 在页面中使用条件判断语句
#if ($p.StrSex == "女")
#set($Sex = "女士")
#elseif ($p.StrSex == "男")
#set($Sex = "先生")
#elseif ($p.StrSex == "无")
#set($Sex = "人妖")
#else
#set($Sex = "怪物")
#end
(备注:可以嵌套在Foreach语句块中,用于对每个列表对象进行特殊显示处理。)
4、使用对象方法
定义变量:#set($str = “CNF”)
调用方法:$str.SubString(0,1)
输出:C
定义变量:#set($a = 123)
调用方法:$a.GetType()
输出:System.Int32
(备注:不管是.NET代码定义的对象,还是设计人员在页面中定义的变量,都可以使用对象的方法及属性,这一点非常强大。)
5、使用even与odd简化代码,each辅助
如上面所说用IF语句可以在列表中为每行创建不同的样式,但如果只需要区分单行与双行的话,可以使用even与odd简化代码。如下:
#foreach($p in $ps)
#even
<p>双行:$p.StrName</p>
#odd
<p>单行:$p.StrName</p>
#end
(备注:在使用这两个关键字时,出现了与创建宏一样的问题,即在初始化模板引引擎的时候,如果是用模板文件内容初始化的,会出现问题)
实例介绍
1.生成前台html
怎么通过NVelocity生成上图的表格呢,请看下面的例子,先看模版文件
<table id="appMenu" style="background-color: rgb(114, 136, 172); border: solid 1px #00377a; height: 23px; color: White; font-size: 12px; font-family: 宋体; width: 100%; cursor: default;" cellspacing="0" cellpadding="0"> <tr> <td style="padding-left: 5px" nowrap=""> <b>学生信息列表</b> </td> <td style="padding-right: 5px; text-align: right;" nowrap=""> <span><span onclick="alert(1)">新增</span> <span class="mnuBtn" onclick="alert(2)">删除</span> </span> </td> </tr> </table> <table border="1" style="width: 100%; border: solid 1px #dbdac9; border-collapse: collapse; table-layout: fixed; cursor: default; font-size: 12px; font-family: 宋体;" cellspacing="0" cellpadding="0"> <colgroup> <col width="40"> <col width="12%"> <col width="12%"> <col width="12%"> <col width="12%"> <col width="12%"> <col width="12%"> <col width="12%"> <col /> </colgroup> <tr height="22" style="background-color: rgb(233, 231, 215);"> <th align="center"> 序号 </th> <th> 学生姓名 </th> <th> 年级 </th> <th> 专业 </th> <th> 性别 </th> <th> 考试成绩 </th> <th> 级别 </th> <th> 申请时间 </th> <th> 申请状态 </th> </tr> #foreach( $s in $ListStudent ) <tr height="22"> <td> $s.Num </td> <td> $s.Name </td> <td> $s.Grade </td> <td> $s.Major </td> <td> $s.Sex </td> <td align="right"> #if($s.Status=="已审核") $s.Score #else <input style="border:solid 1px black;width:95%;" value="$s.Score" /> #end </td> <td align="right"> #if($s.Status=="已审核") $s.Level #else <input style="border:solid 1px black;width:95%;" value="$s.Level" /> #end </td> <td align="center"> $s.GetAppoveDate($s.Status) </td> <td align="center"> $s.Status </td> </tr> #end </table>
用到了foreach循环和调用类的方法,这里特别强调一下,其实NVelocity和直接写后台代码类似,通过.方法名就可以调用变量有的方法
后台代码文件
protected void Page_Load(object sender, EventArgs e) { if (!IsPostBack) { Hashtable ht = new Hashtable(); List<Student> list = new List<Student>(); for (int i = 1; i < 10; i++) { Student s = new Student(); s.Num = i; s.Name = "Test"+i.ToString(); s.Score = i.ToString(); s.Status = i % 2 == 0 ? "未审核" : "已审核"; s.Sex = i % 2 == 0 ? "男" : "女"; s.Level = i.ToString (); s.Major = "测试"; s.Grade = "大一"; list.Add(s); } ht["ListStudent"] = list; divTemplate.InnerHtml = FileGen.GetFileText(Server.MapPath(@"模版文件\列表模版.vm"), ht).ToString(); } }
为了更方面的使用NVelocity,封装了一个帮助类即上面的FileGen类
using System; using System.Collections.Generic; using System.Linq; using System.Text; using NVelocity.App; using Commons.Collections; using NVelocity.Runtime; using NVelocity; using NVelocity.Context; using System.IO; using System.Collections; namespace NVelocityDemo { /// <summary> /// SQL文件生成 /// </summary> public class FileGen { /// <summary> /// 通过模版文件路径读取文件内容 /// </summary> /// <param name="path">模版文件路径</param> /// <param name="ht">模版文件的参数</param> /// <returns>StringWriter对象</returns> public static StringWriter GetFileText(string path, Hashtable ht) { if (String.IsNullOrEmpty(path)) { throw new ArgumentNullException("模版文件路径为空!"); } try { string tmpPath = path.Substring(0,path.LastIndexOf(@"\")); string filePath = path.Substring(path.LastIndexOf(@"\")+1); //创建NVelocity引擎的实例对象 VelocityEngine velocity = new VelocityEngine(); ExtendedProperties props = new ExtendedProperties(); props.AddProperty(RuntimeConstants.RESOURCE_LOADER, "file"); props.AddProperty(RuntimeConstants.FILE_RESOURCE_LOADER_PATH, tmpPath); props.AddProperty(RuntimeConstants.FILE_RESOURCE_LOADER_CACHE, true); props.AddProperty(RuntimeConstants.INPUT_ENCODING, "utf-8"); props.AddProperty(RuntimeConstants.OUTPUT_ENCODING, "utf-8"); velocity.Init(props); //从文件中读取模板 Template temp = velocity.GetTemplate(filePath); IContext context = new VelocityContext(); foreach (string key in ht.Keys) { context.Put(key, ht[key]); } //合并模板 StringWriter writer = new StringWriter(); temp.Merge(context, writer); return writer; } catch (Exception ex) { throw ex; } } /// <summary> /// 通过模版文件路径读取文件内容 /// </summary> /// <param name="path">模版文件路径</param> /// <param name="ht">模版文件的参数</param> /// <param name="strOutputPath">生成文件的输出路径,如c:\1.txt</param> /// <returns>TextWriter对象</returns> public static void GetFile(string path, Hashtable ht,string strOutputPath) { if (String.IsNullOrEmpty(strOutputPath)) { throw new ArgumentNullException("模版文件输出路径为空!"); } try { StringWriter stringW=GetFileText(path, ht); StreamWriter sw = new StreamWriter(strOutputPath,false,Encoding.UTF8); sw.Write(stringW.ToString()); sw.Close(); } catch (Exception ex) { throw ex; } } } }
上面的例子差不多将NVelocity语法都使用到了,没使用过NVelocity的可以通过上述例子学习语法,下一章将利用本章的语法写出一个简单的代码生成器,敬请期待!
工具源代码下载
目前总共有经过了七个版本的升级,现在提供最新版本的下载地址
数据字典生成工具V2.0安装程序 | 最新安装程序 | |
数据字典生成工具源代码 | 最新源代码 | |
http://code.taobao.org/svn/DataDicPub | SVN最新源码共享地址 |
学习使用
如果你使用了该工具,或者想学习该工具,欢迎加入这个小组,一起讨论数据字典生成工具、把该工具做的更强,更方便使用,一起加入147425783 QQ群。
更多数据字典生成工具资料请点击数据字典生成工具专题。