2

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);
    }
}
4

2 回答 2

4

FreeMarker 宏调用看起来不像@{...}. 那是某种忍者特定的扩展吗?

无论如何,如果你知道bar数据模型中有 a ,那么你的方法可以得到它Environment.getCurrentEnvironment().getDataModel().get("bar"),所以它不需要传入。

此外,了解 FTL 有两种“子例程”可能很有用,一种是类似函数的,一种是类似指令的。两者都可以在 FTL ( #function, #macro) 和 Java (纯 Java 方法, TemplateMethodModelEx, TemplateDirectiveModel) 中实现。真正的区别在于,类似函数的用于计算值,而类似指令的用于将值直接打印到输出(因此绕过自动转义)和副作用。但是所有这些都可以到达Environment,所以那里没有区别。

于 2015-02-12T18:21:02.340 回答
3

您可以“动态地”调用宏。假设你有一个宏:

<#macro myMacro>
  ${foo("bar")}
</#macro> 

你可以这样称呼它:

<@myMacro /> 

或者

<@.vars["myMacro"] />

那么你可以做...

<#assign someVar = "myMacro" />

<@.vars[someVar] />
于 2015-02-12T21:50:59.967 回答