Freemarker用作忍者Web框架中的默认模板引擎。框架为模板分配了一些默认值,这些默认值在使用忍者Web框架时是全局可用的。我已经为模板创建了一个扩展,它扩展了CSRF-Protection。扩展提供了一个可以在模板中使用的功能,例如
${foo(bar)}
目前需要使用特定参数调用函数,这不是非常直观的。使用宏我可以简化对
的调用@{foo}
并且用户无需担心传递正确的(例如" bar")参数。但是为了在忍者Web框架中提供这个,我必须以编程方式定义宏。这可能吗?
更新
很抱歉这个混乱。 Meant< @ foo />而不是@ {foo} ...
查看Freemarker文档,我可以更清楚地了解我想要实现的目标:http://freemarker.org/docs/ref_directive_macro.html
就像我上面解释的那样,我将自定义函数传递给模板,让我可以调用
${foo("bar")}
我想要做的是通过像
这样的宏来调用它@<myMacro/>
但定义的宏像
<#macro myMacro>
${foo("bar")}
</#macro>
不应该在模板中定义,而是以编程方式定义。希望能让它更加清晰。
UPDATE2 / SOLUTION
我最终使用了推荐的TemplateDirectiveModel。
public class TemplateEngineFreemarkerAuthenticityTokenDirective implements TemplateDirectiveModel {
private String authenticityToken;
public TemplateEngineFreemarkerAuthenticityTokenDirective(Context context) {
this.authenticityToken = context.getSession().getAuthenticityToken();
}
@Override
public void execute(Environment env, Map params, TemplateModel[] loopVars, TemplateDirectiveBody body) throws TemplateException, IOException {
if (!params.isEmpty()) {
throw new TemplateException("This directive doesn't allow parameters.", env);
}
if (loopVars.length != 0) {
throw new TemplateException("This directive doesn't allow loop variables.", env);
}
Writer out = env.getOut();
out.append(this.authenticityToken);
}
}
答案 0 :(得分:4)
FreeMarker宏调用看起来不像@{...}
。这是某种忍者特定的延伸吗?
无论如何,如果你知道数据模型中有bar
,那么你的方法可以像Environment.getCurrentEnvironment().getDataModel().get("bar")
那样得到它,所以不需要传入它。
此外,知道FTL有两种&#34;子程序&#34;,类似函数的函数和类似指令的函数可能很有用。两者都可以在FTL(#function
,#macro
)和Java(普通Java方法,TemplateMethodModelEx
,TemplateDirectiveModel
)中实现。真正的区别在于类似函数的用于计算值,而类似指令的用于将值直接打印到输出(因此绕过自动转义)和副作用。但所有这些都可以达到Environment
,所以那里没有区别。
答案 1 :(得分:3)
您可以动态调用宏&#34;#34;。让我们说你有一个宏:
<#macro myMacro>
${foo("bar")}
</#macro>
您可以这样称呼它:
<@myMacro />
OR
<@.vars["myMacro"] />
那么你可以做......
<#assign someVar = "myMacro" />
<@.vars[someVar] />