Cодержание
Используйте Layout в Thymeleaf
View more Tutorials:


Page Layout (разметка страницы) относится к распределению текста, изрбражений и других объектов на одной странице, и это самый обсуждаемый вопрос дизайнеров website. В данной статье я представлю технику, которая используется в Thymeleaf, чтобы создать Layout.
Thymeleaf использует fragment, чтобы соединить вместе и создать страницу, поэтому вам стоит изучить fragment перед тем, как продолжить с данной статьей.
Один website может иметь много странц, но страницы имеют одинаковую структуру. Например, ниже является простая структура:

Основываясь на структуре выше, вы можете создать разные страницы:

Ниже является изображение приложения, написанного на Spring Boot, не волнуйтесь если вы используете другой фреймворк (framework), структура проекта может быть немного другой, но не будет сложно для вас понять, что я здесь выполняю.
Создать 2 файла main.css & main-layout.html:

Файл main-layout.html содержит 1 fragment имеет 6 параметров, эти параметры помогают сформировать полный интерфейс страницы.
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;
}
}
Откройте файл main-layout.html напрямую на браузере и вы сможете увидеть его интерфейс.

Файл app-fragments.html содержит fragment, которые переиспользуются во многих разных Template приложения.

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">
© o7planning.org
</div>
</body>
</html>
Создайте другие страницы для вашего приложения:
- home.html, products.html, about.html.

Файл home.html использует Layout определенный файлом main-layout.html, и передает (pass) значения для параметрв.
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";
}
}