在Thymeleaf中渲染多行字符串

时间:2016-06-11 15:20:49

标签: thymeleaf

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>

2 个答案:

答案 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文档: