web-dev-qa-db-ja.com

Thymeleaf:改行文字を<br>に置き換えます

フィールドがあります(<textarea name="desc" />)改行が含まれている可能性があり、それらを対応するHTMLに置き換えたい:<br />。これどうやってするの? Thymeleaf2.1.4.RELEASEを使用しています。

11
dominik

JSPのように 、単純で単純なものを使用することはできません

${#strings.replace(desc, '\n', '<br />')}

少なくとも2つの問題があります。

  • '\ n'は、基になる式言語(Spel MVCを使用している場合はSpEL)によって、単一の改行文字ではなく、 '\'と 'n'の2つの別個の文字で構成される文字列リテラルとして扱われます
  • thymeleafの基盤となるXMLパーサーが<および>を式内に配置できないため、例外がスローされます。

最初の問題で私が見つけた解決策は、コントローラーに改行文字を設定し、それをビューに渡すことです。

2番目の問題に対処するには、&lt;の代わりに<を使用し、&gt;の代わりに>を使用する必要があります。また、これはth:utextの代わりにth:textを使用することを意味することを忘れないでください

// in controller:
model.addAttribute("newLineChar", '\n');

// in view
${#strings.replace(desc, newLineChar, '&lt;br /&gt;')}

Thymeleaf + Springを使用している場合(つまり、ThymeleafはOGNLの代わりにSpELを使用します)、SpEL T operatorを使用することもできます。この方法では、コントローラーで改行変数を宣言する必要はありませんが、注意してください。この場合の改行区切り文字は、アプリが実行されているオペレーティングシステムによって異なります。

${#strings.replace(desc, T(System).getProperty('line.separator'), '&lt;br /&gt;')}

最後に使用するのは、上記とpublic static final String LF = "\n";を定義するApacheStringUtilsの組み合わせです。

${#strings.replace(desc, T(org.Apache.commons.lang3.StringUtils).LF, '&lt;br /&gt;')}
9
dominik

dominikで述べられているように、改行の\nは機能しません。ただし、&#10;は使用できます。

${#strings.replace(desc,'&#10;','&lt;br&gt;')}

または、コードインジェクションを防ぐためにエスケープする場合:

${#strings.replace(#strings.escapeXml(desc),'&#10;','&lt;br&gt;')}
14
holmis83

カスタムダイアレクトと属性プロセッサを使用してこれを実行し、多くのインライン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プロセッサを拡張する必要があります。そうしないと、<br />の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ドキュメントをお勧めします。

1
ashurexm
<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>

ここから見つかりました:
(日本語) https://qiita.com/ushidatmhr/items/64102d81bfab12dcdf86

0
lechat