快速的开发

 找回密码
 加入我们

QQ登录

只需一步,快速开始

搜索
热搜: 活动 交友 discuz
查看: 235|回复: 0

3:模板语言与解析引擎NVelocity

[复制链接]

92

主题

190

帖子

760

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
760

热心会员

发表于 2017-4-15 23:36:19 | 显示全部楼层 |阅读模式
模板语言的出现,主要是为了弥补主语言与外部系统之间交流的一些限制,他在主体之外,引入了一些扩展点,对于静态语言而言,引入模板主要是为了加入动态的特性,对于动态语言而言,它的目的主要是解决一致性,减少重复工作等。
模板语言的功能可强可弱,你可以将它用的非常简单,也可以将它用的非常复杂,但是,一定要注意的是,模板语言只能让它在系统中起一个辅助的作用,不能喧宾夺主,要严格限制它的功能范围。
模板语言关键的特点是要简单,功能不求完备但要专业够用可扩展。在我们的业务快速构建平台中,模板语言的用户是二次开发人员,所以系统设计的时候,就约定好了,模板语言主要解决简单的判断问题,简单的字符拼接与替换,大多数情况下,为生成一条sql语句服务。
注入数据+模板+引擎解析=结果字符串
NVelocity是一个基于.NET的模板引擎(template engine)。它本身是基于.net开发的,通过注入的C#对象,解析模板,可以得到想要的字符内容。
一、nVelocity的常用功能简介
    1、 在页面中定义变量,并进行简单的运算。
    2、 在页面中获得对后台程序注入的实体对象。
    3、 在页面中迭代实体对象集合。
    4、 在页面中获得实体对象的属性,及其方法。
    5、 对逻辑判断语句的支持。
    6、 对外部文件的引用。
    7、 对外部文件的解析。
    三、基本语法
     1、特殊字符介绍
         A、“#”:表示开始做什么事情。
         B、“$”:表示用于获得什么。(以$开头的表示“引用”意思是取得一些东东.可引用变量,属性,方法)
         C、“##“:单行注释。
         D、 “#*… …*#”:多行注释。
     2、关键字
          A、 Set:开始做什么事情,比如定义变量,给变量重新赋值等。(注意:如果右边的操作数是一个属性或命令的引用而返回null,那么赋值将不会成功,且在随后的VTL中也不能再取出使用,如果要用做if条件,一个解决办法是,先给变量赋一个值,然后再将一个属性或命令的引用赋给该变量)
          B、 Foreach:迭代语句
          C、 If:条件判断语句
          D、 Elseif
          E、 Else
          F、 Include:对外部文件的引用,开始位置为模板路径。
          G、 Parse:对外部文件的引用,并用nVelocity方式解析。
          H、 Macro:创建宏,可以重复做某件事,类似于方法。
          I、  Even:双数执行
          J、  Odd :单数执行
          K、each:每次都执行
    (备注:所有变量在未定义之前不能使用(因为我们习惯了有全局变量的习惯),一个合法的VTL标示符是以一个字母开头的。.NET后台定义的对象除外。模板语言区分大小写,所有的关键字必须为小写,默认情况下,NVelocity解析是不分大小写的,当然可以通过设置runtime.strict.math=true,采用严格解析模式。)
四、使用示例
    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语句块中,用于对每个列表对象进行特殊显示处理。)
    3、 创建宏,可以当做方法使用。
创建:#macro(Add $a $b)
         #set($c = $a + $b)
          <p>最后结果:$c</p>
      #end
调用:#Add(1 2)
   (备注:模板引擎的初始化方法有3种,一种参数为模板文件内容,一种是带模板文件地址。结果发现带模板文件内容的,在应用宏的时候好像有点问题。另外一个就是假如在宏里面加入一个判断语句,则可以实现递归调用。)
    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
    (备注:在使用这两个关键字时,出现了与创建宏一样的问题,即在初始化模板引引擎的时候,如果是用模板文件内容初始化的,会出现问题)
     6、引用外部文件
          Include与parse都有引入外部文件的作用,不同的是parse会根据nVelocity模板语言解析外部文件。也就是说如果引入当前模板,则会出现死循环。
          #include 脚本元素让模板设计者可以在模板中引入一个本地文件, 这个被引入的文件将不会经过NVelocity的解析. 安全起见,可以引放的文件只是是配置参数TEMPLATE_ROOT所定义目录下的,默认为当前目录下.
#include( "head.html" )
        如果需要引入多个文件,可以像下面这样.   
#include("one.gif","two.txt","three.htm" )
            当然,还可用一个变量名来代替文件名引入.   
#include( "greetings.txt", $seasonalstock )
      #parse 元素指示可以引入一个包含TVL的本地文件,这个文件将被NVeloictengine解析输出。
#parse( "me.vm" )
         与 #include 指令不同, #parse 可以从引入的模板中得到变量引用.但#parse指令只能接受一个参数.VTLtemplates 被#parse 的模板中还可以再包含#parse声明,默认的深度为10,这是由配置参数directive.parse.max.depth在文件velocity.properties中决定的,你可以修改它以适合项目要求。
     7、使用Foreach语句
          上面多次列出Foreach语句,相信已经知道它的作用。即循环列出一组对象集合。比如:#foreach($p in $ps),其中$ps需要与后台代码中具体的实体类名称对应,$p代表$ps中的其中一项。上面已经提到过,即$p可以调用实体类的属性和方法。
    (备注:#foreach 语句必须以#end结束,通过引用变量$velocityCount可以访问到NVelocity提供的计数器:)
    8、创建数组
          创建:#set($List = [“男”,”女”])
          遍历:#foreach($Item in $List)
                     <p>List成员:$Item</p>
                      #end
          输出:List成员:男
              List成员:女
    对变量的引用:$ [ ! ][ { ][ a..z, A..Z ][ a..z, A..Z, 0..9, -, _ ][ } ]。
       在NVelocity中,对变量的引用都是以$开头加上变量名称。当使用!时表示当此变量值为空时,显示空字符串。比如当$article为空,那会显示“$article“,而$!article会显示为“”。{}为变量名称限定,有时候变量名称后会有字符串,这是就需要用到{}了。比如$articleshow,想引用$article,这时只要修改为${article}就可以。其实,NVelocity对整个模板解析后都会变成这种模式。
     对属性的引用:$ [ { ][ a..z, A..Z ][ a..z, A..Z, 0..9, -, _ ]* .[a..z, A..Z ][a..z, A-Z, 0..9, -, _ ]* [ } ] 。
     例如$article.Title或者${article.Title}。
     对方法的引用:$ [ { ][ a..z, A..Z ][ a..z, A..Z, 0..9, -, _ ]* .[ a..z, A..Z ][a..z, A..Z, 0..9, -, _ ]*( [ optional parameter list...  ] ) [  } ]。
     例如:$article.GetListByTitle(‘nvelocity’)或${article.GetListByTitle(‘nvelocity’)}。其实对对象的属性值也可以用$article.get_Title()获得。
     赋值指令#set:# [ { ] set [ } ]  ( $ref = [", &apos; ]arg[ ", &apos; ] )。
     例如:$article.Title=’NVelocity’,$$article.Categories=[1,2,3],当然右侧也可以使用复杂的表达式:$article.Title=$otherArticle.Title.SubString(0,3),算术表达式:$article.Page=4/3等等。属性赋值也可以用$article.set_Title(‘NVelocity’)。
     条件指令#if:# [ { ] if [ } ] ( [condition] )[output] [ # [ { ] elseif [ } ] ( [condition] ) [output] ]* [ # [ { ] else [ }] [output] ] # [ { ] end [ } ] 。
     条件可以是返回bool的复查表达式。例如:#if($article.Total>1)$article.Title #else 没有数据 #end。
     循环指令#foreach:# [ { ] foreach [ } ]($refinarg)statement# [ { ] end [ } ]。
     例如:#foreach($article in $articles) $article.Title #end。
     引用静态资源指令#include:# [ { ] include [ } ] ( arg[ arg2... argn] )。
      例如:#include(‘tmp.js’),会把tmp.js文件内容插入当前流。当然可以使用表达式:#include($article.Url)。
     引用并解析资源指令#parse:# [ { ] parse [ } ] ( arg )。
     例如:#parse(‘tmp.js’),与#include不同是,假如tmp.js文件中有NVelocity的指令,变量会进行处理,并把结果插入到当前流。
     停止指令#stop:# [ { ] stop [ } ] 。
     当NVelocity解析到此指令时,会停止解析过程。一般用户调试。
     计算指令#evaluate:# [ { ] evaluate [ } ] ( arg )。
     例如:#evaluate(‘$article.Title’),会在当前输出$article.Title
能用鼠标,不用键盘
回复

使用道具 举报

QQ|Archiver|手机版|小黑屋|业务快速构建平台 ( 鄂ICP备15010001号

鄂公网安备 42011502000533号

GMT+8, 2019-8-20 12:01 , Processed in 0.089928 second(s), 36 queries .

Powered by Discuz! X3.3

© 2016-2036 Comsenz Inc.

快速回复 返回顶部 返回列表