Thymeleaf +弹簧动态更换

时间:2015-08-01 11:25:41

标签: spring thymeleaf

是否可以在Thymeleaf中创建动态替换?

我有以下控制器:

@Controller
public class LoginController {

    @RequestMapping("/login")
    public String getLogin(Model model){
        model.addAttribute("template","login");
        return "index";
    }
}

以下观点:

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org" >
<head></head>
<body>

<div th:replace="fragments/${template} :: ${template}"></div>

</body>
</html>

我收到以下错误:

Error resolving template "fragments/${template}", template might not exist or might not be accessible by any of the configured Template Resolvers

更新

我试图预处理我的变量:

<div th:replace="fragments/${__#{${template}}__} :: ${__#{${template}}__}"></div>

现在${template}login取代我现在有以下错误:

Exception evaluating SpringEL expression: "??login_en_US??"

6 个答案:

答案 0 :(得分:10)

虽然Joe Essey的解决方案也正常运行,但我使用以下代码解决了这个问题:

<div th:replace="@{'fragments/' + ${template}} :: ${template}"></div>

答案 1 :(得分:4)

我认为在thymeleaf中管理此行为的适当方法是使用layout:fragment标记。如果我错了,请纠正我。这是我的布局页面的简单示例,以及“动态”加载的登录页面:

的layout.html

<html xmlns:layout="http://www.w3.org/1999/xhtml" xmlns:th="http://www.w3.org/1999/xhtml">
<head>
    <title layout:title-pattern="$DECORATOR_TITLE - $CONTENT_TITLE">Layout</title>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
    <meta http-equiv="X-UA-Compatible" content="IE=Edge"/>
</head>
<body>
<div>
    <div class="app-container">
        <div th:fragment="content">
        </div>
    </div>
</div>
<div th:fragment="script"></div>
</body>
</html>

然后,当登录加载时,它会将h th:fragment div替换为html视图中与控制器方法返回的字符串相关联的div,在本例中为login.html:

<html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org"
      xmlns:layout="http://www.w3.org/1999/xhtml"
      layout:decorator="layout">
<head>
    <title>Login</title>
</head>
<body>
<div th:fragment="content">
    <form th:action="@{/login}" method="post">
        <div><label> User Name : <input type="text" name="username"/> </label></div>
        <div><label> Password: <input type="password" name="password"/> </label></div>
        <div><input type="submit" value="Sign In"/></div>
    </form>
</div>
</body>
</html>

现在,如果你想有条件地加载另一个片段,我采取的方法是使用th:if case添加替换标记。以下是基于当前用户的属性显示不同问题的表单示例:

<div th:if="${foo.type)} == 'type_1'">
    <div th:replace="fragments/custom-questions :: type-1-checkboxes"></div>
</div>
<div th:if="${foo.type} == 'type_2'">
    <div th:replace="fragments/custom-questions :: type-2-checkboxes"></div>
</div>

然后从custom-questions.html文件加载相关的div:

<div th:fragment="type-1-checkboxes">
  //stuff
</div>

<div th:fragment="type-2-checkboxes">
  //stuff
</div>

答案 2 :(得分:2)

我正在遇到这个问题(这是我第一次使用百里香/春天)。这就是为我解决的问题:

<div class="col-md-12" th:include="__${template}__ :: body" ...

答案 3 :(得分:1)

在Thymeleaf 3.0中,以下解决方案对我有效:

<div th:replace="('fragments/' + ${template}) :: (${template})">

(但是,请注意,我将其与片段的固定名称和模板的动态名称一起使用,因此 :: (${template})周围的括号可能是可选的。)

该解决方案的灵感来自https://www.thymeleaf.org/doc/tutorials/3.0/usingthymeleaf.html#fragment-specification-syntax

中有关Thymeleaf的文档

以上示例中的templatename和选择器都可以是功能齐全的表达式(甚至是条件表达式!),例如: <div th:insert="footer :: (${user.isAdmin}? #{footer.admin} : #{footer.normaluser})"></div> 再次注意周围的〜{...}信封在th:insert / th:replace

中是可选的

答案 4 :(得分:0)

该问题并未说明登录指的是什么。 登录名是一个单独的页面还是另一个html页面中定义的片段。 因为使用上面的只是导致以下错误 “模板可能不存在,或者任何已配置的模板解析器都无法访问”。

答案 5 :(得分:0)

<div th:insert=“${subpage}::fragementName”> 

只需更改子页面名称,您就会在胸腺中动态行为