Thymeleaf Variables – 百里叶变量

最后修改: 2020年 11月 29日

中文/混合/英文(键盘快捷键:t)

1. Introduction

1.绪论

In this tutorial, we’re going to take a look at variables in Thymeleaf. We’ll create a Spring Boot example that will fetch a list of Baeldung articles and display them in a Thymeleaf HTML template.

在本教程中,我们将对Thymeleaf中的变量进行考察。我们将创建一个Spring Boot示例,该示例将获取Baeldung文章的列表,并在Thymeleaf HTML模板中显示它们。

2. Maven Dependencies

2.Maven的依赖性

To work with Thymeleaf, we’ll need to add the spring-boot-starter-thymeleaf and spring-boot-starter-web dependencies:

为了与Thymeleaf一起工作,我们需要添加spring-boot-starter-thymeleafspring-boot-starter-web>依赖。

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>

3. Web Controller

3.网络控制器

First, we’ll create a web controller with a GET endpoint that returns a page with a list of Baeldung articles.

首先,我们将创建一个带有GET端点的网络控制器,返回一个包含Baeldung文章列表的页面。

The method annotated with @GetMapping will take a single parameter – the Model. It holds all the global variables that can be further used inside the Thymeleaf template. In our case, the model will have just one parameter – the list of articles.

@GetMapping注释的方法将接受一个参数–Model。它持有所有全局变量,可以在Thymeleaf模板中进一步使用。在我们的例子中,该模型将只有一个参数–文章列表。

The Article class will consist of two String fields, name and url:

Article类将由两个String字段组成,nameurl

public class Article {
    private String name;
    private String url;

    // constructor, getters and setters
}

The return value of our controller’s method should be the name of the desired Thymeleaf template. This name should correspond to the HTML file located in the src/resource/template directory. In our case, it’ll be src/resource/template/articles-list.html.

我们控制器方法的返回值应该是所需的Thymeleaf模板的名称。这个名字应该对应于位于src/resource/template目录下的HTML文件。在我们的例子中,它将是src/resource/template/articles-list.html

Let’s take a quick look at our Spring controller:

让我们快速浏览一下我们的Spring控制器。

@Controller
@RequestMapping("/api/articles")
public class ArticlesController {

    @GetMapping
    public String allArticles(Model model) {
        model.addAttribute("articles", fetchArticles());
        return "articles-list";
    }

    private List<Article> fetchArticles() {
        return Arrays.asList(
          new Article(
            "Introduction to Using Thymeleaf in Spring",
            "https://www.baeldung.com/thymeleaf-in-spring-mvc"
          ),
          // a few other articles
        );
    }
}

After running the application, the articles page will be available at http://localhost:8080/articles.

运行应用程序后,文章页面将可在http://localhost:8080/articles

4. Thymeleaf Template

4.百里香树叶模板

Now, let’s move into the Thymeleaf HTML template. It should have the standard HTML document structure with just the additional Thymeleaf namespace definition:

现在,让我们进入Thymeleaf的HTML模板。它应该有标准的HTML文档结构,只是增加了Thymeleaf的命名空间定义。

<html xmlns:th="http://www.thymeleaf.org">

We’ll use this as a template in further examples, where we’ll be replacing just the content of the <main> tag:

我们将在进一步的例子中使用这个模板,我们将只替换<main>标签的内容。

<!DOCTYPE HTML>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <title>Thymeleaf Variables</title>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
</head>
<body>
    <main>
        ...
    </main>
</body>
</html>

5. Define Variables

定义变量

There are two ways we can define a variable in a Thymeleaf template. The first option is to take a single element while iterating over an array:

我们有两种方法可以在Thymeleaf模板中定义一个变量。第一种方法是在遍历一个数组时取一个单一元素。

<div th:each="article : ${articles}">
    <a th:text="${article.name}" th:href="${article.url}"></a>
</div>

As a result, we’ll get a <div> with several <a> elements corresponding to the number of articles in the articles variable.

结果,我们将得到一个<div>,其中有几个<a>元素,与articles变量中的文章数量相对应。

Another way is to define a new variable based on another one. For example, we can take the first element of the articles array:

另一种方法是在另一个变量的基础上定义一个新的变量。例如,我们可以取文章数组的第一个元素。

<div th:with="firstArticle=${articles[0]}">
    <a th:text="${firstArticle.name}" th:href="${firstArticle.url}"></a>
</div>

Or we can create a new variable that holds just the article’s name:

或者我们可以创建一个新的变量,只保存文章的名字。

<div th:each="article : ${articles}", th:with="articleName=${article.name}">
    <a th:text="${articleName}" th:href="${article.url}"></a>
</div>

In the above example, the ${article.name} and ${articleName} fragments are replaceable.

在上述例子中,${article.name}${articleName}片段是可以替换的。

It’s also possible to define multiple variables. For example, we can create two separate variables to hold the article name and URL:

也可以定义多个变量。例如,我们可以创建两个单独的变量来保存文章名称和URL。

<div th:each="article : ${articles}" th:with="articleName=${article.name}, articleUrl=${article.url}">
    <a th:text="${articleName}" th:href="${articleUrl}"></a>
</div>

6. Variables Scope

6.范围变量

Variables passed to the Model in a controller have a global scope. This means they can be used in every place of our HTML templates.

在控制器中传递给Model的变量有一个全局范围。这意味着它们可以在我们的HTML模板的每个地方使用。

On the other hand, variables defined in the HTML template have a local scope. They can be used only within the range of the element that they were defined in.

另一方面,在HTML模板中定义的变量有一个局部范围。它们只能在它们所定义的元素范围内使用。

For example, the below code is correct as the <a> element is within the firstDiv:

例如,下面的代码是正确的,因为<a>元素是在firstDiv内。

<div id="firstDiv" th:with="firstArticle=${articles[0]}">
    <a th:text="${firstArticle.name}" th:href="${firstArticle.url}"></a>
</div>

On the other hand, when we try to use the firstArticle in another div:

另一方面,当我们试图在另一个div中使用firstArticle

<div id="firstDiv" th:with="firstArticle=${articles[0]}">
    <a th:text="${firstArticle.name}" th:href="${firstArticle.url}"></a>
</div>
<div id="secondDiv">
    <h2 th:text="${firstArticle.name}"></h2>
</div>

We’ll get an exception during compile-time saying that the firstArticle is null:

我们会在编译时得到一个异常,说firstArticlenull

org.springframework.expression.spel.SpelEvaluationException: EL1007E: Property or field 'name' cannot be found on null

This is because the <h2> element is trying to use a variable defined in the firstDiv, which is out of scope.

这是因为<h2>元素试图使用firstDiv,中定义的一个变量,而这个变量已经超出了范围。

If we still need to use the firstArticle variable inside the secondDiv, we would need to define it again in secondDiv or wrap these two div tags in a common element and define the firstArticle in it.

如果我们仍然需要在secondDiv内使用firstArticle变量,我们需要在secondDiv中再次定义它,或者将这两个div标签包裹在一个共同的元素中,在其中定义firstArticle

7. Changing a Variable’s Value

7.改变一个变量的值

It’s also possible to overwrite a variable’s value in a given scope:

也可以在一个给定的范围内覆盖一个变量的值。

<div id="mainDiv" th:with="articles = ${ { articles[0], articles[1] } }">
    <div th:each="article : ${articles}">
        <a th:text="${article.name}" th:href="${article.url}"></a>
    </div>
</div>

In the above example, we redefined the articles variable to have just two first elements.

在上面的例子中,我们重新定义了articles变量,使其只有两个第一元素。

Note that outside of the mainDiv, the articles variable will still have its original value passed in the controller.

请注意,在mainDiv之外,articles变量仍将在控制器中传递其原始值。

8. Conclusion

8.结语

In this tutorial, we’ve learned how to define and use variables in Thymeleaf. As always, all the source code is available over on GitHub.

在本教程中,我们已经学会了如何在Thymeleaf中定义和使用变量。一如既往,所有的源代码都可以在GitHub上找到