使用 "this :: content" 或“:: content”包含来自同一 thymeleaf 模板的片段未按预期工作
Include a fragment from the same thymeleaf template using "this :: content" or ":: content" not working as expected
我正在包含来自同一模板文件的模板片段。文档的“8.1 Including template fragments - Defining and referencing fragments”部分指出:
"::domselector" or "this::domselector" Includes a fragment from the
same template.
如果我没理解错的话,我应该可以引用片段如下:th:include="this :: contentB"
or th:include=":: contentB"
但只有完整参考 th:include="test-fragment :: contentB"
对我有用。
这是示例代码:
HomeController.java
@Controller
class HomeController {
@RequestMapping({ "/", "index", "home" })
String index(Model model) {
return "test";
}
}
test.html
<!DOCTYPE html>
<html>
<head></head>
<body>
<ul th:replace="test-fragment :: contentA" />
</body>
</html>
测试-fragment.html
<!DOCTYPE html>
<html>
<head></head>
<body>
<ul th:fragment="contentA">
<li th:each="idx : ${#numbers.sequence(1,4)}" th:switch="${idx}">
<th:block th:case="1"
th:include="test-fragment :: contentB"
th:with="strVar = 'One'"/>
<th:block th:case="2"
th:include="this :: contentB"
th:with="strVar = 'Two'"/>
<th:block th:case="3"
th:include=" :: contentB"
th:with="strVar = 'Three'"/>
<th:block th:case="*"
th:include="/test-fragment :: contentB"
th:with="strVar = 'Other'"/>
</li>
</ul>
<span th:fragment="contentB">
<span th:text="|value: ${strVar}|" />
</span>
</body>
</html>
输出为:
<!DOCTYPE html>
<html>
<head></head>
<body>
<ul>
<li><span>value: One</span></li>
<li></li>
<li></li>
<li><span>value: Other</span></li>
</ul>
</body>
</html>
案例 2 和案例 3 缺失。我究竟做错了什么?
我正在使用 Spring Boot 1.3.2.RELEASE
进行测试
编辑:
我做了一个小测试项目来重现这个问题,可以在这里找到:https://github.com/t-cst/thymeleaf-springboot-test
编辑:
经过一些调试,我发现当片段选择器是"this :: contentB"
或" :: contentB"
时,模板名称被解析为test
而不是test-framgent
。这是在以下位置完成的:
StandardFragment#extractFragment:189
来自 thymeleaf-2.1.4.RELEASE:
/* 186 */ String targetTemplateName = getTemplateName();
if (targetTemplateName == null) {
if (context != null && context instanceof Arguments) {
targetTemplateName = ((Arguments)context).getTemplateName();
/* 190 */ } else {
throw new TemplateProcessingException(
"In order to extract fragment from current template (templateName == null), processing context " +
"must be a non-null instance of the Arguments class (but is: " +
(context == null? null : context.getClass().getName()) + ")");
/* 195 */ }
}
但我仍然不知道为什么在我的测试中会出现这种情况。
编辑:
我也在thymeleaf forum. Maybe it's a bug. I've opened an issue问过。
万一有人遇到同样的问题,这在 thymeleaf 2.1.4.RELEASE
版本中是不可能的,但会在下一个版本中 3.0
全面的解释可以在这里找到 issue comment。
我正在包含来自同一模板文件的模板片段。文档的“8.1 Including template fragments - Defining and referencing fragments”部分指出:
"::domselector" or "this::domselector" Includes a fragment from the same template.
如果我没理解错的话,我应该可以引用片段如下:th:include="this :: contentB"
or th:include=":: contentB"
但只有完整参考 th:include="test-fragment :: contentB"
对我有用。
这是示例代码:
HomeController.java
@Controller
class HomeController {
@RequestMapping({ "/", "index", "home" })
String index(Model model) {
return "test";
}
}
test.html
<!DOCTYPE html>
<html>
<head></head>
<body>
<ul th:replace="test-fragment :: contentA" />
</body>
</html>
测试-fragment.html
<!DOCTYPE html>
<html>
<head></head>
<body>
<ul th:fragment="contentA">
<li th:each="idx : ${#numbers.sequence(1,4)}" th:switch="${idx}">
<th:block th:case="1"
th:include="test-fragment :: contentB"
th:with="strVar = 'One'"/>
<th:block th:case="2"
th:include="this :: contentB"
th:with="strVar = 'Two'"/>
<th:block th:case="3"
th:include=" :: contentB"
th:with="strVar = 'Three'"/>
<th:block th:case="*"
th:include="/test-fragment :: contentB"
th:with="strVar = 'Other'"/>
</li>
</ul>
<span th:fragment="contentB">
<span th:text="|value: ${strVar}|" />
</span>
</body>
</html>
输出为:
<!DOCTYPE html>
<html>
<head></head>
<body>
<ul>
<li><span>value: One</span></li>
<li></li>
<li></li>
<li><span>value: Other</span></li>
</ul>
</body>
</html>
案例 2 和案例 3 缺失。我究竟做错了什么?
我正在使用 Spring Boot 1.3.2.RELEASE
进行测试编辑:
我做了一个小测试项目来重现这个问题,可以在这里找到:https://github.com/t-cst/thymeleaf-springboot-test
编辑:
经过一些调试,我发现当片段选择器是"this :: contentB"
或" :: contentB"
时,模板名称被解析为test
而不是test-framgent
。这是在以下位置完成的:
StandardFragment#extractFragment:189
来自 thymeleaf-2.1.4.RELEASE:
/* 186 */ String targetTemplateName = getTemplateName();
if (targetTemplateName == null) {
if (context != null && context instanceof Arguments) {
targetTemplateName = ((Arguments)context).getTemplateName();
/* 190 */ } else {
throw new TemplateProcessingException(
"In order to extract fragment from current template (templateName == null), processing context " +
"must be a non-null instance of the Arguments class (but is: " +
(context == null? null : context.getClass().getName()) + ")");
/* 195 */ }
}
但我仍然不知道为什么在我的测试中会出现这种情况。
编辑:
我也在thymeleaf forum. Maybe it's a bug. I've opened an issue问过。
万一有人遇到同样的问题,这在 thymeleaf 2.1.4.RELEASE
版本中是不可能的,但会在下一个版本中 3.0
全面的解释可以在这里找到 issue comment。