﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>BlogJava-俺们那嘎达-文章分类-FreeMarker</title><link>http://www.blogjava.net/livery/category/23345.html</link><description>找到属于自己的一片天空</description><language>zh-cn</language><lastBuildDate>Fri, 22 Jun 2007 15:42:36 GMT</lastBuildDate><pubDate>Fri, 22 Jun 2007 15:42:36 GMT</pubDate><ttl>60</ttl><item><title>webwork中的FreeMarker</title><link>http://www.blogjava.net/livery/articles/125562.html</link><dc:creator>心情经纬</dc:creator><author>心情经纬</author><pubDate>Thu, 21 Jun 2007 06:21:00 GMT</pubDate><guid>http://www.blogjava.net/livery/articles/125562.html</guid><wfw:comment>http://www.blogjava.net/livery/comments/125562.html</wfw:comment><comments>http://www.blogjava.net/livery/articles/125562.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/livery/comments/commentRss/125562.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/livery/services/trackbacks/125562.html</trackback:ping><description><![CDATA[<p>FreeMarker是一个Java模版语言，它是 <a title=JSP href="http://wiki.javascud.org/display/ww2cndoc/JSP"><u><font color=#0000ff>JSP</font></u></a> 的绝佳替代方案. FreeMarker在你的action result可能需要在Servlet容器环境以外被载入的情况下是理想选择. 例如,如果你希望在你的应用程序中支持plugins,你可能会乐意使用Freemarker，因为那样的话plugins可以支持将所有的action class和view都打包到一个从classloader进行装载的jar文件里面.<br>关于FreeMarker的更多信息，请访问<span class=nobr><a href="http://www.freemarker.org/" rel=nofollow><u><font color=#0000ff>FreeMarker网站<sup><img class=rendericon height=7 alt="" src="http://wiki.javascud.org/images/icons/linkext7.gif" width=7 align=absMiddle border=0></sup></font></u></a></span>.</p>
<table class=noteMacro cellSpacing=8 cellPadding=5 width="85%" align=center border=0>
    <colgroup>
    <col width=24>
    <col></colgroup>
    <tbody>
        <tr>
            <td vAlign=top><img height=16 alt="" src="http://wiki.javascud.org/images/icons/emoticons/warning.gif" width=16 align=absMiddle border=0></td>
            <td>
            <p>FreeMarker与<span class=nobr><a href="http://freemarker.sourceforge.net/" rel=nofollow><u><font color=#800080>Velocity<sup><img class=rendericon height=7 alt="" src="http://wiki.javascud.org/images/icons/linkext7.gif" width=7 align=absMiddle border=0></sup></font></u></a></span>非常相似, 它们都是可以在Servlet容器外使用的模版语言. WebWork小组更推荐FreeMarker, 而不是Velocity, 这是因为FreeMarker提供了更好的错误报告, 支持JSP标签, 稍多的功能. 当然, 这两种技术都是代替JSP的很好方案.</p>
            </td>
        </tr>
    </tbody>
</table>
<h1><a name=FreeMarker-%E5%BF%AB%E9%80%9F%E4%B8%8A%E6%89%8B></a>快速上手</h1>
<p>确认配置好你的项目的classpath中的所有依赖以后, 开始使用FreeMarker就非常简单了. 典型情况下只需要 <strong>freemarker.jar</strong>. 除它以外, <a title=webwork-default.xml href="http://wiki.javascud.org/display/ww2cndoc/webwork-default.xml"><u><font color=#0000ff>webwork-default.xml</font></u></a>已经配置好了将<a title="FreeMarker Result" href="http://wiki.javascud.org/display/ww2cndoc/FreeMarker+Result"><u><font color=#0000ff>FreeMarker Result</font></u></a>映射到你的模版文件. 你现在可以试验一下如下 <strong>xwork.xml</strong> 配置:</p>
<div class=code>
<div class=codeContent>
<pre class=code-java>&lt;action name=<span class=code-quote>"test"</span> class=<span class=code-quote>"com.acme.TestAction"</span>&gt;
&lt;result name=<span class=code-quote>"success"</span> type=<span class=code-quote>"freemarker"</span>&gt;test-success.ftl&lt;/result&gt;
&lt;/action</pre>
</div>
</div>
<p>然后写好 <strong>test-success.ftl</strong>:</p>
<div class=code>
<div class=codeContent>
<pre class=code-java>&lt;html&gt;
&lt;head&gt;
&lt;title&gt;Hello&lt;/title&gt;
&lt;/head&gt;
&lt;body&gt;
Hello, ${name}
&lt;/body&gt;
&lt;/html&gt;</pre>
</div>
</div>
<p>这里 <strong>name</strong> 是你的action中的一个属性. 这样就可以了! 该文档的余下部分将介绍模版如何被加载, 变量如何解析, tags(标签)也可以使用.</p>
<h1><a name=FreeMarker-%E6%A8%A1%E7%89%88%E5%8A%A0%E8%BD%BD></a>模版加载</h1>
<p>Webwork在两个位置查找FreeMarker模版(按顺序):</p>
<ol>
    <li>Web应用程序目录(Web application)
    <li>Class path<br>这个顺序对于在完全编译的jar中提供模版很理想, 但是也同时支持在Web应用程序目录中定义这些模版来覆盖jar中的模版文件. 事实上, 这就是为什么你可以覆盖WebWork中默认的UI tags和<a title="Form Tags" href="http://wiki.javascud.org/display/ww2cndoc/Form+Tags"><u><font color=#0000ff>Form Tags</font></u></a>的原理.<br>还有, 你可以通过templatePath 上下文变量(context variable)指定一个路径(你的文件系统中的一个目录). 如果指定了该变量, 那么这个目录中的内容将会被优先寻找. </li>
</ol>
<h1><a name=FreeMarker-%E5%8F%98%E9%87%8F%E8%A7%A3%E6%9E%90%2F%E5%86%B3%E5%AE%9A%28Resolution%29></a>变量解析/决定(Resolution)</h1>
<p>在FreeMarker中, 变量将会在多个位置进行寻找, 顺序如下:</p>
<ol>
    <li>值栈(value stack)
    <li>action上下文(action context)
    <li>Request范围(scope)
    <li>Session范围(scope)
    <li>Application范围(scope)
    <li>内建变量<br>注意action上下文在value stack后进行搜索. 这意味着你可以引用变量而不必使用标准的符号(#)前缀，不像在JSP中使用ww:property中必须使用的那种语法(译者注:现在在JSP中也可以不用#而访问默认的ValueStack). 这是一个很好的便利特性, 但是小心, 它有时也会把你陷进去.
    <div class=code>
    <div class=codeContent>
    <pre class=code-java>&lt;@ww.url id=<span class=code-quote>"url"</span> value=<span class=code-quote>"http:<span class=code-comment>//www.yahoo.com"</span>/&gt;
    </span>Click &lt;a xhref=<span class=code-quote>"${url}"</span>&gt;here&lt;/a&gt;!</pre>
    </div>
    </div>
    </li>
</ol>
<p>Webwork-FreeMarker整合提供的内建变量如下:</p>
<table class=confluenceTable>
    <tbody>
        <tr>
            <th class=confluenceTh>Name</th>
            <th class=confluenceTh>Description</th>
        </tr>
        <tr>
            <td class=confluenceTd>stack</td>
            <td class=confluenceTd>值栈本身, 方便使用 ${stack.findString('ognl expr')}的方式调用</td>
        </tr>
        <tr>
            <td class=confluenceTd>action</td>
            <td class=confluenceTd>最近执行的action</td>
        </tr>
        <tr>
            <td class=confluenceTd>response</td>
            <td class=confluenceTd>HttpServletResponse</td>
        </tr>
        <tr>
            <td class=confluenceTd>res</td>
            <td class=confluenceTd>与response相同</td>
        </tr>
        <tr>
            <td class=confluenceTd>request</td>
            <td class=confluenceTd>HttpServletRequest</td>
        </tr>
        <tr>
            <td class=confluenceTd>req</td>
            <td class=confluenceTd>与reqeust相同</td>
        </tr>
        <tr>
            <td class=confluenceTd>session</td>
            <td class=confluenceTd>HttpSession</td>
        </tr>
        <tr>
            <td class=confluenceTd>application</td>
            <td class=confluenceTd>ServletContext</td>
        </tr>
        <tr>
            <td class=confluenceTd>base</td>
            <td class=confluenceTd>request的上下文路径(context path)</td>
        </tr>
    </tbody>
</table>
<h1><a name=FreeMarker-%E6%A0%87%E7%AD%BE%E6%94%AF%E6%8C%81></a>标签支持</h1>
<p>FreeMarker是很棒的模版语言, 因为它完整的支持标签(tag). 参照WebWork提供的 <a title="FreeMarker Tags" href="http://wiki.javascud.org/display/ww2cndoc/FreeMarker+Tags"><u><font color=#0000ff>FreeMarker Tags</font></u></a> 文档中的如何使用通用(generic) <a title=Tags href="http://wiki.javascud.org/display/ww2cndoc/Tags"><u><font color=#0000ff>Tags</font></u></a> 部分获取更多信息. 除了那些, 你还可以使用任何的JSP标签(tag), 就像这样:</p>
<div class=code>
<div class=codeContent>
<pre class=code-java>&lt;#assign mytag=JspTaglibs[<span class=code-quote>"/WEB-INF/mytag.tld"</span>]&gt;
&lt;@mytag.tagx attribute1=<span class=code-quote>"some ${value}"</span>/&gt;</pre>
</div>
</div>
<p>这里 <strong>mytag.tld</strong> 是你使用的JSP标签库的定义文件. 注意: 为了使用FreeMarker的这个支持, 你必须开启 <a title="web.xml 2.1.x compatibility" href="http://wiki.javascud.org/display/ww2cndoc/web.xml+2.1.x+compatibility"><u><font color=#0000ff>web.xml 2.1.x compatibility</font></u></a> 文档中的 JSPSupportServlet.</p>
<h1><a name=FreeMarker-%E6%8F%90%E7%A4%BA%E5%92%8C%E6%8A%80%E5%B7%A7></a>提示和技巧</h1>
<p>下面是在使用FreeMarker构建WebWork应用程序时的一些有用的进阶功能.</p>
<h2><a name=FreeMarker-%E7%B1%BB%E5%9E%8B%E8%BD%AC%E6%8D%A2%E4%B8%8E%E6%9C%AC%E5%9C%B0%E5%8C%96></a>类型转换与本地化</h2>
<p>FreeMarker内置支持日期与数字的格式化. 格式化的规则基于action request的地区信息(locale), locale是通过<a title=webwork.properties href="http://wiki.javascud.org/display/ww2cndoc/webwork.properties"><u><font color=#0000ff>webwork.properties</font></u></a>配置的, 它也可以通过<a title="I18n Interceptor" href="http://wiki.javascud.org/display/ww2cndoc/I18n+Interceptor"><u><font color=#0000ff>I18n Interceptor</font></u></a>进行覆盖. 这种方式一般会完美的满足你的需求, 但是你要记住, 这些格式化信息是通过FreeMarker处理的,而不是通过WebWork的<a title="Type Conversion" href="http://wiki.javascud.org/display/ww2cndoc/Type+Conversion"><u><font color=#0000ff>类型转换</font></u></a>支持实现.<br>如果你希望WebWork根据你所指定的<a title="Type Conversion" href="http://wiki.javascud.org/display/ww2cndoc/Type+Conversion"><u><font color=#0000ff>类型转换</font></u></a>处理格式化, 你不应该使用平常的&amp;{...}语法. 取而代之, 你应该使用<a title=property href="http://wiki.javascud.org/display/ww2cndoc/property"><u><font color=#0000ff>property</font></u></a>标签. 区别在于property标签特别为OGNL表达式设计， 计算它的值， 然后将结果用你指定的<a title="Type Conversion" href="http://wiki.javascud.org/display/ww2cndoc/Type+Conversion"><u><font color=#0000ff>Type Conversion</font></u></a>转换为String. 平常使用的${...}语法则会使用FreeMarker的表达式语言(EL), 计算它的值, 然后通过内建的格式化规则转化为String. 这些区别甚微, 但是一定要了解.</p>
<h2><a name=FreeMarker-%E6%89%A9%E5%B1%95></a>扩展</h2>
<p>有时你可能需要扩展WebWork提供的FreeMarker支持. 最常见的原因是你希望引入你自己的<a title=Tags href="http://wiki.javascud.org/display/ww2cndoc/Tags"><u><font color=#0000ff>标签</font></u></a>, 就像你扩展WebWork内建<a title=Tags href="http://wiki.javascud.org/display/ww2cndoc/Tags"><u><font color=#0000ff>标签</font></u></a>一样.<br>如果需扩展, 首先要新建一个继承 <strong>com.opensymphony.webwork.views.freemarker.FreemarkerManager</strong> 并且重载了相应方法的类. 然后将下面代码添加到<a title=webwork.properties href="http://wiki.javascud.org/display/ww2cndoc/webwork.properties"><u><font color=#0000ff>webwork.properties</font></u></a>:</p>
<div class=code>
<div class=codeContent>
<pre class=code-java>webwork.freemarker.manager.classname = com.yourcompany.YourFreeMarkerManager</pre>
</div>
</div>
<h2><a name=FreeMarker-ObjectWrapper%E8%AE%BE%E7%BD%AE></a>ObjectWrapper设置</h2>
<p>如果你熟悉了FreeMarker, 你会发现它的敏感性会带来一些困扰. 最常见的方法就是尝试使用FreeMarker提供的BeanWrapper. 如果你不知道那是什么,别担心. 只要知道这些酒可以了:</p>
<div class=panel>
<div class=panelContent style="BACKGROUND-COLOR: #ffffce">
<p>WebWorkBeanWrapper继承自默认的FreeMarker BeansWrapper, 提供了基本完全一致的功能, 只是修改了maps处理机制. 一般, FreeMarker有两种操作模式: 一种支持友好的内置的map (?key, ?values, etc),但是只支持String作为key; 或者特殊的内置支持(例如: ?key 返回map的相应方法而不是key), 但是它支持String和String相似的非String作为key. WebWork提供了两种情况下的可选的实现方案.<br>这种特殊的做法也许会让你迷惑或产生问题. 所以, 你可以将 webwork.properties 中的*webwork.freemarker.wrapper.altMap*设置为false, 允许替换为常规的BeansWrapper逻辑.</p>
</div>
</div>
<h2><a name=FreeMarker-%E8%AF%AD%E6%B3%95%E6%B3%A8%E9%87%8A></a>语法注释</h2>
<p>如果是FreeMarker 2.3.4, 还支持另外的语法. 这种可选的语法在你感觉你使用的IDE(尤其是ItelliJ IDEA)在默认的语法下运行困难时非常有用. 关于这种语法的更多内容, 请阅读<span class=nobr><a href="http://freemarker.sourceforge.net/docs/dgui_misc_alternativesyntax.html" rel=nofollow><u><font color=#0000ff>这里</font></u><sup><img class=rendericon height=7 alt="" src="http://wiki.javascud.org/images/icons/linkext7.gif" width=7 align=absMiddle border=0></sup></a></span></p>
<img src ="http://www.blogjava.net/livery/aggbug/125562.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/livery/" target="_blank">心情经纬</a> 2007-06-21 14:21 <a href="http://www.blogjava.net/livery/articles/125562.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>FreeMarker学习1(Ftl)</title><link>http://www.blogjava.net/livery/articles/124263.html</link><dc:creator>心情经纬</dc:creator><author>心情经纬</author><pubDate>Thu, 14 Jun 2007 03:50:00 GMT</pubDate><guid>http://www.blogjava.net/livery/articles/124263.html</guid><wfw:comment>http://www.blogjava.net/livery/comments/124263.html</wfw:comment><comments>http://www.blogjava.net/livery/articles/124263.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/livery/comments/commentRss/124263.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/livery/services/trackbacks/124263.html</trackback:ping><description><![CDATA[<font face="Courier New"><font color=#0000ff>&lt;# ... &gt;</font> 中存放所有freemaker的内容，之外的内容全部原样输出。<br><font color=#0000ff>&lt;@ ... /&gt;</font> 是函数调用<br>两个定界符内的内容中，第一个符号表示指令或者函数名，其后的跟随参数。freemaker提供的控制包括如下：<br><font color=#0000ff>&lt;#if condition&gt;&lt;#elseif condition&gt;&lt;#else&gt;&lt;/#if&gt;</font> 条件判断<br><font color=#0000ff>&lt;#list hash_or_seq as var&gt;&lt;/#list&gt;</font> 遍历hash表或者collection（freemaker称作sequence）的成员<br><font color=#0000ff>&lt;#macro name param1 param2 ... &gt;&lt;#nested param&gt;&lt;/#macro&gt;</font> 宏，无返回参数<br><font color=#0000ff>&lt;#function name param1 param2&gt;&lt;#return val&gt;&lt;/#function&gt;</font>函数，有返回参数<br><font color=#0000ff>var?member_function(...)</font> 用函数对var进行转换，freemaker称为build-ins。实际内部实现类似member_function(var, ...)<br><font color=#0000ff>stringA[M .. N]</font> 取子字符串，类似substring(stringA, M, N)<br><font color=#0000ff>{key:value, key2:value2 ...}</font> 直接定义一个hash表<br><font color=#0000ff>[item0, item1, item2 ...]</font> 直接定义一个序列<br><font color=#0000ff>hash0[key0]</font> 存取hash表中key对应的元素<br><font color=#0000ff>seq0[5]</font> 存取序列指定下标的元素<br><font color=#0000ff>&lt;@function1 param0 param1 ... /&gt;</font> 调用函数function1<br><font color=#0000ff>&lt;@macro0 param0 param1 ; nest_param0 nest_param1 ...&gt; nest_body &lt;</font></font> <a><font face="Courier New" color=#0000ff>/@macro</font> </a><font face="Courier New"><font color=#0000ff>&gt;</font> 调用宏，并处理宏的嵌套<br><font color=#0000ff>&lt;#assign var = value &gt;</font> 定义变量并初始化<br><font color=#0000ff>&lt;#local var = value&gt;</font> 在 macro 或者 function 中定义局部变量并初始化<br><font color=#0000ff>&lt;#global var = value &gt;</font> 定义全局变量并初始化<br><font color=#0000ff>${var}</font> 输出并替换为表达式的值<br><font color=#0000ff>&lt;#visit xmlnode&gt;</font> 调用macro匹配xmlnode本身及其子节点<br><font color=#0000ff>&lt;#recurse xmlnode&gt;</font> 调用macro匹配xmlnode的子节点</font> <br><font face="Courier New"><font color=#a03d10>&lt;#if </font><em style="COLOR: #dd4400">condition</em> <font color=#a03d10>&gt;</font> <tt style="COLOR: #a03d10">&lt;/#if&gt;</tt></font> <br><font face="Courier New"><font color=#a03d10>&lt;#list </font><em style="COLOR: #dd4400">SequenceVar</em> <font color=#a03d10>as </font><em style="COLOR: #dd4400">variable</em> <font color=#a03d10>&gt;</font> <em style="COLOR: #dd4400">repeatThis</em> <font color=#a03d10>&lt;/#list&gt;<br></font><font color=#000000><strong>&lt;#include "/copyright_footer.html"&gt;<br><br>一个ftl标记不能放在另外一个ftl标记里面，但是注释标记能够放在ftl标记里面。<br><br>系统预定义指令采用&lt;#...&gt;&lt;/#&gt;<br>用户自定义指令采用&lt;@...&gt;&lt;/@&gt;<br><br>hash片段可以采用：</strong> <font color=#a03d10>products[10..19]</font> or <tt style="COLOR: #a03d10">products[5..]</tt> 的格式。<br><br><font color=#a03d10>序列也可以做加法计算：passwords + {"joe":"secret42"}</font><br><br>
<p>缺省值: <tt style="COLOR: #a03d10">name!"unknown"</tt>&nbsp;或者 <tt style="COLOR: #a03d10">(user.name)!"unknown"</tt>&nbsp;或者 <tt style="COLOR: #a03d10">name!</tt>&nbsp;或者 <tt style="COLOR: #a03d10">(user.name)!</tt></p>
<p>null值检查: <tt style="COLOR: #a03d10">name??</tt> or <tt style="COLOR: #a03d10">(user.name)??</tt><br><br>转义列表：<br></p>
<table cellPadding=4 border=1>
    <thead>
        <tr>
            <th align=left>
            <p>Escape sequence</p>
            </th>
            <th align=left>
            <p>Meaning</p>
            </th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td align=left>
            <p><tt style="COLOR: #a03d10">\"</tt></p>
            </td>
            <td align=left>
            <p>Quotation mark (u0022)</p>
            </td>
        </tr>
        <tr>
            <td align=left>
            <p><tt style="COLOR: #a03d10">\'</tt></p>
            </td>
            <td align=left>
            <p>Apostrophe (a.k.a. apostrophe-quote) (u0027)</p>
            </td>
        </tr>
        <tr>
            <td align=left>
            <p><tt style="COLOR: #a03d10">\\</tt></p>
            </td>
            <td align=left>
            <p>Back slash (u005C)</p>
            </td>
        </tr>
        <tr>
            <td align=left>
            <p><tt style="COLOR: #a03d10">\n</tt></p>
            </td>
            <td align=left>
            <p>Line feed (u000A)</p>
            </td>
        </tr>
        <tr>
            <td align=left>
            <p><tt style="COLOR: #a03d10">\r</tt></p>
            </td>
            <td align=left>
            <p>Carriage return (u000D)</p>
            </td>
        </tr>
        <tr>
            <td align=left>
            <p><tt style="COLOR: #a03d10">\t</tt></p>
            </td>
            <td align=left>
            <p>Horizontal tabulation (a.k.a. tab) (u0009)</p>
            </td>
        </tr>
        <tr>
            <td align=left>
            <p><tt style="COLOR: #a03d10">\b</tt></p>
            </td>
            <td align=left>
            <p>Backspace (u0008)</p>
            </td>
        </tr>
        <tr>
            <td align=left>
            <p><tt style="COLOR: #a03d10">\f</tt></p>
            </td>
            <td align=left>
            <p>Form feed (u000C)</p>
            </td>
        </tr>
        <tr>
            <td align=left>
            <p><tt style="COLOR: #a03d10">\l</tt></p>
            </td>
            <td align=left>
            <p>Less-than sign: <tt style="COLOR: #a03d10">&lt;</tt></p>
            </td>
        </tr>
        <tr>
            <td align=left>
            <p><tt style="COLOR: #a03d10">\g</tt></p>
            </td>
            <td align=left>
            <p>Greater-than sign: <tt style="COLOR: #a03d10">&gt;</tt></p>
            </td>
        </tr>
        <tr>
            <td align=left>
            <p><tt style="COLOR: #a03d10">\a</tt></p>
            </td>
            <td align=left>
            <p>Ampersand: <tt style="COLOR: #a03d10">&amp;</tt></p>
            </td>
        </tr>
        <tr>
            <td align=left>
            <p><tt style="COLOR: #a03d10">\{</tt></p>
            </td>
            <td align=left>
            <p>Curly bracket: <tt style="COLOR: #a03d10">{</tt></p>
            </td>
        </tr>
        <tr>
            <td align=left>
            <p><tt style="COLOR: #a03d10">\x<em style="COLOR: #dd4400">Code</em></tt></p>
            </td>
            <td align=left>
            <p>Character given with its hexadecimal <a href="file:///C:/Documents%20and%20Settings/Administrator/桌面/freemarker-2.3.9/docs/docs/gloss.html#gloss.unicode"><font color=#002c99><u>Unicode</u></font></a> code (<a href="file:///C:/Documents%20and%20Settings/Administrator/桌面/freemarker-2.3.9/docs/docs/gloss.html#gloss.UCS"><font color=#002c99><u>UCS</u></font></a> code)</p>
            </td>
        </tr>
    </tbody>
</table>
<br>如果想打印${，则需要将{转义，可以写成"$\{user}"，或者可以用生字符（r指令）：$(r "${xx}"}<br><br>序列构成：&lt;#list <strong>["winter", "spring", "summer", "autumn"]</strong> as x&gt;${x}&lt;/#list&gt;<br><br>不同的对象可以存放在一个序列里面，比如：<font color=#a03d10>[2 + 2, [1, 2, 3, 4], "whatnot"]</font>. 第一个是数字，第二个是序列，第三个是字符串。<br><br>可用采用start..end的方式来定义一个数字序列，start可以小于end，同时，end也可以省略。<br><br>hash取值支持一下四种模式：<font color=#a03d10>book.author.name</font>, <tt style="COLOR: #a03d10">book["author"].name</tt>, <tt style="COLOR: #a03d10">book.author.["name"]</tt>, <tt style="COLOR: #a03d10">book["author"]["name"]</tt>.<br>
<p>特殊变量是指freemaker引擎本身定义的变量。访问时，以.variable_name的语法访问。<br><br>变量表达式支持嵌套模式，比如：${"Hello ${user}!"}。<br><br>变量表达式在指令中的使用情况：<br>变量表达式可以在指令中，用&#8220;&#8221;的方式存在，不如：<font color=#a03d10>&lt;#include "/footer/${company}.html"&gt;</font>. <br>但是不允许下面的方式存在： <tt style="COLOR: #a03d10">&lt;#if ${isBig}&gt;Wow!&lt;/#if&gt;</tt>,&nbsp;正确写法是：<tt style="COLOR: #a03d10">&lt;#if isBig&gt;Wow!&lt;/#if&gt;</tt>. <br>而且 <tt style="COLOR: #a03d10">&lt;#if "${isBig}"&gt;Wow!&lt;/#if&gt;写法也不正确，因为"${isBig}"返回的是字符串，不是boolean类型。<br></tt><br>字符串中取字符或字符串采用以下语法：${user[0]},${user[0..2]} ${user[4..]},${user?string(4)}<br><br>序列操作：<br>&nbsp;&nbsp;&nbsp;加法：&lt;#list ["Joe", "Fred"] + ["Julia", "Kate"] as user&gt; 但要注意串联之后的读取速度变慢。<br>&nbsp;&nbsp;&nbsp;子序列：<font color=#a03d10>seq[1..4]<br><br>序列和hash的串联都只能用于两个相加，不能有多个相加的模式，hash相加，如果两个相加的hash存在相同的key，则后面会覆盖前面的。<br></font><br>在使用&gt;=或者&gt;时，需要注意一些问题，因为freemaker会将&gt;解释成标记的关闭符，为了解决这个问题，需要在表达式加上括号，比如： <tt style="COLOR: #a03d10">&lt;#if (x &gt; y)&gt;</tt>.&nbsp;或者使用 <tt style="COLOR: #a03d10">&amp;gt;</tt> and <tt style="COLOR: #a03d10">&amp;lt符号来代替。</tt><br><br>无值变量（包括无该变量，null，返回void，无属性等）：<em><font color=#dd4400>unsafe_expr</font></em><font color=#a03d10>!</font><em style="COLOR: #dd4400">default_expr</em> or <tt style="COLOR: #a03d10"><em style="COLOR: #dd4400">unsafe_expr</em>!</tt> or <tt style="COLOR: #a03d10">(<em style="COLOR: #dd4400">unsafe_expr</em>)!<em style="COLOR: #dd4400">default_expr</em></tt> or <tt style="COLOR: #a03d10">(<em style="COLOR: #dd4400">unsafe_expr</em>)!<br></tt>缺省值可以是任何类型，不一定是数字，比如：<font color=#a03d10>hits!0</font>&nbsp;或者 <tt style="COLOR: #a03d10">colors!["red", "green", "blue"]</tt>. <br><br>如果缺省值忽略，那么将会默认为空串、空序列或者空hash，因为freemarker支持多类型的值。不过要让默认值为0或false，则不能省略缺省值。<br><br>非顶层变量的无值处理：<br>&nbsp;&nbsp;&nbsp;product.color!"red"：只处理product不为空，color为空的缺省值处理，如果product为空，则freemaker会抛出异常。(product.color)!"red"：则会处理product为空，color为空，或者没有color属性的无值情况。<br><br>无值变量的判断操作：<em><font color=#dd4400>unsafe_expr</font></em><font color=#a03d10>??</font> or <tt style="COLOR: #a03d10">(<em style="COLOR: #dd4400">unsafe_expr</em>)??<br></tt></p>
判断变量是否是无值。<br><br>普通变量插入方式: <tt style="COLOR: #a03d10">${<em style="COLOR: #dd4400">expression</em>},${3+5);<br></tt>数字变量插入方式: <tt style="COLOR: #a03d10">#{<em style="COLOR: #dd4400">expression</em>}</tt> or <tt style="COLOR: #a03d10">#{<em style="COLOR: #dd4400">expression</em>; <em style="COLOR: #dd4400">format</em>}：过期。<br>变量只能用于文本区或者是字符串里面，比如：&lt;h1&gt;Hello ${name}!&lt;/h1&gt;<font color=#000000>以及 <tt style="COLOR: #a03d10">&lt;#include "/footer/${company}.html"&gt;<br><br>数字值的插入：根据缺省的number_format输出，以及可以通过setting来达到设置数字格式的目的，也可以通过内置函数string来改变输出格式。<br><br>日期类型的格式设置：date_format<font color=#000000>, </font><tt style="COLOR: #a03d10">time_format</tt><font color=#000000>&nbsp;和 </font><tt style="COLOR: #a03d10">datetime_format</tt><font color=#000000><br><br><br></font>定义宏：<br>&nbsp;&nbsp;&nbsp;不带参数：<strong>&lt;#macro 宏名&gt;...</strong><strong>&lt;/#macro&gt;，引用&lt;@宏名 /&gt;<br></strong>&nbsp;&nbsp;&nbsp;带参数：<strong>&lt;#macro 宏名 参数...&gt;...&lt;/#macro&gt;，引用&lt;@宏名 参数1=值1.../&gt;，带有参数的宏，调用是参数的值必须和参数的个数相同。当然也可以在宏定义时给参数一些默认值。比如：&lt;#</strong><font color=#000000>macro greet person color<strong>="black"</strong>&gt;<br></font><br><br>宏里面的嵌套内容：<br>&lt;<font color=#000000>#macro border&gt;<br>&nbsp; &lt;table border=4 cellspacing=0 cellpadding=4&gt;&lt;tr&gt;&lt;td&gt;<br>&nbsp;&nbsp;&nbsp; <strong>&lt;#nested&gt;</strong><br>&nbsp; &lt;/tr&gt;&lt;/td&gt;&lt;/table&gt;<br>&lt;/#macro&gt;&nbsp;<br>在宏的定义body中加入&lt;#nested&gt;指令。嵌套的内容可以是任何正确的ftl块。<br><br>宏的本地变量在嵌套内容中是不可见的。<br><br>宏定义时，&lt;#nest&gt;指令相当于调用定义的内容，而使用宏时，nest body相当于定义。<br></font>
<pre class=smallpre style="MARGIN: 0px">&lt;#macro repeat count&gt;
&lt;#list 1..count as x&gt;
&lt;#nested <strong>x, x/2, x==count</strong>&gt;
&lt;/#list&gt;
&lt;/#macro&gt;
&lt;@repeat count=4 ; <strong>c, halfc, last</strong>&gt;
${<strong>c</strong>}. ${<strong>halfc</strong>}&lt;#if <strong>last</strong>&gt; Last!&lt;/#if&gt;
&lt;/@repeat&gt;&nbsp;<span style="FONT-SIZE: 1pt"><br></span></pre>
<br><br>定义变量：<br>&nbsp;&nbsp;&nbsp;在模板中定义的变量将会隐藏（不是更改）数据模型根下面的同名的变量。<br><br>模板中的3种类型变量：<br>&nbsp;&nbsp;&nbsp;1：<strong>plain variables，能够在模板中的任何地方访问，一个模板include另外一个模板，也可以访问被包含模板的变量。可以通过assign或者macro指令产生或替换变量。<br>&nbsp;&nbsp;&nbsp;如果要访问数据模型中的变量，则可以通过.global来访问：<br></strong>&nbsp;&nbsp;&nbsp;&lt;#assign user = "Joe Hider"&gt;<br>&nbsp;&nbsp;&nbsp;${user}&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;#-- prints: Joe Hider --&gt;<br>&nbsp;&nbsp;&nbsp;${.globals.user} &lt;#-- prints: Big Joe--&gt;&nbsp;<br>&nbsp;&nbsp;&nbsp;2：<strong>Local variables，宏定义body中用local指令创建或者替换。<br>&nbsp;&nbsp;&nbsp;3：Loop variables:由list指令产生。<br></strong><br><br></tt></font>namespaces:<br>&lt;#import "/lib/my_test.ftl" as <strong>my</strong>&gt; &lt;#-- the hash called "my" will be the "gate" --&gt;<br>&lt;@<strong>my</strong>.copyright date="1999-2002"/&gt;<br>${<strong>my</strong>.mail}&nbsp;<span style="FONT-SIZE: 1pt"><br></span><br>设置命名空间里面的变量：&lt;#assign mail="jsmith@other.com" <strong>in my</strong>&gt;<br><br>命名空间与数据模型：命名空间的ftl可以访问数据模型的变量。同样命名空间的变量也会隐藏数据模型中同名的变量。<br><br>空白问题：<br>1：White-space stripping，默认为enabled，清除ftl标记带来的空白以及缩进。处理模板的空白。<br>2：t, <tt style="COLOR: #a03d10">rt</tt>, <tt style="COLOR: #a03d10">lt指令。<br></tt>3：ftl的参数strip_text.<br><br>用compress directive或者transform来处理输出。<br>&lt;#compress&gt;<em style="COLOR: #dd4400">...</em>&lt;/#compress&gt;：消除空白行。<br>&lt;@compress single_line=true&gt;<em style="COLOR: #dd4400">...</em><a>/@compress</a>将输出压缩为一行。<br><br>可替换语法：<br>freemarker可用"["代替"&lt;".在模板的文件开头加上<strong>[#ftl].</strong><br></tt></font></font>
<img src ="http://www.blogjava.net/livery/aggbug/124263.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/livery/" target="_blank">心情经纬</a> 2007-06-14 11:50 <a href="http://www.blogjava.net/livery/articles/124263.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>