Thymeleaf: заменить символы новой строки с
у меня есть поле (<textarea name="desc" />
), которые могут содержать новые строки, и я хочу заменить их на их HTML-аналог:<br />
. Как я могу это сделать? Я использую Thymeleaf 2.1.4.ОСВОБОЖДАТЬ.
3 ответов
как заявил Доминик, \n
для newline не работает. Однако, вы можете использовать
.
${#strings.replace(desc,' ','<br>')}
или с побегом, чтобы предотвратить инъекцию кода:
${#strings.replace(#strings.escapeXml(desc),' ','<br>')}
как в JSP, невозможно использовать простой и понятный
${#strings.replace(desc, '\n', '<br />')}
есть по крайней мере две проблемы:
- '\n 'обрабатывается базовым языком выражений (SpEL в моем случае, поскольку я использую Spring MVC) как строковый литерал, состоящий из двух отдельных символов:" \ " и "n", а не одного символа новой строки
- исключение выбрасывается, поскольку базовый XML-анализатор Thymeleaf не позволяет поместить
<
и>
внутри выражения
решение, которое я нашел для первой проблемы, - установить символ новой строки в контроллере и передать его на просмотр.
для решения второй проблемы нужно использовать <
вместо <
и >
вместо >
. Также помните, что это подразумевает использование th:utext
вместо th:text
// in controller:
model.addAttribute("newLineChar", '\n');
// in view
${#strings.replace(desc, newLineChar, '<br />')}
если вы используете Thymeleaf + Spring (что означает, что Thymeleaf будет использовать SpEL вместо OGNL), вы можете также используйте SpEL T operator
.Таким образом, вам не нужно объявлять переменную newline в контроллере, но имейте в виду, что разделитель newline в этом случае будет отличаться в разных операционных системах, на которых работает ваше приложение:
${#strings.replace(desc, T(System).getProperty('line.separator'), '<br />')}
то, что я собираюсь наконец использовать, - это комбинация вышеуказанных + Apache StringUtils, которая определяет public static final String LF = "\n";
:
${#strings.replace(desc, T(org.apache.commons.lang3.StringUtils).LF, '<br />')}
это можно сделать с помощью пользовательского процессора диалекта и атрибута, чтобы справиться с этим без большого количества встроенных SpEl или хаков.
создание пользовательского процессора атрибутов
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;
}
}
вы должны продлить AbstractUnescapedTextChildModifierAttrProcessor
процессор, иначе вы получите теги сущности html для <br />
и вы на самом деле не сделать разрыв строки.
создание пользовательского диалект
для реализации пользовательского диалекта вы нужен класс диалекта, например:
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;
}
}
на getPrefix
возвращаемое значение метода - это то, что вы использовали бы для вызова любых пользовательских процессоров, которые вы делаете. Например, Thymeleaf использует th
. Пользовательский процессор, который мы реализовали выше, ищет nl2br
поэтому, чтобы назвать его, вы бы использовали вместо th:text
.
регистрация нового диалекта
в вашем основном классе вам просто нужно создать @Bean
что вернется новый экземпляр класса dialect.
@SpringBootApplication
public class MyApplication {
public static void main(String[] args) {
SpringApplication.run(MyApplication.class, args);
}
@Bean
public MyCustomDialect myCustomDialect()
{
return new MyCustomDialect();
}
}
использование пользовательского процессора
наконец, в вашем файле шаблона у вас будет такой HTML-тег:
<div cd:nl2br="${myObject.myField}">MY MULTILINE FIELD</div>
для более тщательного руководства по внедрению пользовательских диалектов я рекомендую документы Thymeleaf: