【问题标题】:How to make resource bundles work with existing Freemarker templates?如何使资源包与现有的 Freemarker 模板一起使用?
【发布时间】:2014-05-13 01:16:21
【问题描述】:

我正在为 IBM Connections 开发 Java 应用程序,我的应用程序需要生成和发送基于模板的电子邮件。
Connections 包括几个使用资源包的 Freemarker 模板。我希望我的代码使用这些副本并进行最少的更改,但我以前从未使用过 Freemarker。

在我的 Java 代码中,如何将资源包与 Freemarker 模板相关联,以使现有模板可以正常工作?

模板和资源包在这个目录结构中:

通知(目录) -> 活动(目录) -> 资源(目录) -> nls(目录) -> 属性文件 -> 模板 FTL 文件 -> 资源(目录) -> nls(目录) -> 属性文件 -> 导入的 FTL 文件

主要模板文件之一是“notifyMail.ftl”。该文件中一些特别感兴趣的行是:

<#import "*/resources/commonStructure.ftl" as s> <#import "*/resources/commonUtil.ftl" as u> <#import "*/resources/commonUrlUtil.ftl" as urlUtil> <#lt><@s.header>${u.resource("email.notify.body."+"${key}","${activity.event.sender.display.name}",urlUtil.linkifyItem("${activity.node.permalink}", "${activity.node.name}"))}</@s.header>

“commonUtil.ftl”文件声明了两个使用资源包的函数,如下所示。
第一个函数使用称为“__parameters”的成员。
我假设需要在 Java 代码中将其传递给 Freemarker,因为我没有看到它在模板中的任何地方定义。

<#function resource messageKey params...>
    <#if __parameters.__resourceBundle?keys?seq_contains(messageKey)>
        <#local bundleString = bundleResource(__parameters.__resourceBundle,messageKey,params) />
    <#elseif __parameters.__sharedBundle?keys?seq_contains(messageKey)>
        <#local bundleString = bundleResource(__parameters.__sharedBundle,messageKey,params) />
    <#else>
        <#return messageKey /> <#-- message key not found, return the key back -->
    </#if>

    <#if bundleString??>
        <#return bundleString />
    <#else>
        <#return messageKey />
    </#if>
</#function>

<#function bundleResource bundle messageKey params>
<#if bundle??>
<#switch params?size>
<#case 0>
    <#return bundle(messageKey)>
    <#break>
<#case 1>
    <#return bundle(messageKey, params[0])>
    <#break>
<#case 2>
    <#return bundle(messageKey, params[0], params[1])>
    <#break>
<#case 3>
    <#return bundle(messageKey, params[0], params[1], params[2])>
    <#break>
<#case 4>
    <#return bundle(messageKey, params[0], params[1], params[2], params[3])>
    <#break>
<#case 5>
    <#return bundle(messageKey, params[0], params[1], params[2], params[3], params[4])>
    <#break>
<#default>
    <#stop "resource function doesn't support more than 5 parameters for a message due to language reason. And it's seldom to have more than 5 parameters in a message. However, you can extend the limit by changing the function if you really want to."/>
</#switch>
</#if>
</#function>

【问题讨论】:

  • __parameters 肯定来自 FreeMarker 数据模型(Template.process(...) 的参数)。因此它也在 FreeMarker 之外填充。尝试${__parameter} - 也许它会打印出该变量的实际类是什么(可能作为错误消息的一部分,使用 FreeMarker 2.3.20)。顺便说一句,不要写... + "${key}" + ... 之类的,它只是... + key + ...
  • 关于${key},我没有创建这些模板,也不想更改任何我不需要的东西。此外,key 实际上是在模板中的 #assign 语句中定义的 - 有些行我没有在我的问题中显示。

标签: java templates freemarker


【解决方案1】:

这个问题的解决方案很简单,尽管由于我的属性文件存在问题,我在让消息格式正常工作时遇到了很多麻烦。

我发送给freemarker.template.Template.process()Map 只需要与FTL 文件使用相同层次结构的ResourceBundle 实例。

例如FTL 文件在哪里:

__parameters.__resourceBundle

我有一个带有我的 Java 源代码的 notification.properties 文件,并将其添加到发送到 Freemarker 的地图中,如下所示:

HashMap tmplParams=new HashMap();

tmplParams.put("__resourceBundle",ResourceBundle.getBundle(
    "<parent directory path>.activities.resources.nls.notification"));

root.put("__parameters",tmplParams);

【讨论】:

    猜你喜欢
    • 2021-08-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多