According to Thymeleaf docs
Fragments can include any th:* attributes. These attributes will be evaluated once the fragment is included into the target template (the one with the th:insert/th:replace attribute), and they will be able to reference any context variables defined in this target template.
My Fragment
<div th:fragment="link">
<a th:href="@{${url}}"><span th:inline="text">[[${text}]]</span></a>
</div>
This is how I include it.
<div th:replace="fragments/common :: link" th:with="url='www.google.com', text='Click Me'"></div>
The html i get
<a href="">
<span>null</span>
</a>
However the same works fine with th:include and gives me following HTML.
<a href="www.google.com">
<span>Click Me</span>
</a>
Why th:replace doesn't work while th:inlcude works fine?
NOTE: th:insert is out of scope because i am using Thymeleaf v2.1.5
The reason is that th:replace actually removes current tag so you lose every attribute you had there, but get all the attributes from fragment. And in your case this means that you never defined any th:with variable in the scope.th:include works the opposite way. You loose fragment tag, but keep everything defined in layout.
Consider this fragment:
<fragmenttag th:fragment="link" style="background-color: red">...</fragmenttag>
And layout:
<layouttag th:include="fragments/common :: link" style="font-size: 250%;"/>
<layouttag th:replace="fragments/common :: link" style="font-size: 250%;"/>
The result is:
<layouttag style="font-size: 250%;">Some Text</layouttag>
<fragmenttag style="background-color: red">Some Text</fragmenttag>
If you want to use th:replace, because you have some important attributes in fragment, you can define everything you need in some parent tag in layout.
<body th:with="url='www.google.com', text='Click Me'">
<div th:replace="fragments/common :: link" ></div>
</body>
You are referencing documentation in your post:
Fragments can include any th:* attributes. These attributes will be evaluated once the fragment is included into the target template (the one with the th:insert/th:replace attribute), and they will be able to reference any context variables defined in this target template.
And i don't see any contradiction here, because this part of the documentation is about th:* attributes inside a fragment.
Fragments (th:fragment part) can include any th:* attributes.
And in your question you are talking about loosing th:* attributes defined in target template. But anyway, this part is quite strait that you perform inclusion logic first
These attributes will be evaluated once the fragment is included
There is nothing here that lets you assume that you will get everything you defined in target template or fragments main tag, because both of them can be replaced depending on witch inclusion strategy you are going to use (th:insert/th:replace).
So you defined th:with="url='www.google.com', text='Click Me'" attribute, but it was never included in the end result template because you selected th:replace inclusion strategy, so th:with attribute was never evaluated and you got no url and text variables in scope. No contradiction here.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With