Freemarker 被用作 ninja web 框架中的默认模板引擎。该框架为使用 ninja web 框架时全局可用的模板分配了一些默认值。我已经为启用 CSRF-Protection 的模板创建了一个扩展。该扩展提供了一个可以在模板中使用的功能,例如
${foo(bar)}
目前需要使用特定的参数调用该函数,这不是很直观。使用宏我可以简化这个调用
@{foo}
并且用户无需担心传递正确的(例如“bar”)参数。但是为了让这个在 ninja web 框架中可用,我必须以编程方式定义一个宏。那可能吗?
更新
对困惑感到抱歉。意思是 <@foo/> 而不是 @{foo} ...
查看 Freemarker 文档,我也许可以更清楚地了解我想要实现的目标:http: //freemarker.org/docs/ref_directive_macro.html
就像我上面解释的那样,我将自定义函数传递给模板,使我能够调用
${foo("bar")}
我想做的是通过一个宏来调用它
@<myMacro/>
但是定义的宏就像
<#macro myMacro>
${foo("bar")}
</#macro>
不应在模板中定义,而是以编程方式定义。希望这能让它更清楚。
更新2/解决方案
我最终使用了推荐的 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);
}
}