freemarker 速记



----------------------------------------------------------模板开发指南-----------------------------------------------------------
1 如果user或name为null,使用默认值。对pojo的调用方式与哈希表相同
${(user.name)!"anonymous"} == ${(user["name"])!"anonymous"}


2 数字格式化插值  # {...}, 如果为空 ! 使用默认值
#{(user.age)!100}


3 调用函数 
${"anonymous"?upper_case}


4 截取字符串,建议使用?substring()
<#-- 同样适用于list。但${"anonymous"[5..2]}不适用于字符串,可用于list-->
${"anonymous"[0]} ${"anonymous"[0..4]} ${"anonymous"[5..]}


5 user.name?? 判断是否存在, 布尔不能直接打印,可使用?string("true","false") 。true/false代表布尔值,不需引号
${(user.name)???string("true","false")}


6 \ 转义 
${"It's \"quoted\" and this is a backslash: \\"}


7 r"...",对字符串不进行解析,直接输出
${r"${foo}"}


8 ${08} == ${+8} == ${8.00} == ${8}


9 list支持合并、截取
<#list ([1,"haha",4]+[3,"heihei"])[3..1] as x>
${x}
</#list>


10 数字列表
<#list 3..1 as x>
${x}
</#list>

11 哈希表支持合并,覆盖。assign 定义全局变量,local 定义局部变量
<#assign map={"one":"张三","two":"李四"}+{"three":"王五","two":"刘六"}>
${map.two} == ${map["two"]}
<#list map?keys as key>
${key} -- ${map[key]}
</#list>

12 获取复杂变量类型,不支持基本类型、string、date
${user.class.simpleName}

13 字符串链接
${"Hello ${user.name}!"} ${"Hello " + user.name + "!"}

14 freemarker只有SimpleNumber类型 这一种数据类型。
${5/2} = 2.5 ${(5/2)?int} = 2 ${(5/2)?round} = 3 ${(5/2)?floor} = 2 ${(5/2)?ceiling} = 3


15 比较符使用 &gt;等,或使用(),遗留问题也可使用\gt。数字、日期类型都可使用比较符。 ?date用于指定使用日期的date/time/datetime
<#if (user.age &gt; 20)>${user.name}</#if> <#if (user.birthday?date < .now?date)>${user.name}</#if>

16 内建函数
html:将html特殊字符进行转换
cap_first/lower_case/upper_case
size:序列/哈希表元素数量,字符串长度使用length

17 调用已定义过的方法
<#--${repeat("love",3)} -->


18 escape 相当于所有$ {..}都变为$ {..?html},noescape 可抵消其作用
<#escape x as x?html>
...
<p>Name: ${user.name}</p>
<p>Age:
<#noescape>${user.age}</#noescape>
</p>
<h2>Hobbys:</h2>
<#list user.hobbys as hobby>
<div class="comment">
${hobby}
</div>
</#list>
...
</#escape>


19 宏变量 greet是宏变量名,person是参数。无默认值的参数调用时必须传入,传入的参数可是变量。< #nested>引用嵌套内容,";"后是循环变量("循环变量"这个名称有歧义),通过< #nested>传入到嵌套内容中
<#macro greet person color="black">
<font size="+2"> ${person}  ${color}</font>
嵌套内容:
<#nested "a","b","c">
</#macro>
调用:
<@greet person="handsome">嘛哩嘛哩哄</@greet>
//传入color
<@greet person=user.name color="red"/>
//传入循环变量,获取< #nested "a","b","c">中定义的值
<@greet person=user.name ; a,b> ${a}  ${b} </@greet>

20 变量作用域。局部同名变量会隐藏普通变量。在局部可使用.globals来调用数据模型的同名变量(map.add()添加的数据)
<#assign x = "plain">
1. ${x} <#-- 这里是普通变量 -->


<#macro test>
2. ${x} <#-- 这里我们仍然看到的是普通变量 -->
<#local x = "local">
3. ${x} <#-- 现在局部变量隐藏了它 -->
<#list ["loop"] as x>
4. ${x} <#-- 现在循环变量隐藏了局部变量 -->
</#list>
5. ${x} <#-- 现在又可以看到局部变量了 -->
</#macro>

<@test/>
6. ${x} <#-- 普通变量的值没有被改变 -->
<#list ["loop"] as x>
7. ${x} <#-- 现在循环变量隐藏了普通变量 -->
<#assign x = "plain2"> <#-- 替换普通变量, 隐藏在这里不起作用-->
8. ${x} <#-- 它仍然隐藏普通变量 -->
</#list>
9. ${x} <#-- 普通变量的新值 -->


-----------------------
内部循环可隐藏外部的变量
<#list ["loop 1"] as x>
${x}
<#list ["loop 2"] as x>
${x}
<#list ["loop 3"] as x>
${x}
</#list>
${x}
</#list>
${x}
</#list>


21 import 使用其他模板文件中的定义的宏函数、变量,不会把模板的内容包含进来。(include指令会将引入的模板当作本模板的一部分来处理,视为一个文件)
<#import "import.ftl" as im>
<@im.copyright .now?date/>
${im.mail}
//替换im命名空间下的普通变量
<#assign mail="simth" in im>
${im.mail}

22 剥离空白
//compress是针对输出的内容进行压缩,移除前后的空白,中间的多个空白只保留一个。single_line=true会移除所有的换行符
<@compress single_line=true>
前面有一个缩进,                                后面有空白            
           前面有很多空格
</@compress>

//可使用t、rt、lt来移除空白


23 通过在模板文件的首行添加[#ftl],可替换文件中的< , >。之后可使用[ #list]、[ #if]来代替< #list>、< #if>








----------------------------------------------------------程序开发指南-----------------------------------------------------------
1 入门级实例:
Configuration cfg = new Configuration();

cfg.setDirectoryForTemplateLoading(new File("resource/template"));
cfg.setObjectWrapper(new DefaultObjectWrapper());

Template temp = cfg.getTemplate(ftl);
Writer out = new OutputStreamWriter(System.out);
temp.process(new HashMap(), out);
out.flush();


//Template 只创建一次,缓存在Configuration中,默认5秒检测模板是否更新,基于类的模板加载器不会注意到模板文件内容的改变,vm会回收模板,cfg.clearTemplateCache可清空
//可通过cfg.setSetting(cache_storage,"strong:20,soft:250")或调用cfg.setCacheStorage来配置缓存,
//默认使用MruCacheStorage("strong:0,soft:Integer.max_value"),实现二级缓存。一级缓存中的模板引用次数超过阀值就被加载到二级缓存中
2 每个接口都继承TemplateModel,此处只列出最常使用的一个实现类
数字:TemplateNumberModel {getAsNumber}----------SimpleNumber
字符串:TemplateScalarModel {getAsString}-----------SimpleScalar
日期:TemplateDateModel {getAsDate/getDateType}-----------SimpleDate ==>(getAsDate/getDateType)
布尔:TemplateBooleanModel-----------BooleanModel.true/BooleanModel.FALSE

序列:TemplateSequenceModel {get/size}-----------SimpleSequence
哈希表:TemplateHashModel {get/isEmpty}-----------SimpleHash
集合:TemplateCollectionModel {iterator}-----------SimpleCollection

方法:TemplateMethodModel {exec}-----------自定义类,返回值是void的方法返回TemplateModel.NOTHING
指令:TempateDirectiveModel {execute}-----------自定义类


3 自定义指令,使用@来调用,可通过map.add()来添加到模板,也可通过< #assign upper="com.example.UpperDirective"?new()>来添加
< @myDirective count=3;cnt> $ {cnt} Welcome </ @myDirective>

public void execute(
Environment env, //通过env.getOut()对象来输出内容。
Map params, //参数
TemplateModel[] loopVars,//代码中填充loopVars变量,freemarker会自动将变量设置到嵌套内容中
TemplateDirectiveBody body //嵌套内容
) throws TemplateException, IOException {


4 map.add()添加的是java对象,模板实现会通过ObjectWrapper使用合适的TemplateModel对象来替换原有对象


5 共享变量集合初始化时,会自动添加capture_output/compress/html_escape/normalize_newliens/xm_escape。
cfg.setSharedVariable("wrap",new WrapDirective());//TemplateModel不是线程安全的,不能在多线程中作为共享变量
cfg.setSharedVariable("company","Foo Inc.");


6 配置信息(可在Configuration、Template、Environment中配置,后者会覆盖前者)
Configuration: cfg.setLocale/cfg.setNumberFormat、cfg.setSetting(name,value)
Template: 由TemplateCache来管理,第一次使用就设置了配置信息,然后就将Template视为只读的
Environment:e nv.setLocale/env.setNumberFormat 或在模板文件中 < #setting locale="cz">

7 模板加载器
setDirectoryForTemplateLoading(File dir)
setClassForTemplateLoading(Class cl, String prefix) //使用 Class.getResource()获取
setServletContextForTemplateLoading(Object servletContext, String path) //使用ServletContext.getResource()获取

cfg.setTemplateLoader(
new MultiTemplateLoader(new TemplateLoader[] { //从多个位置加载
FileTemplateLoader,
URLTemplateLoader, //通过url访问
ClassTemplateLoader
})); 


8 模板异常
cfg.setTemplateExceptionHandler(TemplateExceptionHandler):只要出现TemplateException异常,便会调用配置的模板异常处理器
freemarker的错误控制器:
TemplateExceptionHandler.DEBUG_HANDLER(默认):打印异常信息,重新抛出异常
TemplateExceptionHandler.HTML_DEBUG_HANDLER:除了异常信息格式,与DEBUG_HANDLER相同
TemplateExceptionHandler.IGNORE_HANDLER:忽略异常(只捕获不处理)
TemplateExceptionHandler.RETHROW_HANDLER:只简单重新抛出


9 变量
//Template.process会在内部创建一个Environment,
//Environment存储模板执行是的运行状态信息,还会存储assign、macro、local、global变量

//freeMarker查找变量顺序:Environment-->process传入的数据模型-->Configuration中的共享变量集合

10 freemarker采用unicode(UTF-16)字符集,可通过encoding配置项或cfg.setEncoding方法设置模板字符集。模板使用的字符集和生成的输出内容的字符集是独立的
可通过output_encoding配置输出字符集,也可通过env.setOutputEncoding对模板单独设置字符集


11 使用DefaultObjectWrapper不允许Collection、Map在模板执行期间被修改,但BeansWrapper包装器允许
a:所有Bean都被包装成TemplateHashModel。BeansWrapper.setExposeFields(true)会暴露公有非静态变量,作为哈希表的键值
b:BeansWrapper有一些安全级别
EXPOSE_SAFE(默认):适用于大多数应用
EXPOSE_ALL:允许调用不安全的方法
EXPOSE_PROPERTIES_ONLY:只暴露bean属性的getter方法
EXPOSE_NOTHING:不会暴露任何属性和方法


12 解包:在模板中调用java方法是,传入的参数需要从模板模型转换会java对象
空模型 -------> null
AdapterTemplateModel -------> model.getAdaptedObejct() :由BeansWrapper创建的所有方法是AdapterTemplateModel的实现
WrapperTemplateModel(已废弃) -------> model.getWrappedObject()
TemplateScalarModel -------> String/Character
TemplateNumberModel -------> Number
TemplateBooleanModel -------> Boolean
TemplateHashModel -------> Map
TemplateSequenceModel -------> List/数组
TemplateCollectionModel -------> Set/Collection/Iterable
TemplateDateModel -------> Date
....(FreeMarker教程 4.4.8)


13 访问静态方法
BeansWrapper.getStaticModels()返回哈希表模型,通过该对象可访问所有java的静态变量($ {staticModel["java.lang.System"].currentTimeMills()})
为了安全,可staticModel.get("java.io.File")获取后,放入到数据模型对象中


BeanSWrapper.getEnumModels()返回哈希模型,通过该对象可访问所有枚举($ {enumModel["java.math.RoundingMode"].UP})


14 日志 
FreeMarker会按 slf4j、commons logging、log4j、avalon、logging顺序查找日志包,使用第一个发现的
Logger.selectLoggerLibarary(LoggerLIBRARY_SLF4J):可通过传入Logger.LIBRARY_NONE来关闭日志
freemarker记录器(freemarker.*):beans/cache/runtime/runtime.attempt/servlet/jsp




15 FreeMarkerServlet:会在数据模型中放置几个web相关的哈希表:Request、Session、Application、RequestParameters
可覆盖Servlet的preTemplateProcess来添加额外的数据模型

< @include_pate path="" [inherit_params=true] [params={}]>
a、和 <jsp:include page="">作用相同,
b、inherit_params用于设置被包含的页面能否访问当前请求中的参数
c、params用于设置包含页面能访问的参数


//freemarker模板中使用jsp标签
< #assign html=JspTaglibs["/WEB-INF/struts-html.tld"]>
a、使用jsp标签
b、global指令创建的变量相当于page。jsp需要访问的其他域数据都放置在数据模型中


freemarkerServlet实现了自身轻量级的JSP运行时环境,用到JSP标签,但并不依赖于JSP支持。
需要在TLD文件中,开启FreeMarker的JSP运行时环境来分发事件到JSP标签库注册事件监听器
<listener>
<listener-class>freemarker.ext.jsp.EventForwarding</listener-class>
</listener>


在JSP中嵌入ftl,嵌入的ftl可以访问jsp的4种范围内的属性


----------------------------------------------------------参考文档-----------------------------------------------------------
1 字符串
cap_first|capitalize:首字母大写
uncap_first:首字母小写
lower_case
upper_case

left_pad(5[,"-"]):距左边
right_pad

date("MM/dd/yyyy"):将字符串转换为日期
time("HH:mm:ss")
datetime("yyyy-MM-dd hh:mm a")

index_of("",from)
last_index_of("",from)

contains
start_with:以指定字符串开始
ends_with:
group与matches:正则表达式匹配

html
rft:\-->\\、 {-->\{、 }-->\}
url(["utf-8"])

j_string:java规则字符串转义
js_string:js规则字符串转义
json_string:json规则字符串转义

chop_linebreak:末尾没有换行符的字符串,可以换行,否则不改变字符串
substring(from[,toExclusive]):截取
trim
split
word_list:以空格来分隔字符串
replace

length
number:格式化

2 数字
//格式化,可通过< #setting number_format="currency">来设置全局
string.number
string.currency
string.percent
string.computer:相当于c,不带格式的数字

//会四舍五入
string("0")
string("0.#")
string("0000.00")
string("0.##E0")


round
floor
ceiling


3 日期
//格式化,可通过date_format/time_format/datetime_format
//将日期转换成字符串
string.short
string.medium
string.long
string.full

string("yyyy-MM-dd")
string("HH:mm:ss")
string("yyyy-MM-dd HH:mm:ss")

//返回的仍然是SimpleDate类型
datetime
date
time

iso_utc
iso_utc_ms
iso_local
iso("UTC")
iso_m("GMT+02")


4 布尔
string("true","false")


5 序列
first
last


seq_contains
seq_index_of
seq_last_index_of

sort
sort_by("key"):序列中存放的是哈希表,以哈希表中的指定key来排序
reverse

size
chunk(4[,'-']):将序列分隔成大小为4的子序列,小于4的用指定字符('-')填充


6 哈希表
keys:键集合
values:值集合


7 高级函数
//将毫秒值转换成时间
number_date
number_to_time
number_to_datetime


eval:对字符串进行运算,"1+2"?eval 返回3
interpret:将字符串解释为ftl模板

has_content:变量不为null,且不为空,返回true

//类型判断
is_string
is_number
is_boolean
is_date
is_sequence
is_hash/is_hash_ex
is_collection
is_directive
is_method
is_macro
is_enumerable
is_transform
is_node
is_indexable


namespace:命名空间


new():创建实现了TemplateModel接口的类


--------------------------------------------------------
1 <#if condition> 
<#elseif condition> 
...
<#else> 
...
</#if>

2 <#switch value>
<#case refValue1>
...
<#break>
<#case refValue2>
...
<#break>
<#case refValueN>
...
<#break>
<#default>
...
</#switch>

3 <#list 1..x as i>
<#if x = "spring"><#break></#if>
</#list>


4 <#include path [options]>:
options:
encoding:默认子文件从父文件集成编码方式
parse:如果false,则子文件将被视为简单文本

<#include "*/footer.ftl">:从当前目录或它的任意父目录获取,会按如下顺序查找:
foot_en_US.ftl --> foot_en.ftl --> foot.ftl
可通过cfg.setlocalizedLookup关闭本地查找


5 <#import path as hash> 引入一个库,可视为java中的import
同一个path多次调用,只会实例化一个,其他命名空间都指向这一个实例


6 <#noparse>...</#noparse>:不解析,原文本输出


7 移除空白:
compress:对输出内容压缩,移除首尾空格符,连续出现的空格只保留一个

t:移除首尾空格符
lt:
rt:

nt:抵消t/lt/rt作用

8 <#escape identifier as expression>
...
<#noescape>...</#noescape>
...
</#escape>

9 <#assign name=value>
or
<#assign name1=value1 name2=value2 ... nameN=valueN>
or
<#assign same as above... in namespacehash>
or
<#assign name>
capture this
</#assign>
or
<#assign name in namespacehash>
capture this
</#assign>

//不应该向嵌套内容中插入变量
<#assign x>Hello ${user}!</#assign>:错误
<#assign x="Hello ${user}!">:正确


10 //所有命名空间都可见
<#global name=value>
or
<#global name1=value1 name2=value2 ... nameN=valueN>
or
<#global name>
capture this
</#global>


11 //在宏和方法中定义
<#local name=value>
or
<#local name1=value1 name2=value2 ... nameN=valueN>
or
<#local name>
capture this
</#local>


12 <#setting name=value>,可设置的值:locale/number_format/boolean_format/url_escaping_charset/classic_compatible
/date_format/time_format/datetime_format/time_zone


13 <#macro name param1 param2 ... paramN>
...
<#nested loopvar1, loopvar2, ..., loopvarN>
...
<#return>
...
</#macro>


14 //类似于macro,但是没有nested,使用${name(params)}来调用
<#function name param1 param2 ... paramN>
...
<#return returnValue>
...
</#function>


15 flush:简单调用Writer的flush


16 <#stop reason>:终止模板处理


17 <#ftl param1=value1 param2=value2 ... paramN=valueN>:参数应该是
encoding:模板编码
strip_whitespace:开启/关闭空白剥离
strip_text:开启时,当模板被解析时模板中所有顶级文本被移除
strict_syntax:严格语法,也可调用cfg.setStrictSyntaxMode
ns_prefixes:关联节点命名空间前缀的哈希表
attributes:关联模板任意属性的哈希表


--------------------------------------------
特殊变量:
data_model:直接访问数据模型的哈希表(在global定义的变量同名时使用)
globals:访问全局变量的哈希表
locales:访问本地变量的哈希表
locale:返回当前本地设置的值
language:返回本地设置的语言部分的值
main:访问主命名空间的哈希表
namespace:访问当前命名空间的哈希表
now:返回当前时间
output_encoding:返回当前输出字符集的名称
template_name:当前模板的名称
url_escaping_charset:如果存在,它存储了用于URL转义的字符集名称
vars:表达式.vars.foo或.vars["foo"]和foo效果一样,当变量名比较特殊时使用
version:freemarker的版本





  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
FreeMarker是一个用于生成HTML Web页面的模板引擎。它被设计用于将视图从业务逻辑中分离,通过模板来生成页面并展示数据。虽然FreeMarker具有一些编程能力,但通常由Java程序准备要显示的数据,然后由FreeMarker生成页面。它不是一个Web应用框架,而是适合作为Web应用框架的一个组件。FreeMarker与容器无关,可以应用于非Web应用程序环境。它更适合作为Model2框架(如Struts)的视图组件,也可以在模板中使用JSP标记库。FreeMarker具有强大的模板语言,支持常用的指令、循环结构、变量定义和复杂表达式等。它还提供了通用数据模型,可以方便地处理各种数据。\[2\] 在使用FreeMarker时,可以在webapp目录下创建template文件夹,并在其中创建模板文件。模板文件使用HTML标签和FreeMarker注释语法来定义页面结构和逻辑。可以通过${}语法来引用数据并在页面中展示。\[3\] 要启动使用FreeMarker的项目,需要在项目的依赖中添加FreeMarker的相关配置。可以在pom.xml文件中添加如下依赖配置: ```xml <dependency> <groupId>org.FreeMarker</groupId> <artifactId>FreeMarker</artifactId> <version>2.3.29</version> </dependency> ``` 这样就可以在项目中使用FreeMarker来生成页面了。\[1\] #### 引用[.reference_title] - *1* [FreeMarker简介及使用示例](https://blog.csdn.net/qq_39326472/article/details/131264082)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* *3* [FreeMarker详细介绍](https://blog.csdn.net/weixin_44454512/article/details/109877418)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值