FreeMarker使用总结

FreeMarker使用总结
1.FreeMarker概述
  1)FreeMarker是一个模板引擎: 一个基于模板生成文本输出的通用工具,使用纯Java编写。
         模板+数据模型=输出
  2)FreeMarker被设计用来生成HTML Web页面,适合于作为Web应用程序的一个组件,特别适合于MVC应用程序的视图组件。
======================================================================================================================
2.数据模型 - Data Model
  1)典型的数据模型是树性结构,具有任意复杂和深度的层次
     (root)
       |
       +- test = "It is a test"
       |
       +- whatnot
       |     |
       |     +- because = "don't know"
       |
       +- animals
            |   
            +- (1st)
            |    |
            |    +- name = "elephant"
            |    |
            |    +- price = 5000
            |        
            +- (2st)
                 |
                 +- name = "cat"
                 |
                 +- price = 100  
  2)数据模型中变量的种类
     i) Scalars - 存储单一的值,类型可以为字符串/数值/日期时间/布尔型。
         Example. test、because、name、price都是Scalar
     ii) Hashes - 用于存储其余的变量(subvariables,子变量),类似于目录,包含保存下级变量的唯一查询名字。
         Example. (root)、whatnot都是Hashes,访问because的语法:${whatnot.because}
     iii) Sequences - 子变量顺序存放,子变量通过序号(从0开始)访问。
         Example. animals就是Sequences,访问子变量name的语法: ${animals[0].name}
======================================================================================================================
3. 模板 - Templates
        最简单的模板文件可以是一个简单的HTML文件(或者任意的文本文件),模板文件通常包含以下部分:
   1)Comments - 注释,包含在<#--和-->之间
   2)${...} - Inerpolations(插值),FreeMarker会在输出时使用实际值进行替代。
      Example1. test.ftl
        
        
          ${test}
        
        
         

The most popular animal


         


             <#-- the first animal elephant is more popular-->  
             ${animals[0].name} - price:${animals[0].price}
         

          
        
          
      插值的类型:通用Interpolation - ${expr}
                                    数字Interpolation - #{expr}或#{expr;format}
   3) FTL tags - FreeMarker Template Language tags,FTL标记,也称为指令
      i) FTL标记的语法:
                                  开始标记: <#directive_name parameters>
                                  结束标记:
                                 空标记:      <#directive_name parameters/>
      ii) 指令的类型:预定义指令和用户定义指令(使用@替换#)
======================================================================================================================
4.Value值、Types类型、Expression表达式、操作符
  1)值的类型有:  
    Scalars:
        String
        Number
        Boolean
        Date
    Containers:
        Hash
        Sequence
        Collection
    Subroutines:
        Methods and functions
        User-defined directives
    Miscellaneous/seldom used:
        Node
  2)Expression:  
   (1) 字符串:使用单引号或双引号限定,包含特殊字符需转义。
                         有一类特殊的字符串称为raw字符串,被认为是纯文本,该类字符串在引号前面加r。Example. ${r"${foo}"}
             连接操作 - Example:${"Hello " + user + "!"}
             取子串-     Example:<#assign var1="dangdang2">
                             ${var1[0..3]}
    (2)数字:不需要引号,不支持科学计数法,不能省略小数点前面的0。
                                算术运算符有:+、-、×、/、%
                                使用内建的int获得整数部分
            Example:${1.1?int}    - 返回1
                    ${1.999?int}  - 返回1
                    ${-1.1?int}   - 返回-1
                    ${-1.999?int} - 返回-1
    (3)布尔值:true 和false
    (4)序列:由逗号分隔的子变量列表,由方括号限定。
             Example. ["spring","summer","autumn","winter"]
                 [2+2,[1,2,3,4],"whatnot"] - 列表项目是表达式
                 2..5 - 等同于[2,3,4,5],可以使用数字范围定义数字序列,注意数字范围没有方括号
                 5..2 - 可以定义反递增的数字范围
                                序列的连接操作:
                 <#list ["Joe", "Fred"] + ["Julia", "Kate"] as user>
                    - ${user}
                   
    (5)散列:由逗号分隔的键/值列表,由大括号限定,键和值之间用冒号分隔。
            Example. {"name":"dog","price":120}
                              散列的连接操作:和 字符串一样,使用+,如果具有相同的key,右边的值替代左边的值
           Example:<#assign ages = {"Joe":23, "Fred":25} + {"Joe":30, "Julia":18}>
                    - Joe is ${ages.Joe}
                    - Fred is ${ages.Fred}
                    - Julia is ${ages.Julia}
  -------------------------------------------------------------------------------
  3)获取变量
    (1)顶层变量:${variable}
    (2) 从散列中获取数据:${whatnot.because}或者${whatnot["because"]}
    (3) 从序列获取数据:${animals[0].name}
    (4) 获取序列片段:使用[startIndex..endIndex]语法
    (5) 特殊变量:FreeMarker内定义的变量,使用.variable_name语法访问。
======================================================================================================================
5.Interpolation(插值)的使用
      通用Interpolation
    1)插入字符串值:直接输出表达式结果
    2)插入数字值:根据缺省值(由#setting指令设置)将表达式结果转换为文本输出。
      Example:
         <#setting number_format="currency"/>
         <#assign answer=42>
          ${answer}  - 输出$42.00          
          ${answer?string}  - 输出$42.00
          ${answer?string.number}  - 输出42
          ${answer?string.currency}  - 输出$42.00
          ${answer?string.percent}  - 输出4,200%
    3)插入日期值:
      Example:${lastUpdated?string("yyyy-MM-dd HH:mm:ss")
    4)插入布尔值:
      Example:<#assign foo=true>
               ${foo?string("yes","no")}
   -------------------------------------------------------------------------
   数字Interpolation - #{expr;format}
    format的格式:mX 小数部分最小X位,MX 小数部分最大X位
    Example:<#assign x=2.582/>
            <#assign y=4/>
            #{x; M2} <#-- 2.58 -->
            #{y; M2} <#-- 4 -->
            #{x; m1} <#-- 2.6 -->
            #{y; m1} <#-- 4.0 -->
            #{x; m1M2} <#-- 2.58 -->
            #{y; m1M2} <#-- 4.0 -->
======================================================================================================================
6. 常用指令
  1)if,else,elseif
       语法:<#if condition>
          ...
        <#elseif condition2>
          ...
        <#elseif condition3>
          ...
        ...
        <#else>
          ...    
        
   2)switch, case, default, break
       语法:<#switch value>
          <#case refValue1>
            ...
            <#break>
          <#case refValue2>
            ...
            <#break>
          ...
          <#case refValueN>
            ...
            <#break>
          <#default>
            ...
           
   3)list
       语法: <#list sequence as item>
          ...
              
   List指令中的隐含变量:
     item_index:当前迭代项的位置,从0开始。
     item_has_next:用于判断当前迭代项是否有下一项。   
     -------------------------------------------------------------------------------------             
        Example1:
            <#-- 在循环中使用隐含变量 -->
            <#assign seq = ["winter", "spring", "summer", "autumn"]>
            <#list seq as x>
             ${x_index + 1}. ${x}<#if x_has_next>,
           
        Example2:
            <#-- 固定次数的循环-->
            <#assign x=3>
            <#list 1..x as i>
              ${i}
            
        Example3:
             <#-- 散列的循环 -->
            <#assign items={"k1":"one","k2":"two"}>
            
    --------------------------------------------------------------------------------------
   4)include:用于包含其他的模板文件
       语法:<#include path> or <#include path options>
           path: The path of the file to include; an expression that evaluates to a string. (With other words, it doesn't have to be a fixed string, it can also be something like, for example, profile.baseDir + "/menu.ftl".)
           options: One or more of these: encoding=encoding, parse=parse
                  encoding: Expression evaluates to string
                  parse: Expression evaluates to boolean (also accepts a few string values for backward compatibility)
         example1:
                <#-- struts2中主题xhtml下的select.ftl文件 -->
                <#include "/${parameters.templateDir}/${parameters.theme}/controlheader.ftl" />
                <#include "/${parameters.templateDir}/simple/select.ftl" />
                <#include "/${parameters.templateDir}/xhtml/controlfooter.ftl" />
  5) assign:用于定义变量或者替换存在的变量
     语法:<#assign name=value>
        or
        <#assign name1=value1 name2=value2 ... nameN=valueN>
        or
        <#assign same as above... in namespacehash>
        or
        <#assign name>
          capture this
        
        or
        <#assign name in namespacehash>
          capture this
        
        name: name of the variable. It is not expression. However, it can be written as a string literal, which is useful if the variable name contains reserved characters, for example <#assign "foo-bar" = 1>. Note that this string literal does not expand interpolations (as "${foo}").
        value: the value to store. Expression.
        namespacehash: a hash that was created for a namespace (by import). Expression.
   6)import: 导入一个库到模板中,FreeMarker为导入库创建新的命名空间
       语法:<#import path as hash>
        path: The path of a template. This is an expression that evaluates to a string.
        (With other words, it doesn't have to be a fixed string, it can also be something like, for example, profile.baseDir + "/menu.ftl".)
        hash: The unquoted name of hash variable by which you can access the namespace. Not an expression.
   Example1:
        <#--使用命名空间-->
        <#import "/template/simple/test.ftl" as my>
        <#assign var1="dangdang2" in my>
        ${my.var1}
========================================================================
7.内置函数 - 参阅FreeMarker Manual
8.杂项
  1)宏 - 宏是和某个变量关联的模板片段,以便在模板中通过用户定义指令使用该变量。
  Example1:<#macro greet>
               Hello world!
           
            <#--使用宏-->
            <@greet>
   -----------------------------------------------------------------------------------------
   (1)  嵌套内容 - 用户定义指令可以有嵌套内容,使用<#nested>指令执行指令开始和结束标记之间的模板片段
    Example2:<#macro border>
             
                
             
<#nested>

          
          
           <@border>The bordered text
    -------------------------------------------------------------------------
   (2)在宏定义中使用循环变量:
                 用户定义指令可以有循环变量,通常用于重复嵌套内容,基本用法是:作为nested指令的
                  参数传递循环变量的实际值,而在调用用户定义指令时,在<@…>开始标记的参数后面指定
                 循环变量的名字
       Example3:
         <#macro repeat count>
            <#list 1..count as x>
            <#nested x, x/2, x==count>
            
        
         <@repeat count=4 ; c, halfc, last>
             ${c}. ${halfc}<#if last> Last!
        
         输出结果:
            1. 0.5
            2. 1
            3. 1.5
            4. 2 Last!
    -------------------------------------------------------------------------
  2)在模板中定义变量
    (1)plain变量:使用assign指令创建和替换,可以在模板任何地方访问,包括使用include指令插入的模板。
    (2)局部变量:使用local指定创建和替换,只在宏定义体中有效。
    (3)循环变量:只能存在于指令的嵌套内容中,由指令(如list)自动创建。
  3)名字空间
          通常情况下,只使用一个名字空间,称为主名字空间。
         为了创建可重用的宏或其他变量的集合(通常称为库),必须使用多名字空间,以防止命名冲突。
        使用名字空间的步骤:
     Step1.创建库
       Example:《#-- 保存在模板文件inc.ftl-->
                <#macro copyright date>
                 

Copyright (C) ${date} Bill Smith. All rights reserved.
                 
Email: ${mail}


                
                <#assign mail = "[email protected]">  
     Step2.使用import指令将库导入到模板中
          <#import "/lib/inc.ftl" as my>
          <#assign mail="[email protected]> <#--定义同名变量,并没有冲突-->
          <@my.copyright date="2010-2011"/>
          ${my.mail}
          ${mail}
======================================================================================================================
9.FreeMarker综合案例 - 分页标签模板文件
<#-- 分页标签模板文件pager.ftl-->

    

     

       确定
      
      
       共${parameters.pageCount}页 转到
     

    

    

        <#-- 下一页 -->
        <#if parameters.pageno==parameters.pageCount>
          下一页        
        <#else>
          下一页
           
        <#-- 页码 -->     
        <#list parameters.pageCount..1 as x>
           <#assign url=parameters.url+'?pageno='+x/>
           <#if parameters.pageno==x>
              ${x}
           <#else>
             ${x}
          
              
        <#-- 上一页 -->
        <#if parameters.pageno==1>
          上一页
        <#else>
          上一页
         
    

 

======================================================================================================================
(END)
 
            
     

        

   
 
   
                         
                         
                         
                         
                         
                         
                         
                         
                         
                                              
    
               
    

 
        
        
        
        
        
        
         
         
         
         
         
         
         
         
         
        

你可能感兴趣的:(J2EE)