我的模型包含两个字母的语言代码列表,例如(伪代码):
${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
内置功能相结合?还是我忽视的其他有用的东西?或者我唯一的选择是让我的自定义功能进行加入以及翻译?
答案 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>