Spring MVC/Freemarker:在 Freemarker 表达式中使用来自包的消息

And*_*oni 2 freemarker spring-mvc internationalization

在 Fremarker 模板中,我需要访问从 Spring MVC 在 Freemarker 表达式中提供的 i18n 资源包中获取的消息。

我已经从中导入了 Spring 宏,spring.ftl并且可以将消息与以下宏一起使用:

<@spring.messageText "my.key" "Default message" />
Run Code Online (Sandbox Code Playgroud)

但实际上我无法从内部表达式访问消息,例如在内置表达式中:

${myBoolean?string( ###here I want my true message###, ###here I want my false message###)}
Run Code Online (Sandbox Code Playgroud)

我怎样才能做到这一点?

dde*_*any 5

在你展示的具体案例中,也许你应该写

<#if myBoolean><@spring.messageText ...><#else><@spring.messageText ...></#if>
Run Code Online (Sandbox Code Playgroud)

如果经常需要它,那就#macro为它做一个。

在更通用的情况下,问题是您不能从表达式调用宏(或指令),并且 Spring 也应该提供一个函数变体message。我不知道 Spring MVC,但是看着spring.ftl,似乎springMacroRequestContext.getMessage(code, text)应该可以解决这个问题。但这很冗长,所以您可能想创建一个/lib/springutils.ftl包含以下内容的内容:

<#function message code text=''>
    <#if text != ''>
        <#return springMacroRequestContext.getMessage(code, text)>
    <#else>
        <#return springMacroRequestContext.getMessage(code)>
    </#if>
</#function>
Run Code Online (Sandbox Code Playgroud)

然后在您的模板中:

<#import "/lib/springutils.ftl" as su>

${myBoolean?string(su.message(...), su.message(...))}
Run Code Online (Sandbox Code Playgroud)

但是,请注意,如果您使用 打印值${...},它会受到#escape(当然,如果您使用它)的影响,而如果您使用 打印某些内容<@...>,则它永远不会转义(因为<@...>/<#...>意味着打印标记)。因此,如果您的消息包含 HTML,${...}那么您最终可能会按字面意思为用户显示 HTML 标记(如<将被转义&lt;等)。除非,你写<#noescape>${...}</#noescape>.

(对转义的更新:FreeMarker 2.3.24 支持没有 的自动转义#escape,在那里你可以使用${su.message(...)?no_esc}。更好的是,如果你以某种方式知道message消息是 HTML的函数内部,你可以使用<#return springMacroRequestContext.getMessage(...)?no_esc>,然后只写${su.message(...)}并且 FreeMarker 不会重复 -逃避它。)