thymeleaf 公共模板布局

590

片段引入

在 Thymeleaf 中,我们可以使用以下 3 个属性,将公共页面片段引入到当前页面中。

  • th:insert:将代码块片段整个插入到使用了 th:insert 属性的 HTML 标签中;
  • th:replace:将代码块片段整个替换使用了 th:replace 属性的 HTML 标签中;
  • th:include:将代码块片段包含的内容插入到使用了 th:include 属性的 HTML 标签中。

使用上 3 个属性引入页面片段,都可以通过以下 2 种方式实现。

  • ~{templatename::#selector}:模板名::选择器
  • ~{templatename::fragmentname}:模板名::片段名

通常情况下,~{} 可以省略

实例

  1. 在页面 fragment.html 中引入 commons.html 中声明的页面片段,可以通过以下方式实现
<!--th:insert 片段名引入-->
<div th:insert="commons::fragment-name">  </div>

<!--th:insert id 选择器引入-->
<div th:insert="commons::#fragment-id">  </div>
------------------------------------------------
<!--th:replace 片段名引入-->
<div th:replace="commons::fragment-name">  </div>

<!--th:replace id 选择器引入-->
<div th:replace="commons::#fragment-id">  </div>

------------------------------------------------
<!--th:include 片段名引入-->
<div th:include="commons::fragment-name">  </div>

<!--th:include id 选择器引入-->
<div th:include="commons::#fragment-id">  </div>
  1. 效果如下
<!--th:insert 片段名引入-->
<div>
    <div id="fragment-id"> 
        <span>公共页面片段</span> 
    </div>
</div>
<!--th:insert id 选择器引入-->
<div>
    <div id="fragment-id"> 
        <span>公共页面片段</span> 
    </div>
</div>
<!--th:replace 片段名引入-->
<div id="fragment-id"> 
    <span>公共页面片段</span>
</div>
<!--th:replace id 选择器引入-->
<div id="fragment-id"> 
    <span>公共页面片段</span>
</div>
<!--th:include 片段名引入-->
<div> 
    <span>公共页面片段</span>
</div>
<!--th:include id 选择器引入-->
<div> 
    <span>公共页面片段</span>
</div>

可参数化片段签名

为了为模板片段创建一个更像函数的th:fragment机制,定义的片段可以指定一组参数:

<div th:fragment="frag (onevar,twovar)">
    <p th:text="${onevar} + ' - ' + ${twovar}">...</p>
</div>

这需要使用这两种语法之一来从th:insertor调用片段th:replace

<div th:replace="::frag (${value1},${value2})">...</div>
<div th:replace="::frag (onevar=${value1},twovar=${value2})">...</div>

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

多亏了片段表达式,我们可以为片段指定参数,这些片段不是文本、数字、bean 对象……而是标记片段。

这使我们能够以一种方式创建我们的片段,以便可以使用来自调用模板的标记来丰富它们,从而产生非常灵活的模板布局机制

请注意以下片段中的titlelinks变量的使用:

<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``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>

  <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>
...

更多详解参考官方文档:
https://www.thymeleaf.org/doc/tutorials/3.0/usingthymeleaf.html