在this question的变体中,我想使用Thymeleaf将多行字符串渲染到HTML表格中。
也就是说,如何转换像
这样的字符串Cronut fixie tousled migas.
Whatever neutra offal fanny pack, photo booth kitsch bespoke hammock swag.
Keffiyeh yuccie meditation mustache cornhole paleo.
到
<table class="table">
<tr>
<td>Cronut fixie tousled migas.</td>
</tr>
<tr>
<td>Whatever neutra offal fanny pack, photo booth kitsch bespoke hammock swag.</td>
</tr>
<tr>
<td>Keffiyeh yuccie meditation mustache cornhole paleo.</td>
</tr>
</table>
答案 0 :(得分:1)
使用模型变量model.text
中包含的字符串,可能的解决方案(使用Spring方言时)是这样的:
<table>
<tr th:each="line : ${#strings.arraySplit(model.text, T(org.apache.commons.lang3.StringUtils).LF)}">
<td th:text="${line}"></td>
</tr>
</table>
使用T(org.apache.commons.lang3.StringUtils).LF
而非\n
的原因是(也在this answer中描述)SpEL转义反斜杠,然后决定拆分&#39; n&# 39; -letters而不是换行符。
当然,还应该考虑直接在控制器中将字符串拆分为数组的解决方案(即使用普通Java)。
答案 1 :(得分:1)
我最初在之前的SO question上发布了这个答案,但这个答案似乎也出现了。我已将其修改为输出表而不仅仅是换行符。
可以使用自定义方言和属性处理器执行此操作,以便在没有大量内联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);
final String[] lines = StringUtils.split(value, "\n");
return "<table><td>" + StringUtils.join(lines, "</td><td>") + "</td></table>";
}
@Override
public int getPrecedence()
{
return 10000;
}
}
您必须扩展AbstractUnescapedTextChildModifierAttrProcessor
处理器,否则您将获得<table>...</table>
的html实体标记,而您实际上并不会获得HTML。
制作自定义方言
要实现自定义方言,您需要一个类似的方言类:
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
,因此要调用它,您将使用cd:nl2br
属性而不是th:text
。
注册新方言
在您的主课程中,您只需要创建一个@Bean
,它将返回您的方言类的新实例。
@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文档: