devstory

Utiliser Layout dans Thymeleaf

  1. L'objectif de la leçon
  2. Exemple : Thymeleaf Layout

1. L'objectif de la leçon

Page Layout (la mise en page) fait référence à la disposition du texte, des images et d'autres objets sur une page, et c'est la question la plus intéressante pour les concepteurs de website. Dans cette leçon, je vais vous présenter la technique utilisée dans Thymeleaf pour créer un Layout.
Thymeleaf utilise des fragment pour former une page, par conséquent, vous devriez vous renseigner sur les fragment avant de continuer cette leçon.
Un website peut contenir beaucoup de pages, mais les pages ont la même structure. Par exemple, ci-dessous est une structure simple :
En fonction de la structure ci-dessus, vous pouvez créer différentes pages :

2. Exemple : Thymeleaf Layout

Ci-dessous se trouve l'image d'une application, qui est écrite sur Spring Boot. Ne vous inquiétez pas, si vous utilisez un autre framework, la structure du projet peut être légèrement différente, mais il n'est pas difficile pour vous de comprendre les étapes que je réalise ici.
Créez deux fichiers comme main.css & main-layout.html :
Le fichier main-layout.html contient un fragment qui a 6 paramètres. Ces paramètres permet de façonner l'interface complète d'une page.
layouts/main-layout.html
<!DOCTYPE HTML>
<html xmlns:th="http://www.thymeleaf.org"
    th:fragment="main-fragment (title, otherStaticResources, header, nav, mainContent, footer)">
<head>
<meta charset="UTF-8" />
<title th:replace="${title}">Page 1 Title</title>
<link rel="stylesheet" type="text/css" th:href="@{/main.css}" href="../../static/main.css"/>
<!-- Other javascript, css source files -->
<th:block th:replace="${otherStaticResources} ?: ~{}"></th:block>
</head>
<body>
    <header th:insert="${header} ?: ~{}">
        <h2>Page 1</h2>
    </header>
    <section>
        <nav th:insert="${nav} ?: ~{}">
            <ul>
                <li><a href="#">Page 1</a></li>
                <li><a href="#">Page 2</a></li>
            </ul>
        </nav>
        <article th:insert="${mainContent} ?: ~{}">
            <h1>Page 1</h1>
            <p>Main content of Page 1</p>
        </article>
    </section>
    <footer th:insert="${footer} ?: ~{}">
        <p>Footer</p>
    </footer>
</body>
</html>
main.css
* {
    box-sizing: border-box;
}
header {
    background-color: #666;
    padding: 5px;
    text-align: center;
    font-size: 35px;
    color: white;
}
nav {
    float: left;
    width: 30%;
    height: 300px;
    background: #ccc;
    padding: 20px;
}
nav ul {
    list-style-type: none;
    padding: 0;
}
article {
    float: left;
    padding: 20px;
    width: 70%;
    background-color: #f1f1f1;
    height: 300px;
}
section:after {
    content: "";
    display: table;
    clear: both;
}
footer {
    background-color: #777;
    padding: 10px;
    text-align: center;
    color: white;
}
@media ( max-width : 600px) {
    nav, article {
        width: 100%;
        height: auto;
    }
}
Ouvrez le fichier main-layout.html directement sur le navigateur et vous pouvez voir ses interfaces.
Le fichier app-fragments.html comprend des fragment réutilisés dans les différents Template de l'application.
fragments/app-fragments.html
<!DOCTYPE HTML>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8" />
<title>App Fragments</title>
</head>
<body>
    <!-- Default Navigator -->
    <ul th:fragment = "nav-default">
        <li><a th:href="@{/}">Home</a></li>
        <li><a th:href="@{/products}">Products</a></li>
        <li><a th:href="@{/about}">About</a></li>
    </ul>
    <!-- Admin Navigator -->
    <ul th:fragment = "nav-admin">
        <li><a th:href="@{/admin/products}">Product Management</a></li>
        <li><a th:href="@{/admin/orders}">Order Management</a></li>
    </ul>
    <div th:fragment="copyright">
      &copy; o7planning.org
    </div>
</body>
</html>
Créez d'autres pages de votre application :
  • home.html, products.html, about.html.
The home.html file uses Layout difined by the main-layout.html file, and pass values for parameters.
home.html
<!DOCTYPE html>
<!--  main-fragment (title, otherStaticResources, header, nav, mainContent, footer)  -->
<html xmlns:th="http://www.thymeleaf.org"
      th:replace="~{layouts/main-layout :: main-fragment(  
                                                ~{::title},
                                                ~{:: #home-static-resources},
                                                ~{:: #home-header},
                                                ~{:: #home-nav},
                                                ~{:: #home-main-content},  
                                                ~{:: #home-footer}
                                               )}">
                                              
<head>
    <title>Title of Home Page</title>
    <th:block id="home-static-resources">
        <script type="text/javascript" src="../static/home.js" th:src="@{/home.js}"></script>
        <link rel="stylesheet" type="text/css" href="../static/home.css" th:href="@{/home.css}"/>
    </th:block>
</head>
<body>
    <div id="home-header">
        Header of Home Page
    </div>
    <div id="home-nav" th:replace="~{/fragments/app-fragments :: nav-default}">
        Home Nav
    </div>
    <div id="home-main-content">
        <h2>Home content</h2>
        <div>Content of Home Page</div>
    </div>
    <div id="home-footer" th:replace="~{/fragments/app-fragments :: copyright}">
        Footer
    </div>
</body>
</html>
products.html
<!DOCTYPE html>
<!--  main-fragment (title, otherStaticResources, header, nav, mainContent, footer)  -->
<html xmlns:th="http://www.thymeleaf.org"
      th:replace="~{layouts/main-layout :: main-fragment(  
                                                ~{::title},
                                                ~{:: #products-static-resources},
                                                ~{:: #products-header},
                                                ~{:: #products-nav},
                                                ~{:: #products-main-content},  
                                                ~{:: #products-footer}
                                               )}">
                                              
<head>
    <title>Title of Products Page</title>
    <th:block id="products-static-resources">  
       <script type="text/javascript" src="../static/products.js" th:src="@{/products.js}"></script>
    </th:block>
</head>
<body>
    <div id="products-header">
        Header of Products Page
    </div>
    <div id="products-nav" th:replace="~{/fragments/app-fragments :: nav-default}">
         Nav
    </div>
    <div id="products-main-content">
        <h2>Product</h2>
        <p>Samsung</p>
        <p>iPhone</p>
        <p>Nokia</p>
    </div>
    <div id="products-footer" th:replace="~{/fragments/app-fragments :: copyright}">
        Footer
    </div>
</body>
</html>
about.html
<!DOCTYPE html>
<!--  main-fragment (title, otherStaticResources, header, nav, mainContent, footer)  -->
<html xmlns:th="http://www.thymeleaf.org"
      th:replace="~{layouts/main-layout :: main-fragment(  
                                                ~{::title},
                                                ~{:: #about-static-resources},
                                                ~{:: #about-header},
                                                ~{:: #about-nav},
                                                ~{:: #about-main-content},  
                                                ~{:: #about-footer}
                                               )}">
                                              
<head>
    <title>Title of About Page</title>
    <th:block id="about-static-resources">
        <script type="text/javascript" src="../static/about.js" th:src="@{/about.js}"></script>
    </th:block>
</head>
<body>
    <div id="about-header">
        Header of About Page
    </div>
    <div id="about-nav" th:replace="~{/fragments/app-fragments :: nav-default}">
         Nav
    </div>
    <div id="about-main-content">
        <h2>About</h2>
        <div>Content of About Page</div>
    </div>
    <div id="about-footer" th:replace="~{/fragments/app-fragments :: copyright}">
        Footer
    </div>
</body>
</html>
MainController.java
package org.o7planning.thymeleaf.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

@Controller
public class MainController {
    @RequestMapping("/")
    public String home() {
        return "home";
    }
    @RequestMapping("/products")
    public String products() {
        return "products";
    }
    @RequestMapping("/about")
    public String about() {
        return "about";
    }
}