How can localized messages in Thymeleaf be processed using SpEL
Asked Answered
G

4

16

I am a beginner with ThymeLeaf and have not used SpEL too much except for @PreAuthorize annotations, so please be so kind to help me out.

I am using ThymeLeaf (version 2.1.2) together with Spring (4.0.2.RELEASE) and the thymeleaf-spring4 package which (as far as I understood it) replaces the default OGNL scripting with SpEL.

What I want to achieve is simply that a localized string is capitalized via #strings.capitalize function. Here is what I tried so far:

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

Works perfectly and gives the expected result.

Now when I tried this:

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

I got the following exception (root cause, rest omitted for clarity):

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

Ok, fine. Just for fun, I omitted the curly brackets and got what I expected: the <h1> was empty.

So now I thought that it might necessary to preprocess the retrieval of the message for retrievable.key so that it is already evaluated when #strings.capitalize is evaluated. Though this seemed bot either counterintuitive and illogical to me, as this would break all programming rules, I tried that approach. It did not work either: using

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

lead to

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

and using

${#strings.capitalize(__#{retrievable.key}__)}

led to (you guessed it) <h1></h1>.

I know that the actual problem can be solved with CSS or JavaScript, but it's not necessarily about uppercasing or capitalizing, but on processing of localized strings and this is an example.

So what am I missing here?

Solution provided by Thymeleaf Forum

Zemi of the ThymeLeaf Forum provided the following, elegant solution:

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

Please notice the single quotes. Preprocessing seems to really mean preprocessing in Thymeleaf.

I have accepted the first working answer, however.

Gig answered 23/3, 2014 at 18:7 Comment(1)
Thanks for your precise question AND the answer! I had the exact same problem while using strings.replace and you helped me a lot! :)Firebird
B
14

The following worked for me

<body th:with="message=#{retrievable.key}">
    <h1 th:text="${#strings.capitalize(message)}">Text to be replaced</h1>
</body>
Business answered 23/3, 2014 at 18:31 Comment(3)
This works for me too. Thanks for that. The question remains why it is not possible to use the message directly. Do you have an idea on that?Gig
I have no idea why the expression can not be parsed... That would be a good question for Daniel Fernandez the creator of Thymeleaf on the forum forum.thymeleaf.org/template/…Business
The issue with "#retrievable.key" should be that this resolves against a thymeleaf object/function like "#strings.capitalize" and "retrievable" is not known by Thymeleaf.Limoges
T
1

#messages.msg can be used.

<h1 th:text="${#strings.capitalize(#messages.msg('retrievable.key'))}"></h1>
Twinberry answered 14/1 at 20:33 Comment(0)
L
0

As you wrote it looks like preprocessed expressions ala

__${...}__

do not work with the hashtag.

What you can do instead is using the messageSource bean inside your expression as this can be resolved in a "normal" expression as anything else.

 <div th:text="${beans.messageSource.getMessage(messageVariable)}"></div>
Limoges answered 24/3, 2014 at 6:47 Comment(0)
F
-1

Why would you capitalize a localized string? If it were truly localized to different languages then you might not get the results you want if you do a toUpper on them. The better approach is to localize the strings in the case that you want for display.

Fragmental answered 13/3, 2015 at 19:37 Comment(3)
a) This isn't an answer to my question and would be better suited for a comment. b) a localized string may be used in multiple instances - for example and in this very use case at least once in a headline, which are capitalized as per style guidelines for the project and in multiple instances in the text. c) Professional localization is either darn expensive or quite time consuming or both. Reusing phrases is simply a question of efficiency.Gig
And separating content and design is simply best practise. Would you really want to change the localization just because the designer decided he wants the headlines in uppercase instead of capitalized string? d) I am totally aware of the fact that calling toUpper (which converts all characters in a String to the uppercase equivalents, if applicable) is very different from capitalization, which converts the first character of each word in a string (or, to be more exact, each character following a word boundary) to its uppercase equivalent.Gig
e) Let me put it polite: smart answers don't depend on assumptions, but on facts as presented in the question.Gig

© 2022 - 2024 — McMap. All rights reserved.