Thymeleaf: replace newlines with
As in JSP , itβs not possible to use simple and simple
${#strings.replace(desc, '\n', '<br />')} There are at least two problems:
- '\ n' is processed by the main expression language (SpEL in my case when I use Spring MVC) as a string literal that consists of two separate characters: '\' and 'n', and not a single newline character Exception
- occurs because the Thymeleaf-based XML parser does not allow the placement of
<and>internal expressions
The solution I found for the first problem is to set a newline character in the controller and pass it for viewing.
To solve the second problem you need to use < instead of < and > instead of > . Also remember that this implies using th:utext instead of th:text
// in controller: model.addAttribute("newLineChar", '\n'); // in view ${#strings.replace(desc, newLineChar, '<br />')} If you use Thymeleaf + Spring (which means that Thymeleaf will use SpEL instead of OGNL), you can also use the SpEL T operator . Thus, you do not need to declare a newline variable in your controller, but remember that the new line separator in this case will differ on the different operating systems in which your application is running:
${#strings.replace(desc, T(System).getProperty('line.separator'), '<br />')} What I'm going to finally use is the combination above + Apache StringUtils, which defines a public static final String LF = "\n"; :
${#strings.replace(desc, T(org.apache.commons.lang3.StringUtils).LF, '<br />')} This can be done using a special dialect and an attribute processor to handle this without a lot of built-in SpEl or hacks.
Creating a custom attribute processor
public class NewlineAttrProcessor extends AbstractUnescapedTextChildModifierAttrProcessor { public NewlineAttrProcessor() { super("nl2br"); } @Override protected String getText(Arguments arguments, Element element, String attributeName) { final Configuration configuration = arguments.getConfiguration(); final IStandardExpressionParser parser = StandardExpressions.getExpressionParser(configuration); final String attributeValue = element.getAttributeValue(attributeName); final IStandardExpression expression = parser.parseExpression(configuration, arguments, attributeValue); final String value = (String)expression.execute(configuration, arguments); return StringUtils.replace(value, "\n", "<br />"); } @Override public int getPrecedence() { return 10000; } } You need to extend the AbstractUnescapedTextChildModifierAttrProcessor processor, otherwise you will get html entity tags for <br /> , and in fact you won't get a line break.
Create custom dialect
To implement a custom dialect, you will need a dialect class:
public class MyCustomDialect extends AbstractDialect { @Override public String getPrefix() { return "cd"; } @Override public Set<IProcessor> getProcessors() { final Set<IProcessor> processors = new HashSet<>(); processors.add(new NewlineAttrProcessor()); return processors; } } The return value of the getPrefix method is what you could use to call any custom processors you make. For example, Thimeleaf uses th . The user processor that we implemented above this is looking for nl2br , so you must use the cd:nl2br instead of th:text to call it.
Register a new dialect
In your main class, you just need to create @Bean , which will return a new instance of your dialect class.
@SpringBootApplication public class MyApplication { public static void main(String[] args) { SpringApplication.run(MyApplication.class, args); } @Bean public MyCustomDialect myCustomDialect() { return new MyCustomDialect(); } } Using a custom processor
Finally, in your template file you will have the following HTML tag:
<div cd:nl2br="${myObject.myField}">MY MULTILINE FIELD</div>
For a more detailed guide on implementing custom dialects, I recommend the Thymeleaf docs:
<th:block th:if="${text_value}"> <th:block th:each="str, stat : ${text_value.split('\r\n|\r|\n', -1)}"> <th:block th:text="${str}"/> <br th:if="${!stat.last}"/> </th:block> </th:block> found from here:
(Japanese) https://qiita.com/ushidatmhr/items/64102d81bfab12dcdf86