Thymeleaf 3.0教程:8 模板布局(三)
8.3灵活的布局:不仅仅是片段插入
感谢片段表达式,我们可以为片段指定参数,这些片段不是文本、数字、bean对象……而是标记片段。
这允许我们以一种方式创建片段,使得它们可以用来自调用模板的标记来丰富,从而产生非常灵活的模板布局机制。
请注意下面片段中title和links变量的使用:
<head th:fragment="common_header(title,links)"> <title th:replace="${title}">The awesome application</title> <!-- Common styles and scripts --> <link rel="stylesheet" type="text/css" media="all" th:href="@{/css/awesomeapp.css}"> <link rel="shortcut icon" th:href="@{/images/favicon.ico}"> <script type="text/javascript" th:src="@{/sh/scripts/codebase.js}"></script> <!--/* Per-page placeholder for additional links */--> <th:block th:replace="${links}" /> </head>
我们现在可以称这个片段为:
<head th:replace="base :: common_header(~{::title},~{::link})"> <title>Awesome - Main</title> <link rel="stylesheet" th:href="@{/css/bootstrap.min.css}"> <link rel="stylesheet" th:href="@{/themes/smoothness/jquery-ui.css}"> </head>
结果将使用我们调用模板中的实际<title>和<link> 标记作为title和link变量的值,导致我们的片段在插入过程中被定制:
<head> <title>Awesome - Main</title> <!-- Common styles and scripts --> <link rel="stylesheet" type="text/css" media="all" href="/awe/css/awesomeapp.css"> <link rel="shortcut icon" href="/awe/images/favicon.ico"> <script type="text/javascript" src="/awe/sh/scripts/codebase.js"></script> <link rel="stylesheet" href="/awe/css/bootstrap.min.css"> <link rel="stylesheet" href="/awe/themes/smoothness/jquery-ui.css"> </head>
使用空片段
一个特殊的片段表达式,即空片段(~{}),可以用于指定无标记。使用前面的例子:
<head th:replace="base :: common_header(~{::title},~{})"> <title>Awesome - Main</title> </head>
注意片段(links)的第二个参数是如何设置为空片段的,因此不会为< th:block th:replace="${links}" />块写入任何内容:
<head> <title>Awesome - Main</title> <!-- Common styles and scripts --> <link rel="stylesheet" type="text/css" media="all" href="/awe/css/awesomeapp.css"> <link rel="shortcut icon" href="/awe/images/favicon.ico"> <script type="text/javascript" src="/awe/sh/scripts/codebase.js"></script> </head>
使用no-operation令牌
如果我们只想让片段使用其当前标记作为默认值,则no-op也可以用作片段的参数。同样,使用common_header示例:
<head th:replace="base :: common_header(_,~{::link})"> <title>Awesome - Main</title> <link rel="stylesheet" th:href="@{/css/bootstrap.min.css}"> <link rel="stylesheet" th:href="@{/themes/smoothness/jquery-ui.css}"> </head>
查看标题参数(common_header片段的第一个参数)如何设置为no-op (_),这将导致片段的这一部分根本不被执行(title = no-operation):
<title th:replace="${title}">The awesome application</title>
结果是:
<head> <title>The awesome application</title> <!-- Common styles and scripts --> <link rel="stylesheet" type="text/css" media="all" href="/awe/css/awesomeapp.css"> <link rel="shortcut icon" href="/awe/images/favicon.ico"> <script type="text/javascript" src="/awe/sh/scripts/codebase.js"></script> <link rel="stylesheet" href="/awe/css/bootstrap.min.css"> <link rel="stylesheet" href="/awe/themes/smoothness/jquery-ui.css"> </head>
片段的高级条件插入
emtpy片段和无操作令牌的可用性允许我们以非常简单和优雅的方式执行片段的条件插入。
例如,我们可以这样做,以便只有当用户是管理员时才插入我们的公共::adminhead片段,如果不是,则不插入任何内容(emtpy片段):
<div th:insert="${user.isAdmin()} ? ~{common :: adminhead} : ~{}">...</div>
此外,我们可以使用no-operation标记,以便仅在满足指定条件时插入片段,但如果不满足条件,则保留标记而不做修改:
<div th:insert="${user.isAdmin()} ? ~{common :: adminhead} : _"> Welcome [[${user.name}]], click <a th:href="@{/support}">here</a> for help-desk support. </div>
此外,如果我们已经配置了模板解析器来检查模板资源的存在-通过它们的检查存在标志——我们可以在默认操作中使用片段本身的存在作为条件:
<!-- The body of the <div> will be used if the "common :: salutation" fragment --> <!-- does not exist (or is empty). --> <div th:insert="~{common :: salutation} ?: _"> Welcome [[${user.name}]], click <a th:href="@{/support}">here</a> for help-desk support. </div>