Thymeleaf 教程

灵活的布局:不仅仅是插入片段

由于片段表达式,我们可以为片段指定参数,这些片段不是文本、数字、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-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(_,~{::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 操作标识(“_”)。

说说我的看法
全部评论(
没有评论
关于
本网站专注于 Java、数据库(MySQL、Oracle)、Linux、软件架构及大数据等多领域技术知识分享。涵盖丰富的原创与精选技术文章,助力技术传播与交流。无论是技术新手渴望入门,还是资深开发者寻求进阶,这里都能为您提供深度见解与实用经验,让复杂编码变得轻松易懂,携手共赴技术提升新高度。如有侵权,请来信告知:hxstrive@outlook.com
公众号