Thymeleaf学习系列

Thymeleaf学习二

3.Using Texts

3.1 A multi-language welcome
我们的第一个任务是创建我们的商店主页。
第一版极其简单,下面是我们的/WEB-INF/templates/home.html 文件:

<!DOCTYPE html>

<html 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>

第一件事情注意到的是这个文件是HTML5,可以被任何浏览器展现。因为其没有包含任何非HTML的标签(浏览器将忽略所有他们不理解的属性,例如 th:text)
但是你也许会注意到这个模板并不是一个合法的HTML5文档,因为我们正在使用的这些非标准属性例如th:*形式,在HTML5标准中是不被允许的。实际上,我们甚至提娜佳了一个xmlns:th属性到我们的标签,这绝对是非HTML5的。

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

在模板处理的时候没有任何的影响,但是其作用是作为一个符号,防止我们的IDE报缺少对th:*属性的命名空间定义缺少的错。
所以如何让这个模板合法呢?很简单:转换到Thyme leaf的数据属性语法,对属性名使用data-前缀和-分隔符而不使用冒号:

<!DOCTYPE html>

<html>

  <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" data-th-href="@{/css/gtvg.css}" />
  </head>

  <body>
  
    <p data-th-text="#{home.welcome}">Welcome to our grocery store!</p>
  
  </body>

</html>

data-前缀属性在HTML5里面是允许的,所以上面的代码是合法的HTML5文档

Using th:text and externalizing text
外部文本就是从模板文件的模板代码中提取片段,这样可以被保存在不同的文件(典型的就是.properties文件)。也可以被其他的语言写的同等的文件方便的替换(一个叫做internationalization 或者i18n的过程)。文本的外部片段通常叫做messages

Messages 通常有一个key来标识它们,Thymeleaf让你能够指定一个text来对应于一个message使用#{…}语法。

<p th:text="#{home.welcome}">Welcome to our grocery store!</p>

在这里我们可以看到Thymeleaf标准方言的两个不同特性:

1.th:text属性,会检查它的value表达式,设置这个结果到tag里面,并且有效替换我们在代码里面看到的”Welcome to our grocery store!“文本
2.#{home.welcome}表达式,在 Standard Expression Syntax中规定,th:text属性使用的文本将会是带有home.welcome的key的message,对应于无论我们将用这个模板处理的区域。

现在,什么是externalized text呢?
externalized text的位置在Thymeleaf中是完全可以配置的,取决于使用的具体org.thymeleaf.messageresolver.IMessageResolver实现。一般来说,一个基于.propertie文件的实现将会使用。但实际我们也可以根据需要创建我们自己的实现。比如说,从数据库获取message。
然而。我们在初始化的时候,没有为我们的模板引擎指定一个message resolver,这就意味着我们的应用将使用Standard Message Resolver,由org.thymeleaf.messageresolver.StandardMessageResolver实现。
org.thymeleaf.messageresolver.StandardMessageResolver在和/WEB-INF/templates/home.html同一路径和相同姓名作为其模板。例如:

  • /WEB-INF/templates/home_en.properties作为英文文本
  • /WEB-INF/templates/home_es.properties作为西班牙语文本
  • /WEB-INF/templates/home_pt_BR.properties作为葡萄牙语(巴西语)文本
  • /WEB-INF/templates/home.properties默认文本(若区域未指定)

看一下home_es.properties文件

home.welcome=¡Bienvenido a nuestra tienda de comestibles!

Contexts

为了处理我们的模板,需要创建一个HomeController类来实现我们的IGTVGController接口

public class HomeController implements IGTVGController {

    public void process(
            final HttpServletRequest request, final HttpServletResponse response,
            final ServletContext servletContext, final ITemplateEngine templateEngine)
            throws Exception {
        
        WebContext ctx = 
                new WebContext(request, response, servletContext, request.getLocale());
        
        templateEngine.process("home", ctx, response.getWriter());
        
    }

}

首先创建了一个context。一个Thymeleaf context就是一个是实现了org.thymeleaf.context.IContext接口的对象。Contexts应该包含一个模板引擎执行的所有数据。并且需要指出需要使用外部message的区域。

public interface IContext {

    public Locale getLocale();
    public boolean containsVariable(final String name);
    public Set<String> getVariableNames();
    public Object getVariable(final String name);
    
}

有一个这个接口的定制的扩展,org.thymeleaf.context.IWebContext,可以使用在基于Servlet API的web应用。如Spring MVC

public interface IWebContext extends IContext {
    
    public HttpServletRequest getRequest();
    public HttpServletResponse getResponse();
    public HttpSession getSession();
    public ServletContext getServletContext();
    
}

Thymeleaf核心库提供了这些接口的实现

  • org.thymeleaf.context.Context 实现了IContext
  • org.thymeleaf.context.WebContext 实现了 IWebContext
    正如在controller中的代码一样,WebContext 是我们看到的,实际上因为使用了ServletContextTemplateResolver ,我们必须使用一个是西安了IWebContext的Context
WebContext ctx = new WebContext(request, response, servletContext, request.getLocale());

只需要三个参数就可以,因为默认的区域将使用若未指定(虽然在实际开发中永远也不要这么干)

有一些特殊的表达式,我们可以用来获得request参数还有request,session,application属性从我们的模板的WebContext中。例如:

  • ${x}返回一个存储在Thymeleaf context中的x变量或者作为一个request属性
  • ${param.x}会返回一个request参数叫做x
  • ${session.x}将会返回一个叫做x的session属性
  • ${application.x}将会返回一个叫做x的servlet context属性

Executing the template engine
Unescaped Text

如何先理:?

home.welcome=Welcome to our <b>fantastic</b> grocery store!

如果我们执行上面的模板,将获得:

<p>Welcome to our &lt;b&gt;fantastic&lt;/b&gt; grocery store!</p>

不是我们想看的,因为标签已经转义了,因此将会被展现在浏览器。
这是th:text属性的默认行为。如果我们希望Thymeleaf考虑到我们的HTML标签。不去转义,我们必须使用一个不同的属性 th:utext

<p th:utext="#{home.welcome}">Welcome to our grocery store!</p>

这将输出我们想要的信息:

<p>Welcome to our <b>fantastic</b> grocery store!</p>

Using and displaying variables

添加一些信息:

Welcome to our fantastic grocery store!

Today is: 12 july 2010

首先需要修改我们的controller,添加日期信息作为context变量

public void process(
            final HttpServletRequest request, final HttpServletResponse response,
            final ServletContext servletContext, final ITemplateEngine templateEngine)
            throws Exception {
        
    SimpleDateFormat dateFormat = new SimpleDateFormat("dd MMMM yyyy");
    Calendar cal = Calendar.getInstance();
        
    WebContext ctx = 
            new WebContext(request, response, servletContext, request.getLocale());
    ctx.setVariable("today", dateFormat.format(cal.getTime()));
        
    templateEngine.process("home", ctx, response.getWriter());
        
}

我们添加了一个String 变量,叫做today到我们的context,现在我们将在我们的模板中展现:

<body>

  <p th:utext="#{home.welcome}">Welcome to our grocery store!</p>

  <p>Today is: <span th:text="${today}">13 February 2011</span></p>
  
</body>

我们任然使用th:text属性来完成这个任务,但语法有一点不一样,不是#{…},我们使用${…}
这是一个变量表达式,包含一个OGNL表达式。

t o d a y t o d a y {today}表达式表明需要获取一个叫today的变量,表达式可以更复杂。例如 {user.name}来获取一个叫user的变量并执行其getName()方法。

猜你喜欢

转载自blog.csdn.net/u010971018/article/details/84939494
今日推荐