2.
any number of times.
意思如下:实现此接口的对象可以作为用户定义指令(很像宏)。他们做任意的行为,写入任意
文本模板的输出,并触发其嵌套的内容以任意的次数显示出来。
当然这个接口并不是一开始就有的,在2.3.11版本的Freemarker之后才加入了该接口。可能看完上面一段话,你可能会觉得生涩难懂。没关系只要看懂下面的例子就行了。
import
java.io.IOException;
import
java.io.Writer;
import
java.util.Map;
import
com.common.freemarker.DirectiveUtils;
import
static freemarker.template.ObjectWrapper.DEFAULT_WRAPPER;
import
freemarker.core.Environment;
import
freemarker.template.TemplateDirectiveBody;
import
freemarker.template.TemplateDirectiveModel;
import
freemarker.template.TemplateException;
import
freemarker.template.TemplateModel;
public
class TestDirective
implements
TemplateDirectiveModel {
@Override
public
void execute(Environment env,
Map
params,
TemplateModel[] loopVars,
TemplateDirectiveBody body)
throws
TemplateException, IOException {
Writer out = env.getOut();// 固定写法
// 获取标签中,参数名为'param'对应的值
Long tpyeID= DirectiveUtils.getLong("param",params);
// 获取标签中,参数名为'var'对应的值
String varName = DirectiveUtils.getString("var", params);
// 根据获得的值,根据业务来处理输出数据
// 比如在新闻版块,从模板上把某一类的新闻的TypeID传给了自定标签
// 根据这个TpyID我们可以去获取前Top5的新闻,将这个Top5新闻封装在
// 自定义标签中。在预编译模板的时候,自定义标签就会被解析为5条新闻
// 并按照你预定的格式显示在页面上
List list = xxxxService.getTop5News(typeID);
// 比如你list里封装的是新闻对象(new)
//循环这个列表,依此把对象放入自定义标签中
for
(New new: list) {
// varName,相当于Map中的Key.通过varName可以在模板中取出new对象的值
env.setVariable(varName , DEFAULT_WRAPPER.wrap(new));
body.render(env.getOut());
}
}
}
// 模板中标签的写法
<@t_test var="news"
param="TypeID">
${news.属性}<---- 取出值
</@t_test >
在完成类的编写后在Spring配置文件中声明这个类
<bean
id="TestDirective"
class="XXX.TestDirective"/>
记得之前那边文章中spring配置文件中的
freemarkerVariables 属性吗?
通过Spring配置文件将我们的自定义标签注入进去
<property
name="freemarkerVariables">
<map>
<entry
key="TestDirective"
value-ref="t_test"/> [t_test]自定义名称,对应模板中的标签
</map>
</property>