3

I would like to use the fragment functionality without the th:fragment (just using id). And in my code, the target fragment to be included is dynamically built from an iterator. The problem is creating the proper expression for the th:include to be rendered correctly. I've tried Concatenation, Preprocessing and Literal Substitution as per the tutorial, but without result - makes me think - is this allowed in th:include?

Fragment definition (It's in a file called Comments.html under my template, with my other templates).

<div id="LOW_SCORE_COMMENT">

It's been called this way

<div class="well" th:each="commentFragment : ${allComments}">
    <div th:include="'Comments :: #' + {__${commentFragment}__}">
    </div>          
</div>

allComments is an Iterator<String>, and the Strings retrieved are the fragment id's, so it should then build out the entire page. But I get this error

org.thymeleaf.exceptions.TemplateInputException: Error resolving template "'Comments", template might not exist or might not be accessible by any of the configured Template Resolvers

Note the single quote between " and Comments in the error message.

Do you have any suggestions?

EDIT: i tried this code

<div class="well" th:each="commentFragment,iterstat : ${allComments}"> <div th:include="${commentFragment.getValue()}"></div>

essentially changed allcomments to a TreeMap to solve ordering issues, but now the error is as follows:

org.thymeleaf.exceptions.TemplateInputException: Error resolving template "Comments :: #LOW_SCORE_COMMENT", template might not exist or might not be >accessible by any of the configured Template Resolvers

2
  • It seems that you misuse th:include. From the docs about th:include: The first part of the statement is a template name that we are referencing. The expression after double colon is a fragment selector (either fragment name or DOM selector). But in your code it's all mixed up. Commented Apr 7, 2016 at 11:52
  • if, as above, my fragment is <div id="LOW_SCORE_COMMENT"> and ${commentFragment} resolves to LOW_SCORE_COMMENT, shouldn't it be read as th:include= "Comments :: #LOW_SCORE_COMMENT" .could you explain what you mean by mixed up? I'm referring to the Using Thymeleaf guide Section 8 Referencing fragments without th:fragment Commented Apr 7, 2016 at 12:47

2 Answers 2

5

The problem is in missing preprocessing symbols __ - see the Thymeleaf documentation. The expression without __ is just replaced as is and passed to the resulting HTML page.

Preprocessing is an execution of the expressions done before the normal one that allows for modification of the expression that will eventually be executed.

Preprocessed expressions are exactly like normal ones, but appear surrounded by a double underscore symbol (like __${expression}__).

The correct working code is this:

<div class="well" th:each="commentFragment : ${allComments}">
    <div th:include="__${commentFragment.getValue()}__"></div>
Sign up to request clarification or add additional context in comments.

Comments

2

This should work using fragment expression as explained here

<div class="well" th:each="commentFragment : ${allComments}">
  <div th:include="~{Comments :: #__${commentFragment}__}">
  </div>          
 </div>

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.