zoukankan      html  css  js  c++  java
  • Monorail NVelocity语法整理

    NVelocity是Monorail的模板之一,语法简洁,应用灵活。

    以下搜集整理的一些语法和应用技巧:

     

    <HTML>

    <BODY>

    ##指定用户名字

    欢迎你: $customer.Name!

    <table>

    ###输出用户喜好的MuD

    #foreach( $mud in $mudsOnSpecial )

       #if ( $customer.hasPurchased($mud) )

          <tr>

            <td>

              $flogger.getPromo( $mud )

            </td>

          </tr>

       #end

    #end

    </table>

    set 指示符使用一个表达式(expression) (包含在一对括号里) –将一个值 value (这里是Velocity)付给变量a,(变量名在左边,值在右边,用=组合起来).

    以$开头的表示“引用”意思是取得一些东东.可引用变量,属性,方法

    属性可以引用到对象的命令. Velocity会使用合适的策略选择引用到的命令. 它会根据协定的命令命令格式查找. 无论属性引用的的名字是否大小写,Velocity都有固定的查找规则.如在$customer.address引用时,查找顺序是:

    1. getaddress()
    2. getAddress()
    3. get("address")
    4. isAddress()

    对于VTL中大写的属性名Address引用,将是:

    1. getAddress()
    2. getaddress()
    3. get("Address")
    4. isAddress()

    正规引用格式

    ${mudSlinger}

    1.Jack is a $vicemaniac.

    2.Jack is a ${vice}maniac.

    这样,Velocity就知你要的是 $vice, 而不是 $vicemaniac变量,正规引用格式一般用于在模板中直接调整字符串内容.

    Quiet Reference Notation(静态引用输出)

    Velocity遇到一个不能处理的引用时,一般他会直接输出这个引用$email的写法,页面上会看到的是$email,如下例,我们可以在$后面加上一个!号,那么就会输出空白:.

    <input type="text" name="email" value="$email"/>

    <input type="text" name="email" value="$!email"/>

    正式的写法是:.

    <input type="text" name="email" value="$!{email}"/>

    Getting literal( 语义问题)

    velocity使用$,#字符来标志它的声明,但有时,HTML中因为某种其它意图,也会写出这样的字符

    1.Currency(货币标志)

    如美元 $2.50!这样的写法出现到模板中, VTL处理时是不会出错,会正确的输出$2.50!这个你想要的结果。为什么呢?一个合法的VTL标示符是以一个字母开头的

    如下示,如果没有#set( $email = "foo" )这一行且java代码中Context对象中没有放放email对象,将直接输出$email.

    #set( $email = "foo" )

    $email

    如果email己定义了 (比如它的值是 foo),而这里你却想输出 $email. 这样一个字符串,就需要使用转义字符”\”.

    ## The following line defines $email in this template:

    #set( $email = "foo" )

    $email

    \$email

    \\$email

    \\\$email

    上面的模板在web页面上的输出将是:

    foo

    $email

    \foo

    \$email

    但如果email并没有定义,我们这样写:.

    $email

    \$email

    \\$email

    \\\$email

    输出就原封不动了:

    $email

    \$email

    \\$email

    \\\$email

    注意:当己定义变量和未定义变量一起输出时,会输出字面意思,如下便,$moon是未定义的:

    #set( $foo = "gibbous" )

    $moon = $foo

    输出到web页面中将是

    $moon = gibbou

    Case Substitution(可选的格式)

    $foo.getBar()

    ## 等同于

    $foo.Bar

    $data.setUser("jon")

    ##等同于

    #set( $data.User = "jon" )

    $data.getRequest().getServerName()

    ##等同于

    $data.Request.ServerName

    ## is the same as

    ${data.Request.ServerName}

    指令:(Directives)则以#开头来表示,有点“做些什么动作”的意思.

    #set( $monkey = $bill ) ## variable reference

    #set( $monkey.Friend = "monica" ) ## string literal

    #set( $monkey.Blame = $whitehouse.Leak ) ## property reference

    #set( $monkey.Plan = $spindoctor.weave($web) ) ## method reference

    #set( $monkey.Number = 123 ) ##number literal

    #set( $monkey.Say = ["Not", $my, "fault"] ) ## ArrayList

    #set( $monkey.Map = {"banana" : "good", "roast beef" : "bad"}) ## Map

    注意:如果右边的操作数是一个属性或命令的引用而返回null,那么赋值将不会成功,且在随后的VTL中也不能再取出使用

    #set( $criteria = ["name", "address"] )

    #foreach( $criterion in $criteria )

        #set( $result = $query.criteria($criterion) )

        #if( $result )

            Query was successful

        #end

    #end

    在上例中,就不能依赖if( $result )来决定查询是否成功. $result 一但被 #set 为null (context会同样), 它将不能被赋 其它值 (不能从 context中取出).

    一个解决办法是,每次都将$result 设为 false. 如果 $query.criteria() 调用成功,就可以检测到.

    #set( $criteria = ["name", "address"] )

    #foreach( $criterion in $criteria )

        #set( $result = false )

        #set( $result = $query.criteria($criterion) )

        #if( $result )

            Query was successful

        #end

    #end

    注意: #set 不需要使用 #end 来声明结尾.

    使用#set 指令时,变量如果用 “”引起会被解析,如:

    #set( $directoryRoot = "www" )

    #set( $templateName = "index.vm" )

    #set( $template = "$directoryRoot/$templateName" )

    $template

    输出的将是:

    www/index.vm

    但当用单引号引起来时,就不会被解析::

    #set( $foo = "bar" )

    $foo

    #set( $blargh = '$foo' )

    $blargh

    输出后会是:

    bar

    $foo

    默认情况下,不会解析单引号中的变量,当然,这可以通过改变Velocity的配置参数来改变:

    velocity.properties such that stringliterals.interpolate=false.

    通过引用变量$velocityCount可以访问到Velocity提供的计数器:

    <table>

    #foreach( $customer in $customerList )

        <tr><td>$velocityCount</td><td>$customer.Name</td></tr>

    #end

    </table>

    #include 脚本元素让模板设计者可以在模板中引入一个本地文件, 这个被引入的文件将不会经过Velocity的解析. 安全起见,可以引放的文件只是是配置参数TEMPLATE_ROOT所定义目录下的,默认为当前目录下.

    #include( "one.txt" )

    如果需要引入多个文件,可以像下面这样.

    #include( "one.gif","two.txt","three.htm" )

    当然,还可用一个变量名来代替文件名引入.

    #include( "greetings.txt", $seasonalstock )

    #parse 元素指示可以引入一个包含TVL的本地文件,这个文件将被Veloict engine解析输出。.

    #parse( "me.vm" )

    与 #include 指令不同, #parse 可以从引入的模板中得到变量引用.但#parse指令只能接受一个参数.

    VTL templates 被#parse 的模板中还可以再包含#parse声明,默认的深度为10,这是由配置参数directive.parse.max.depth在文件velocity.properties中决定的,你可以修改它以适合项目要求

    #stop 指令用来指示在模板的某处,engine停止解析,这一般用来调用。用法很简单.

    Velocimacros(宏调用)

    #macro 指令让模板设计者可以将些重复、相关的的脚本版断定义为一个功能块.无论在什么情况下. 出于单一意图设计的 Velocimacro都会最大程序的减少模板编写中可以的出错,还是看个例子来理解一下Velocimacros的概念.

    #macro( d )

    <tr><td></td></tr>

    #end

    这样就定义了一个名为d的宏,它可以在其它的模板中像下面那样直接引用:

    #d()

    Velocimacro可以接收0到任意多的传入参数.如上个例是0个参数,但当它被调用时,也必须传入同样多的参数. 这里定义了一个有两个参数的宏.

    #macro( tablerows $color $somelist )

    #foreach( $something in $somelist )

        <tr><td bgcolor=$color>$something</td></tr>

    #end

    #end

    然后,我们在页面中来使用:

    #set( $greatlakes = ["Superior","Michigan","Huron","Erie","Ontario"] )

    #set( $color = "blue" )

    <table>

        #tablerows( $color $greatlakes )

    </table>

    注意变量 $greatlakes 取代了宏中变量 $somelist的输出,最终的输出如下:

    <table>

        <tr><td bgcolor="blue">Superior</td></tr>

        <tr><td bgcolor="blue">Michigan</td></tr>

        <tr><td bgcolor="blue">Huron</td></tr>

        <tr><td bgcolor="blue">Erie</td></tr>

        <tr><td bgcolor="blue">Ontario</td></tr>

    </table>

    宏一般被定义在模板中,那么站点上的其它模板中又如何调用呢?如能定义一个可以更大范围内共想的宏就太好了

    如果将宏#tablerows($color $list) 定义到一个模板库中(Velocimacros template library), 其它模板就都可以访问它了.

    Velocimacro Arguments(宏的参数)

    Velocimacros可以从TVL中接受以下参数 :

    • 引用类型 : 所有以'$'开头的
    • String literal : something like "$foo" or 'hello'
    • Number literal : 1, 2 etc
    • IntegerRange : [ 1..2] or [$foo .. $bar]
    • ObjectArray : [ "a", "b", "c"]
    • boolean value true
    • boolean value false

    当传一个引用参数给宏时, 引用是通过名字传入的('pass by name').

         #macro( callme $a )

             $a $a $a

         #end

         #callme( $foo.bar() )

    上例中命令 bar() 被调用了3 times.

    最后要说的是,这个特性有些难以学习,但当你精心组织规划你的宏库时, 消除在VTL中重复功能的脚本时 –你可以像使用一个对象或组件一样使用宏, 比如一个宏对象生成多个表格的重复色彩.

    如果你想利用这个特性,你只需要像下面那样简单的编码传一个值给它来调用 :

         #set( $myval = $foo.bar() )

         #callme( $myval )

    Velocimacro Properties(宏的属性)

    配置文件 velocity.properties 中有多行相关配置,具体请见《Velocity Java开发指南中文版》.

    velocimacro.library –用来指定全局的宏库,多个可以,号分开.

    velocimacro.permissions.allow.inline – 默认为true,可以让宏定义在一个正规的模板文件中.

    velocimacro.permissions.allow.inline.to.replace.global – 用来指定模板内定义的宏的功能是否要以替换全局库,默认为false.

    velocimacro.permissions.allow.inline.local.scope –模板中定义的宏的使用范围是否只是本模板可用.

    velocimacro.context.localscope –如果为true,宏通过#set赋值时.宏中将保持一个,且不会由于context中的数据被修改而变化,同样,宏中的修改也不会改变context中的。

    velocimacro.library.autoreload – 是否自动重新载入,用于调试环境,默认false,如为true,需要取掉chcheing:. file.resource.loader.cache = false ).

    一些细节:

    宏必须在模板中使用#macro()指令前定义.

    尽量不要直接在模板中使用#parse() 包含 #macro() 指令.因为 #parse() 动作在运行时执行,时会有一个在VM中查找元素的过程.

    两种注释方式:

    ##

    #* ……*#

    Velocimacro Miscellany(关于宏的一些问题)

    这是一些简短的问题总结,也许你先要有这样一个概念:. 'Velocimacro' 就像一个‘VM’。

    可否用一个指示符做为另外一个指示符运算的参数?

    如 : #center( #bold("hello") )

    No. 指示符不是有效的参数但你可以这样实现你想要的:

    #set($stuff = "#bold('hello')" )

    #center( $stuff )

    或者:

    #center( "#bold( 'hello' )" )

    可否通过 #parse()来注册一个宏 ?

    宏必须在模板使用前定义好.前面己有一个关于此问题的建议,#parse()是运行时执进的,JVM查找对象的顺序不一定会全按我们预计的执行。

    String Concatenation(连结字符串)

    很简单,看例子就是 :

           #set( $size = "Big" )

           #set( $name = "Ben" )

          The clock is $size$name.

    上面的输出将是

    'The clock is BigBen'.

    或者:

          #set( $size = "Big" )

          #set( $name = "Ben" )

          #set($clock = "$size$name" )

          The clock is $clock.

    它们都是同样的输出,最后一个例子如下,:

          #set( $size = "Big" )

          #set( $name = "Ben" )

          #set($clock = "${size}Tall$name" )

          The clock is $clock.

    输出将是

    'The clock is BigTallBen'.

    Layout应用:

    首先Layout母板页

    $childContent

    然后在子页面里

    #capturefor(title) Home Page #end

    #capturefor(scripts)

    <!-- Here you can include some inline javascript that will be added to the <head> element -->

    function sayHello()

    {

    return alert("Hello");

    }

    #end

    #capturefor(head)

    <!-- Here you can include some content to appear on the layout, inside head. For example, stylesheets -->

    #end

     

    表格行奇偶样式变换

    #foreach($test in $tests) 
    #even 
    <tr class="Test1"> 
    #odd 
    <tr class="Test2"> 
    #each 
      <td>$test.Name</td> 
    <tr> 
    #end

  • 相关阅读:
    C# 編譯錯誤 CS0016 解決方案
    Javascript 日期
    Javascript Url处理
    Linq中in用法
    oracle中的排名函数用法
    webservices [WebServiceBinding(ConformsTo = WsiProfiles.None)]
    C#中的多态
    C# Math类简介 (转)
    客服工单任务系统发展简史 商商
    jQuery LigerUI 使用教程表格篇(2) 服务器数据交互
  • 原文地址:https://www.cnblogs.com/chinatefl/p/1549793.html
Copyright © 2011-2022 走看看