Simple application of thmeleaf in springboot
The priority of static directory and the type of storage resources
Shortcut key of query class: ctrl+shift+r
Search ResourceProperties
private static final String[] CLASSPATH_RESOURCE_LOCATIONS = new String[]{ "classpath:/META-INF/resources/", "classpath:/resources/", "classpath:/static/", "classpath:/public/" };
priority
resources>static>public
Resource storage
resource: store uploaded resources
static: store css and pictures
Public: store public resources such as js
Simple application
Official website address of thymeleaf: https://www.thymeleaf.org/
A simple html on the official website
<!DOCTYPE html SYSTEM "http://www.thymeleaf.org/dtd/xhtml1-strict-thymeleaf-4.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org"> <head> <title>Good Thymes Virtual Grocery</title> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> <link rel="stylesheet" type="text/css" media="all" href="../../css/gtvg.css" th:href="@{/css/gtvg.css}" /> </head> <body> <p th:text="#{home.welcome}">Welcome to our grocery store!</p> </body> </html>
Bring in namespace
Xmlns: shorthand for XML namespace
An error may be reported when a namespace is introduced. You can delete xmlns="http://www.w3.org/1999/xhtml", just use xmlns: th = "http://www.thmeleaf.org"
xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org"
Some syntax of thymeleaf
- Simple expression:
Variable expression: ${ }
Select variable expression: * { }
Message expression: }
Link URL expression: @ { } - Written words
Text text: 'one text', 'Another one!'
Number text: 0, 34, 3.0, 12.3
Boolean text: true, false
Empty text: null
Text mark: one, sometext, main - Text operation:
String concatenation:+
Replace text with: "|The name is ${name}"| - Arithmetic operation:
Binary operators: +, -, *, /,%
Minus sign (unary operator):- - Boolean operation:
Binary operators: and, or
Boolean negation (unary operator):!, not - Comparison and equality:
Comparison: >
Equal sign operator: = =,! = (eq, ne) - Conditional operator:
If - then: (if)? (then)
If - then - otherwise: (if)? (then): (else)
Default: (value)?: (DefaultValue)
Introduce css address
Above mentioned link URL expression: @ { }
<!-- Bootstrap core CSS --> <link th:href="@{/css/bootstrap.min.css}" rel="stylesheet"/> <!-- Custom styles for this template --> <link th:href="@{/css/signin.css}" rel="stylesheet"/>
sprigmvc+thymeleaf
This is in the doc on the official website
This is about Spring MVC and Thymeleaf: how to access data from templates:
In a typical Spring MVC application, the @ Controller class is responsible for preparing model diagrams with data and selecting the views to render. This model diagram allows for a complete abstraction of view technology, and in the case of Thymeleaf, it is transformed into a Thymeleaf context object (part of the execution context of the Thymeleaf template), which makes all defined variables available to expressions executed in the template.
sprigmvc+thymeleaf
- Spring model attributes
- Request parameters
- Session attributes
- ServletContext attributes
- Spring beans(@Bean)
Let's talk about model properties
Refer to the document for details: https://www.thymeleaf.org/doc/articles/springmvcaccessdata.html
Internationalization
Create the i18n folder in the resources directory (i18n international abbreviation)
Take the landing page as an example
- Create the login.properties file
- Create the login ABCD cn.properties file
- Automatically generate Resource Bundle 'login' folder
- Click Resource Bundle view
- Click + to create login.xxx
- Input content in default, Chinese and English respectively
- Binding internationalized content in a page
<h1 class="h3 mb-3 font-weight-normal" th:text="#{login.tip}">Please sign in</h1>
Translation between Chinese and English
index.html page Chinese English conversion a tag
<a class="btn btn-sm" th:href="@{/index.html(l='zh_CN')}">Chinese</a> <a class="btn btn-sm" th:href="@{/index.html(l='en_US')}">English</a>
Chinese English mutual transfer configuration
Search webmvcauautoconfiguration
Refer to MessageCodesResolver method override
public MessageCodesResolver getMessageCodesResolver() { if (this.mvcProperties.getMessageCodesResolverFormat() != null) { DefaultMessageCodesResolver resolver = new DefaultMessageCodesResolver(); resolver.setMessageCodeFormatter(this.mvcProperties.getMessageCodesResolverFormat()); return resolver; } else { return null; } }
Process the request parameters about the language from the request
package com.common.config; import org.springframework.web.servlet.LocaleResolver; import org.thymeleaf.util.StringUtils; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.util.Locale; public class MyLocalResolver implements LocaleResolver { //Parsing request @Override public Locale resolveLocale(HttpServletRequest httpServletRequest) { //Get language parameters in the request String language = httpServletRequest.getParameter("l"); Locale locale = Locale.getDefault(); //If the default is not used //If the requested language parameter is not empty if(!StringUtils.isEmpty(language)) { //zh_CN String[] split = language.split("_"); //Country, region locale = new Locale(split[0],split[1]); } return locale; } @Override public void setLocale(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Locale locale) { } }
Register LocaleResolver in the custom MyWebmvcConfig
package com.common.config; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.LocaleResolver; import org.springframework.web.servlet.config.annotation.ViewControllerRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; @Configuration //@EnableWebMvc public class MyWebmvcConfig implements WebMvcConfigurer { @Override public void addViewControllers(ViewControllerRegistry registry) { registry.addViewController("/").setViewName("index"); registry.addViewController("/index").setViewName("index"); registry.addViewController("/index.html").setViewName("index"); } //Custom internationalization components @Bean public LocaleResolver localeResolver() { return new MyLocalResolver(); } }
index.html code
<!DOCTYPE html> <html lang="en" xmlns:th="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/> <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"/> <meta name="description" content=""/> <meta name="author" content=""/> <title>Signin Template for Bootstrap</title> <!-- Bootstrap core CSS --> <link th:href="@{/css/bootstrap.min.css}" rel="stylesheet"/> <!-- Custom styles for this template --> <link th:href="@{/css/signin.css}" rel="stylesheet"/> </head> <body class="text-center"> <form class="form-signin" action="dashboard.html"> <img class="mb-4" th:src="@{/img/bootstrap-solid.svg}" alt="" width="72" height="72"/> <h1 class="h3 mb-3 font-weight-normal" th:text="#{login.tip}">Please sign in</h1> <label class="sr-only" th:text="#{login.username}">Username</label> <input type="text" class="form-control" th:placeholder="#{login.username}" required="" autofocus=""/> <input type="password" class="form-control" th:placeholder="#{login.password}" required=""/> <div class="checkbox mb-3"> <label> <input type="checkbox" value="remember-me"/> [[#{login.remember}]] </label> </div> <button class="btn btn-lg btn-primary btn-block" type="submit">[[#{login.btn}]]</button> <p class="mt-5 mb-3 text-muted">© 2017-2018</p> <a class="btn btn-sm" th:href="@{/index.html(l='zh_CN')}">Chinese</a> <a class="btn btn-sm" th:href="@{/index.html(l='en_US')}">English</a> </form> </body> </html>
DOM selector syntax
according to vue Put forward the idea of public page thymeleaf Can also do
commons.html
th:fragment="topbar" //Extract head navigation bar
th:fragment="sidebar" //Extract sidebar
th:class="${active=='list.html'?'nav-link active':'nav-link'}" th:href="@{/emps}" //Control highlighting
dashboard.html:
th:replace="~{commons/commons::topbar}" //Import the header navigation bar from commons.html
th:replace="~{commons/commons::sidebar(active='main.html')}" //Introduce sidebar and pass value to commons.html to control highlight
common.html
<!DOCTYPE html> <html lang="en" xmlns:th="http://www.thymeleaf.org"> <!-- Head navigation bar--> <nav class="navbar navbar-dark sticky-top bg-dark flex-md-nowrap p-0" th:fragment="topbar"> <a class="navbar-brand col-sm-3 col-md-2 mr-0" href="http://getbootstrap.com/docs/4.0/examples/dashboard/#">[[${session.loginUser}]]</a> <input class="form-control form-control-dark w-100" type="text" placeholder="Search" aria-label="Search"> <ul class="navbar-nav px-3"> <li class="nav-item text-nowrap"> <a class="nav-link" href="http://getbootstrap.com/docs/4.0/examples/dashboard/#">Sign out</a> </li> </ul> </nav> <!--sidebar--> <nav class="col-md-2 d-none d-md-block bg-light sidebar" th:fragment="sidebar"> <div class="sidebar-sticky"> <ul class="nav flex-column"> <li class="nav-item"> <a th:class="${active=='main.html'?'nav-link active':'nav-link'}" th:href="@{/index.html}"> <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-home"> <path d="M3 9l9-7 9 7v11a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z"></path> <polyline points="9 22 9 12 15 12 15 22"></polyline> </svg> Dashboard <span class="sr-only">(current)</span> </a> </li> <li class="nav-item"> <a class="nav-link" href="http://getbootstrap.com/docs/4.0/examples/dashboard/#"> <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-shopping-cart"> <circle cx="9" cy="21" r="1"></circle> <circle cx="20" cy="21" r="1"></circle> <path d="M1 1h4l2.68 13.39a2 2 0 0 0 2 1.61h9.72a2 2 0 0 0 2-1.61L23 6H6"></path> </svg> Products </a> </li> <li class="nav-item"> <a th:class="${active=='list.html'?'nav-link active':'nav-link'}" th:href="@{/emps}"> Staff management </a> </li> </ul> </nav> </html>
dashboard.html import
//Part of code <!-- Top navigation bar--> <div th:replace="~{commons/commons::topbar}"></div> <!-- sidebar--> <div th:replace="~{commons/commons::sidebar(active='main.html')}"></div>
list.hmtl introduction
//Part of code <!--Head navigation bar--> <div th:replace="~{commons/commons::topbar}"></div> <div th:replace="~{commons/commons::sidebar(active='list.html')}"></div>