Search code examples
spring-bootthymeleaf

How to use th:replace in Thymeleaf TEXT Templates?


In a Thymeleaf TEXT template I want to use replace/insert to get a bit more flexibilty. I've tried to transpose HTML templating behavior to TEXT templating, but the first warning I get is that I can't use fragments in TEXT mode. I shall replace with complete files instead. That's really sad :(

So the best possible solution I think is to source out the more or less static parts like header and footer into separate files and then insert them into according templates. For now I have a text email template and a footer.

The email template looks like this:

[[#{email.greeting}]],

[[#{email.message}]]

[[#{email.signature}]]

------------------------------------------

[#th:block th:replace="~{includes/footer}"][/th:block]

The footer.txt is located inside the includes subfolder and looks like that:

[[#{email.footer.information}]]

For the sake of completeness here the according TemplateResolver as well:

private ITemplateResolver textTemplateResolver() {
    ClassLoaderTemplateResolver templateResolver = new ClassLoaderTemplateResolver();
    templateResolver.setResolvablePatterns(Collections.singleton("text/*"));
    templateResolver.setPrefix("/templates/mail/");
    templateResolver.setSuffix(".txt");
    templateResolver.setTemplateMode(TemplateMode.TEXT);
    templateResolver.setCharacterEncoding("UTF-8");

    return templateResolver;
}

Unfortunately, Thymeleaf doesn't process the replacement with the given file but replaces the block with the filename itself. In this case includes/footer is the textual replacement I can see in the processed outcome:

Hello you,

you look really great totay :)

Have fun and enjoy your round trip here on earth!

------------------------------------------

includes/footer

There are no errors, and Thymeleaf has no samples to follow in their documentation.

Has anybody any clue how to use replacing/inserting/fragmenting in Thymeleaf's textual templating mode?


Solution

  • Turns out that specifying the templates have to be done via an absolute path, meaning that you have to provide the full path, starting from the root path set in the template resolver:

    [#th:block th:replace="~{text/includes/footer}"][/th:block]
    

    If desired you can use a shortened self-closing version:

    [# th:replace="~{text/includes/footer}" /]