Thymeleafでフラグメントを扱う

1概要

このチュートリアルでは、Thymeleafフラグメントを利用してサイトの共通部分を再利用する方法を説明します。非常に単純なSpring MVCプロジェクトを設定した後は、ビューに焦点を当てます。

Thymeleafを初めて使用する場合は、このサイトの この紹介 、および この3.0についての記事 のような他の記事を確認できます。]エンジンの。

2 Mavenの依存関係

Thymeleafを有効にするには、いくつかの依存関係が必要です。

<dependency>
    <groupId>org.thymeleaf</groupId>
    <artifactId>thymeleaf</artifactId>
    <version>3.0.9.RELEASE</version>
</dependency>
<dependency>
    <groupId>org.thymeleaf</groupId>
    <artifactId>thymeleaf-spring5</artifactId>
    <version>3.0.9.RELEASE</version>
</dependency>

thymeleaf およびhttps://の最新バージョンsearch.maven.org/classic/#search%7Cgav%7C1%7Cg%3A%22org.thymeleaf%22%20AND%20a%3A%22thymeleaf-spring5%22[thymeleaf-spring5]はMaven Centralで見つけることができます。

3春のプロジェクト

3.1. Spring MVCの設定

Thymeleafを有効にしてテンプレートサフィックスを設定するには、ビューリゾルバとテンプレートリゾルバを使ってMVCを設定する必要があります。

また、いくつかの静的リソース用にディレクトリを設定します。

@Bean
public ViewResolver htmlViewResolver() {
    ThymeleafViewResolver resolver = new ThymeleafViewResolver();
    resolver.setTemplateEngine(templateEngine(htmlTemplateResolver()));
    resolver.setContentType("text/html");
    resolver.setCharacterEncoding("UTF-8");
    resolver.setViewNames(ArrayUtil.array("** .html"));
    return resolver;
}

private ITemplateResolver htmlTemplateResolver() {
    SpringResourceTemplateResolver resolver
      = new SpringResourceTemplateResolver();
    resolver.setApplicationContext(applicationContext);
    resolver.setPrefix("/WEB-INF/views/");
    resolver.setCacheable(false);
    resolver.setTemplateMode(TemplateMode.HTML);
    return resolver;
}

@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
    registry.addResourceHandler("/resources/** ** ", "/css/** ** ")
      .addResourceLocations("/WEB-INF/resources/", "/WEB-INF/css/");
}

Spring Bootを使用している場合は、独自のカスタマイズを適用する必要がない限り、この設定は不要な場合があります。

3.2. コントローラー

この場合、コントローラーはビューを見るための単なる手段です。各ビューは、異なるフラグメント使用シナリオを示しています。

最後のものは、モデルに渡されてビューに表示されるデータをロードします。

@Controller
public class FragmentsController {

    @GetMapping("/fragments")
    public String getHome() {
        return "fragments.html";
    }

    @GetMapping("/markup")
    public String markupPage() {
        return "markup.html";
    }

    @GetMapping("/params")
    public String paramsPage() {
        return "params.html";
    }

    @GetMapping("/other")
    public String otherPage(Model model) {
        model.addAttribute("data", StudentUtils.buildStudents());
        return "other.html";
    }
}
  • ビュー名には、リゾルバを設定する方法のため、 “。html” 接尾辞を含める必要があることに注意してください。フラグメント名を参照するときは、接尾辞も指定します。

4ビュー

4.1. 単純なフラグメントインクルージョン

まず第一に、私たちは私たちのページで共通の部分を再利用するつもりです。

これらの部分は、独立したファイルまたは共通のページのいずれかでフラグメントとして定義できます。このプロジェクトでは、これらの再利用可能部分は fragments という名前のフォルダーに定義されています。

フラグメントのコンテンツを含めるには、3つの基本的な方法があります。

  • insert - タグの中にコンテンツを挿入する

  • replace - は現在のタグを定義しているタグで置き換え

断片 include - ** これは非推奨ですが、それでもレガシーに現れるかもしれません

コード

次の例 fragments.html、 は、3つの方法すべての使用方法を示しています。

このThymeleafテンプレートは、文書の頭と本文にフラグメントを追加します。

<!DOCTYPE HTML>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<title>Thymeleaf Fragments: home</title>
<!--/** /<th:block th:include="fragments/general.html :: headerfiles">
        </th:block>/** /-->
</head>
<body>
    <header th:insert="fragments/general.html :: header"> </header>
    <p>Go to the next page to see fragments in action</p>
    <div th:replace="fragments/general.html :: footer"></div>
</body>
</html>
  • それでは、いくつかのフラグメントを含むページを見てみましょう** それは general.html と呼ばれ、フラグメントとして定義されたいくつかの部分を使用する準備ができているページ全体のようなものです。

<!DOCTYPE HTML>
<html xmlns:th="http://www.thymeleaf.org">
<head th:fragment="headerfiles">
<meta charset="UTF-8"/>
<link th:href="@{/css/styles.css}" rel="stylesheet">
</head>
<body>
    <div th:fragment="header">
        <h1>Thymeleaf Fragments sample</h1>
    </div>
    <p>Go to the next page to see fragments in action</p>
    <aside>
        <div>This is a sidebar</div>
    </aside>
    <div class="another">This is another sidebar</div>
    <footer th:fragment="footer">
        <a th:href="@{/fragments}">Fragments Index</a> |
        <a th:href="@{/markup}">Markup inclussion</a> |
        <a th:href="@{/params}">Fragment params</a> |
        <a th:href="@{/other}">Other</a>
    </footer>
</body>
</html>

<head> セクションにはスタイルシートが含まれていますが、Bootstrap、jQuery、Foundationなどの他のツールを直接またはWebjarsを使用して適用できます。

このテンプレートの再利用可能なタグはすべて属性 th:fragment を持ちますが、次にページの他の部分を含める方法について説明します。

レンダリングとフラグメントを含めると、返されるコンテンツは次のようになります。

<!DOCTYPE HTML>
<html>
<head>
<title>Thymeleaf Fragments: home</title>
<meta charset="UTF-8"/>
<link href="/spring-thymeleaf/css/styles.css" rel="stylesheet">
</head>
<body>
    <header>
        <div>
            <h1>Thymeleaf Fragments sample</h1>
        </div>
    </header>
    <p>Go to the next page to see fragments in action</p>
    <footer>
        <a href="/spring-thymeleaf/fragments">Fragments Index</a> |
        <a href="/spring-thymeleaf/markup">Markup inclussion</a> |
        <a href="/spring-thymeleaf/params">Fragment params</a> |
        <a href="/spring-thymeleaf/other">Other</a>
    </footer>
</body>
</html>

4.2. フラグメントのマークアップセレクター

Thymeleaf Fragmentsの優れた点の1つは、クラス、ID、またはタグを使用して、単純なセレクタを使用するだけで** テンプレートの任意の部分を取得できることです。

たとえば、このページには general.html ファイルの一部のコンポーネントが含まれています。

<body>
    <header th:insert="fragments/general.html :: header"> </header>
    <div th:replace="fragments/general.html :: aside"></div>
    <div th:replace="fragments/general.html :: div.another"></div>
    <div th:replace="fragments/general.html :: footer"></div>
</body>

4.3. パラメータ化されたフラグメント

特定の部分を変更するために、 フラグメントにパラメータを渡すことができます。そのためには、フラグメントを関数呼び出しとして定義する必要があります。ここで、パラメーターのリストを宣言する必要があります。

この例では、ジェネリックフォームフィールドのフラグメントを定義します。

<div th:fragment="formField (field, value, size)">
    <div>
        <label th:for="${#strings.toLowerCase(field)}"> <span
            th:text="${field}">Field</span>
        </label>
    </div>
    <div>
        <input type="text" th:id="${#strings.toLowerCase(field)}"
            th:name="${#strings.toLowerCase(field)}" th:value="${value}"
            th:size="${size}">
    </div>
</div>

そして、ここに私たちがそれにパラメータを渡すところでその断片の簡単な使い方があります:

<body>
    <header th:insert="fragments/general.html :: header"> </header>
    <div th:replace="fragments/forms.html
      :: formField(field='Name', value='John Doe',size='40')">
    </div>
    <div th:replace="fragments/general.html :: footer"></div>
</body>

そして、これは返されるフィールドがどのように見えるかです:

<div>
    <div>
        <label for="name"> <span>Name</span>
        </label>
    </div>
    <div>
        <input type="text" id="name"
        name="name" value="John Doe"
        size="40">
    </div>
</div>

4.4. フラグメント包含式

Thymeleafフラグメントは、フラグメントを含めるかどうかを判断するための** 条件式のサポートなど、その他の興味深いオプションを提供します。

Thymeleafが提供する式(セキュリティ、文字列、コレクションなど)のいずれかと一緒に Elvis 演算子を使用すると、さまざまなフラグメントを読み込むことができます。

たとえば、特定の条件に応じて表示するコンテンツを使用してこのフラグメントを定義できます。これは、さまざまな種類のブロックを含むファイルです。

<div th:fragment="dataPresent">Data received</div>
<div th:fragment="noData">No data</div>

そしてこれが、式を使ってそれらをロードする方法です。

<div
    th:replace="${#lists.size(data) > 0} ?
        ~{fragments/menus.html :: dataPresent} :
        ~{fragments/menus.html :: noData}">
</div>

Thymeleaf式の詳細については、記事リンク/spring-thymeleaf-3-expressions[こちら]を参照してください。

4.5. 柔軟なレイアウト

次の例は、データを含むテーブルをレンダリングするための、フラグメントの他の2つの興味深い使い方も示しています。これは再利用可能なテーブルフラグメントで、2つの重要な部分があります。変更可能なテーブルヘッダと、データがレンダリングされる本体です。

<table>
    <thead th:fragment="fields(theadFields)">
        <tr th:replace="${theadFields}">
        </tr>
    </thead>
    <tbody th:fragment="tableBody(tableData)">
        <tr th:each="row: ${tableData}">
            <td th:text="${row.id}">0</td>
            <td th:text="${row.name}">Name</td>
        </tr>
    </tbody>
    <tfoot>
    </tfoot>
</table>

このテーブルを使いたいときは、 fields 関数を使って独自のテーブルヘッダを渡すことができます。ヘッダはクラス myFields で参照されます。テーブル本体は tableBody 関数にパラメータとしてデータを渡すことによってロードされます。

<body>
    <header th:replace="fragments/general.html :: header"> </header>
    <table>
        <thead th:replace="fragments/tables.html
              :: fields(~{ :: .myFields})">
            <tr class="myFields">

                <th>Id</th>
                <th>Name</th>
            </tr>
        </thead>
        <div th:replace="fragments/tables.html
          :: tableBody(tableData=${data})">
        </div>
    </table>
    <div th:replace="fragments/general.html :: footer"></div>
</body>

これが最終ページの外観です。

<body>
    <div>
        <h1>Thymeleaf Fragments sample</h1>
    </div>
    <div>Data received</div>
    <table>
        <thead>
            <tr class="myFields">

                <th>Id</th>
                <th>Name</th>
            </tr>
        </thead>
        <tbody>
            <tr>
                <td>1001</td>
                <td>John Smith</td>
            </tr>
            <tr>
                <td>1002</td>
                <td>Jane Williams</td>
            </tr>
        </tbody>
    </table>
    <footer>
        <a href="/spring-thymeleaf/fragments">Fragments Index</a> |
        <a href="/spring-thymeleaf/markup">Markup inclussion</a> |
        <a href="/spring-thymeleaf/params">Fragment params</a> |
        <a href="/spring-thymeleaf/other">Other</a>
    </footer>
</body>

5結論

この記事では、テンプレートの管理を容易にする強力なツールであるThymeleaf Fragmentsを使用してビューコンポーネントを再利用する方法を説明しました。

また、基本を超えた他の興味深い機能もいくつか紹介しました。ビューレンダリングエンジンとしてThymeleafを選択するときは、これらを考慮する必要があります。

あなたが他のThymeleaf機能について知りたいなら、あなたは間違いなく レイアウト方言 についての私達の記事を見てみるべきです。

いつものように、この例の完全な実装コードはhttps://github.com/eugenp/tutorials/tree/master/spring-thymeleaf[over on GitHub]にあります。