Thymeleaf模板引擎——JSP替代方案

介绍Thymeleaf模板引擎

 

翻译自 阿尔诺COGOLUÈGNES 的文章

有一堆Java模板引擎,但其中一个现在已经获得了一些动力:Thymeleaf。良好而强大的语法,灵活性,充满活力的社区以及与流行Web技术的良好集成,这些都是发现JSP替代方案的充分理由。本文列出了Thymeleaf的核心功能,并展示了如何编写和处理HTML模板。

 

Thymeleaf简而言之

Thymeleaf是一个Java模板引擎。它是一个开源项目,并根据Apache License 2.0获得许可。以下是Thymeleaf的核心功能:

  • 简单而自然的模板
  • 针对Web环境进行了优化,但可以独立运行
  • 高级评估语言(OGNL或Spring Expression Language)
  • 支持模板逻辑(条件,迭代)
  • 全力支持国际化
  • Spring MVC和Spring Web Flow集成
  • 支持复合视图模式(带有片段的本机,Tiles集成,可与Sitemesh一起使用)
  • 先进的模板缓存支持
  • 适用于蒲公英数据表

是的,这是很多功能!继续阅读以了解如何使用数据编写和提供Thymeleaf模板...

Maven 最新模板依赖



    org.thymeleaf
    thymeleaf
    3.0.10.RELEASE

 

设置模板引擎

Thymeleaf基础设施非常简单:a TemplateResolver加载模板和a TemplateEngine进行实际处理(使用给定的上下文合并模板)。以下是独立设置的代码:

 

1

2

3

4

5

ClassLoaderTemplateResolver resolver = new ClassLoaderTemplateResolver();

resolver.setTemplateMode("XHTML");

resolver.setSuffix(".html");

TemplateEngine engine = new TemplateEngine();

engine.setTemplateResolver(resolver);

我们将从类路径的根目录加载模板。当我们要求Thymeleaf呈现一个名为的模板时home,解析器将添加html扩展名,因为我们设置了该suffix属性。然后,我们将能够根据逻辑名称进行思考,并且不会担心文件的物理名称。

模板

我们的模板是home.html位于类路径根目录的文件(例如,src/main/resources如果我们遵循Maven约定,则在项目目录中)。模板的第一个版本仅包含HTML页面的骨架:

 

1

2

3

4

5

6

7

8

9

10

11

<!DOCTYPE html SYSTEM "http://www.thymeleaf.org/dtd/xhtml1-strict-thymeleaf-3.dtd">

<html xmlns="http://www.w3.org/1999/xhtml"

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

<head>

    <title>My first template with Thymeleaf</title>

    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />

</head>

<body>

</body>

</html>

请注意使用特定于Thymeleaf的doctype。

处理模板

我们的模板中没有任何动态,但我们可以通过在引擎配置后添加以下代码来测试我们的设置:

 

1

2

3

StringWriter writer = new StringWriter();

Context context = new Context();

engine.process("home", context, writer);

然后,writer变量应包含已处理模板的输出,该输出基本上是文件的静态内容。重要的事情:

处理需要上下文。该对象通常包含我们想要在视图中显示的变量。

要调用要渲染的模板home。解析器将负责将此逻辑名称映射到文件的物理位置。请记住,我们使用的是基于类路径的解析器,它为模板名称添加了HTML扩展。

好的,一切似乎都有效!了解Thymeleaf是如何轻量级的。模板引擎大部分时间都在Web环境中使用,但我们也可以在独立环境中轻松使用它,比如JUnit测试。

标签和国际化(i18n)

Thymeleaf的默认国际化支持非常简单:删除模板旁边的属性文件,您就完成了。让我们home.properties在与模板相同的目录中创建一个:

 

1

hello.world=Hello World!

还有一个home_fr.properties法文版的文件:

 

1

hello.world=Bonjour le monde !

我们修改模板以引用此标签:

 

1

2

3

4

5

6

7

8

9

10

11

<!DOCTYPE html SYSTEM "http://www.thymeleaf.org/dtd/xhtml1-strict-thymeleaf-3.dtd">

<html xmlns="http://www.w3.org/1999/xhtml"

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

<head>

    <title>My first template with Thymeleaf</title>

    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />

</head>

<body>

    <p th:text="#{hello.world}">Hello</p>

</body>

</html>

就是这样,我们公开了如何在Thymeleaf的模板中插入动态内容:在HTML元素中添加额外的属性:

 

1

<p th:text="#{hello.world}">Hello</p>

嵌套Hello只是为了预览,Thymeleaf将在处理过程中用动态值替换它。请注意使用Thymeleaf的特定th:text属性以及使用#{key}语法来引用属性文件的条目。

如果我们执行渲染程序,我们最终得到以下输出(如果你的语言环境不是法语!):

 

1

2

3

4

5

6

7

8

9

10

11

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">

<head>

    <title>My first template with Thymeleaf</title>

    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />

</head>

<body>

    <p>Hello World!</p>

</body>

</html>

法语版怎么样?我们可以在上下文中指定语言环境:

 

1

2

3

StringWriter writer = new StringWriter();

Context context = new Context(Locale.FRANCE);

engine.process("home", context, writer);

Thymeleaf使用适当的属性文件:

 

1

2

3

4

5

6

7

8

9

10

11

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">

<head>

    <title>My first template with Thymeleaf</title>

    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />

</head>

<body>

    <p>Bonjour le monde !</p>

</body>

</html>

到目前为止,非常好,让我们继续讨论核心主题:在上下文中推送对象以在视图中呈现它们。

变量替换

我们假设我们想在视图中显示当前日期。我们可以使用已经格式化的字符串提供上下文:

 

1

2

String now = new SimpleDateFormat("yyyy-MM-dd").format(Calendar.getInstance().getTime());

context.setVariable("date", now);

然后在模板中引用此变量,如下所示:

 

1

<p th:text="${date}">The date</p>

注意这次使用${variable}语法(我们用于#{...}i18n)。我们再次依靠该th:text属性来注入动态内容。如果我们再次处理模板,则输出包含预期的内容:

 

1

<p>2013-01-18</p>

让我们看看如何显示典型的域对象。

使用Java bean进行变量替换

显示域对象是Web应用程序的常见用例。我们可以添加一个Contact对象来显示Thymeleaf上下文:

 

1

context.setVariable("contact",new Contact("John","Doe"));

我们对域对象状态进行了硬编码,但它也可以从数据库中加载。以下是如何显示firstnamelastname域对象的属性:

 

1

2

3

4

<div>

     <p>First name: <span th:text="${contact.firstname}">First name</span></p>

     <p>Last name: <span th:text="${contact.lastname}">Last name</span></p>

</div>

正如您所看到的,${...}Thymeleaf中的内容可能是一个复杂的表达式,而不仅仅是对变量的引用。Thymeleaf使用OGNL作为其默认处理引擎,开启了广泛的可能性:运营商,连接等。

现在让我们看一个额外的功能,它可以缩短Java对象的显示。

选择语法的详细程度较低

Thymeleaf允许对对象执行选择。一旦选择了一个对象,它就可以作为评估上下文中的某种第一级变量。然后我们可以使用*{...}语法而不是语法来引用它${...}

在我们的模板中,我们可以contact使用通常的${...}语法选择对象,然后使用以下*{...}语法引用其属性:

 

1

2

3

4

<div th:object="${contact}">

    <p>First name: <span th:text="*{firstname}">First name</span></p>

    <p>Last name: <span th:text="*{lastname}">Last name</span></p>

</div>

我们最终得到完全相同的渲染,但模板代码更简单。不错,不是吗?

迭代

Web应用程序的另一个常见用例是在表中显示数据:我们从数据库中加载Java对象列表并将它们显示在HTML表中。想象一下,我们用以下方式提供上下文List

 

1

2

3

4

5

6

Context context = new Context();

List<Contact> contacts = new ArrayList<Contact>();

contacts.add(new Contact("John","Doe"));

contacts.add(new Contact("Jane","Doe"));

context.setVariable("contacts",contacts);

engine.process("home", context, writer);

迭代列表,我们使用th:each属性:

 

1

2

3

4

5

6

7

8

9

10

<table>

    <tr>

        <th>Firstname</th>

        <th>Lastname</th>

    </tr>

    <tr th:each="contact : ${contacts}">

         <td th:text="${contact.lastname}">The first name</td>

         <td th:text="${contact.firstname}">The last name</td>

     </tr>

</table>

我们最终得到了这个输出:

 

1

2

3

4

5

6

7

8

9

10

11

12

13

<table>

    <tr>

        <th rowspan="1" colspan="1">Firstname</th>

        <th rowspan="1" colspan="1">Lastname</th>

    </tr>

    <tr>

         <td rowspan="1" colspan="1">Doe</td>

         <td rowspan="1" colspan="1">John</td>

    </tr><tr>

         <td rowspan="1" colspan="1">Doe</td>

         <td rowspan="1" colspan="1">Jane</td>

    </tr>

</table>

 

注意Thymeleaf 根据所选XHTML 1.0 Strict标准的DTD 添加了一些rowspancolspan属性。如果我们告诉它符合HTML 5,Thymeleaf就不会生成它们。

在完成我们对Thymeleaf的发现之前,让我们玩条件语句。

条件,«if»语法

想象一下,如果联系人列表为空,我们不想显示空表,我们可以轻松检查列表的大小,如果列表不为空,则选择显示整个表

 

1

2

3

4

5

6

7

8

9

10

<table th:if="${not #lists.isEmpty(contacts)}">

    <tr>

        <th>Firstname</th>

        <th>Lastname</th>

    </tr>

    <tr th:each="contact : ${contacts}">

         <td th:text="${contact.lastname}">The first name</td>

         <td th:text="${contact.firstname}">The last name</td>

     </tr>

</table>

 

请注意使用#lists实用程序对象来检查列表是否为空。

结论

本文介绍了Thymeleaf的基本模板特征。Thymeleaf旨在用于Web应用程序,但它的灵活性使我们可以在独立环境中使用它。Thymeleaf不需要JSP编译器,可以从任何地方获取模板(文件系统,Web上下文,类路径)。您甚至可以将整个Web应用程序打包到一个简单的JAR中,这是迈向模块化的重要一步!Thymeleaf有很多功能,我们将在后续文章中看到如何将它与Spring MVC集成。

英文原文链接:https://blog.zenika.com/2013/01/18/introducing-the-thymeleaf-template-engine/

 

你可能感兴趣的:(Thymeleaf)