由于片段表达式,我们可以为片段指定参数,这些片段不是文本、数字、bean 对象......而是标记的片段。
这允许我们以这样的方式创建片段,即可以使用来自调用模板的标记来丰富片段,从而形成非常灵活的模板布局机制。
注意,下面片段中 title 和 links 变量的用法:
<head th:fragment="common_header(title,links)"> <title th:replace="${title}">The awesome application</title> <!-- 通用样式和脚本 --> <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> <!--/* 每个页面定制样式的链接占位符 */--> <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> <!-- 通用样式和脚本 --> <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> ...
注意,上面代码中 ~{::title} 和 ~{::link} 片段表达式分别通过标签名匹配了片段。
一个特殊的片段表达式,空片段(~{}),可以用于指定任何标记。使用前面的示例:
<head th:replace="base :: common_header(~{::title},~{})"> <title>Awesome - Main</title> </head> ...
注意,片段的第二个参数(links)被设置为空片段,因此不会为 <th:block th:replace=“${links}”/> 块写入任何内容:
... <head> <title>Awesome - Main</title> <!-- 通用样式和脚本 --> <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-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(_,~{::link}) 指定的第一个参数 “_” 表示 no-op,这会导致片段的这一部分根本无法执行,即什么也不做,直接将当前 <title> 标签的值 “The awesome application” 作为默认值,不进行任何形式的替换操作:
<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> ...
空片段和 no-operation 的可用性允许我们以非常简单和优雅的方式执行片段的条件插入。
例如,我们可以这样做,以便仅在用户是管理员时插入 common::adminhead 片段,如果不是,则不插入任何内容(空片段):
... <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> ...
此外,如果我们已经配置了我们的模板解析器来检查模板资源的存在,通过它们的 checkExistence 标志,我们可以使用片段本身的存在作为默认操作的条件:
... <!-- 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> ...
上面代码中,如果 common 下没有 salutation 片段,则使用 no-operation 操作标识(“_”)。