如何使用 SpEL 处理 Thymeleaf 中的本地化消息

Posted

技术标签:

【中文标题】如何使用 SpEL 处理 Thymeleaf 中的本地化消息【英文标题】:How can localized messages in Thymeleaf be processed using SpEL 【发布时间】:2014-04-30 22:52:06 【问题描述】:

我是 ThymeLeaf 的初学者,除了 @PreAuthorize 注释外,没有过多使用 SpEL,所以请帮帮我。

我正在使用 ThymeLeaf(版本 2.1.2)与 Spring(4.0.2.RELEASE)和 thymeleaf-spring4 包(据我了解)replaces the default OGNL scripting with SpEL。

我想要实现的只是通过#strings.capitalize 函数将本地化字符串大写。到目前为止,这是我尝试过的:

<h1 th:text="#retrievable.key">Text to be replaced</h1>

完美运行并提供预期结果。

现在当我尝试这个时:

<h1 th:text="$#strings.capitalize(#retrievable.key)">Text to be replaced</h1>

我得到了以下异常(根本原因,为清楚起见省略其余部分):

org.springframework.expression.spel.SpelParseException:
EL1043E:(pos 21): Unexpected token.  Expected 'identifier' but was 'lcurly()'

好的,好的。只是为了好玩,我省略了大括号并得到了我的预期:&lt;h1&gt; 是空的。

所以现在我认为可能有必要对retrievable.key 的消息检索进行预处理,以便在评估#strings.capitalize 时已经评估它。尽管这对我来说似乎违反直觉和不合逻辑,因为这会破坏所有编程规则,但我尝试了这种方法。它也不起作用:使用

$#strings.capitalize(__#retrievable.key__)

导致

org.thymeleaf.exceptions.TemplateProcessingException:
Could not parse as expression: "#retrievable.key"

并使用

$#strings.capitalize(__#retrievable.key__)

导致(你猜对了)&lt;h1&gt;&lt;/h1&gt;

我知道实际问题可以用 CSS 或 javascript 解决,但不一定是大写或大写,而是本地化字符串的处理,这是一个例子。

那么我在这里错过了什么?

Thymeleaf 论坛提供的解决方案

ThymeLeaf 论坛的 Zemi 提供了以下内容,elegant solution:

<h1 th:text="$#strings.capitalize('__#retrievable.key__')">Text to be replaced</h1>

请注意单引号。预处理似乎真的意味着 Thymeleaf 中的预处理。

不过,我已经接受了第一个可行的答案。

【问题讨论】:

感谢您的准确问题和答案!我在使用 strings.replace 时遇到了完全相同的问题,你帮了我很多! :) 【参考方案1】:

以下对我有用

<body th:with="message=#retrievable.key">
    <h1 th:text="$#strings.capitalize(message)">Text to be replaced</h1>
</body>

【讨论】:

这也适用于我。感谢那。问题仍然是为什么不能直接使用该消息。你对此有什么想法吗? 我不知道为什么无法解析表达式...这对于论坛forum.thymeleaf.org/template/…Thymeleaf 的创建者 Daniel Fernandez 来说是个好问题@ “#retrievable.key”的问题应该是它解决了诸如“#strings.capitalize”之类的thymeleaf对象/函数,而Thymeleaf不知道“retrievable”。【参考方案2】:

为什么要将本地化字符串大写?如果它真的被本地化为不同的语言,那么如果你对它们执行 toUpper,你可能不会得到你想要的结果。更好的方法是在您想要显示的情况下本地化字符串。

【讨论】:

a) 这不是我的问题的答案,更适合发表评论。 b) 本地化字符串可以在多个实例中使用 - 例如,在这个用例中,至少在标题中使用一次,根据项目的样式指南和文本中的多个实例将其大写。 c) 专业本地化要么非常昂贵,要么非常耗时,或者两者兼而有之。重复使用短语只是效率问题。 分离内容和设计是最好的做法。您是否真的想要更改本地化只是因为设计师决定他想要大写的标题而不是大写的字符串? d) 我完全知道调用 toUpper (将字符串中的 all 字符转换为大写等价物,如果适用)与大写非常不同,后者将每个单词的第一个字符转换为一个字符串(或者,更准确地说,一个单词边界后的每个字符)到它的大写等效项。 e) 客气地说:聪明的答案不依赖于假设,而是依赖于问题中提出的事实。【参考方案3】:

正如你所写,它看起来像预处理表达式 ala

__$...__

不要使用主题标签。

您可以做的是在表达式中使用 messageSource bean,因为这可以在“正常”表达式中解决。

 <div th:text="$beans.messageSource.getMessage(messageVariable)"></div>

【讨论】:

以上是关于如何使用 SpEL 处理 Thymeleaf 中的本地化消息的主要内容,如果未能解决你的问题,请参考以下文章

Thymeleaf 和 Spring Security - 自定义 SpEL 表达式

Spring Security - Thymeleaf - 我可以在 sec:authorize 标签中评估 SPEL 表达式吗?

SpEL表达式

org.springframework.expression.spel.SpelEvaluationException: EL1008E:(pos 8): 属性或字段

Spring / Thymeleaf:在null上找不到属性或字段,但仍在渲染

如何在 Thymeleaf 中循环遍历 Map