在Freemarker中,如何单独翻译列表中的每个字符串,然后加入结果

时间:2016-03-07 04:49:21

标签: freemarker

我的模型包含两个字母的语言代码列表,例如(伪代码):

${info.languages} = [en, jp, mi]

我目前在我的模板中有标记,将这些标记格式化为以分号空格分隔的列表:

<#if info.languages??>
  ${info.languages?join("; ", "")}
</#if>

给出了

  

烯; J.P; MI

我想在分号分隔列表中显示每种语言代码的英文名称。我知道我可以使用Locale#getDisplayLanguage在Java中进行查找,所以我并不担心实际的翻译部分。

我的问题是如何将其与模板联系起来,同时仍然利用join内置功能。我想理想的是我希望能够像这样链接运营商:

${info.languages?displayLanguage?join(", ", "")}

it appears ?xyz语法是为核心内置函数保留的。

Tl;博士:有没有办法将自定义功能与join内置功能相结合?还是我忽视的其他有用的东西?或者我唯一的选择是让我的自定义功能进行加入以及翻译?

2 个答案:

答案 0 :(得分:1)

?join几乎只是为了方便而存在,以解决最常见的情况。在更一般的情况下,您应该使用#list。例如:

<#list info.languages as lang>${my.displayLanguage(lang)}<#sep>, <#/list>

当然,如果您在多个地方执行此操作,则应该将此代码段移动到宏中。

?xyz开始(它们被称为内置函数),是的,它是为模板语言保留的。

答案 1 :(得分:0)

关于这种处理属于何处的问题,我想出了如何做我在我的问题中描述的内容。

为了仍然使用?join运算符(因为它实际上 是加入列表中值的最常见情况),只需确保自定义方法返回传入的语言代码的显示名称列表

以下工作,假设传入的参数始终是列表:

public class DisplayLanguageMethod implements TemplateMethodModelEx {
  @Override
  public Object exec(List arguments) throws TemplateModelException {
      if (arguments == null || arguments.isEmpty()) {
          return null;
      }

      Object argObject = arguments.get(0);
      if (argObject == null || !(argObject instanceof TemplateSequenceModel)) {
          return Collections.emptyList();
      }

      TemplateSequenceModel argSequence = ((TemplateSequenceModel) argObject);
      List<String> displayLanguages = new ArrayList<>();
      for (int i = 0; i < argSequence.size(); i++) {
          String languageCode = Objects.toString(argSequence.get(i), null);
          String displayName = languageCode;
          if (languageCode != null) {
              Locale argLocale = Locale.forLanguageTag(languageCode);
              if (argLocale != null) {
                  displayName = argLocale.getDisplayName(Locale.getDefault());
              }
          }
          displayLanguages.add(displayName);
      }
      return displayLanguages;
  }
}

放入上下文中:

Map<String, Object> data = new HashMap<>();
data.put("displayLanguage", new DisplayLanguageMethod());
// get template, output writer etc as per usual
template.process(data, writer);

然后在模板中使用如下:

<#if info.languages??>
  ${displayLanguage(info.languages)?join("; ", "")}
</#if>