Thymeleaf使ってみた

ビューコンポーネントを組み合わせるApache Tilesみたいなのないかなーと思い、
Javaのテンプレートエンジンを探してたら、Thymeleafってのが面白そうだったので、ちょっと試してみた。
繰り返すが、こいつは「タイムリーフ」と読めばいいのか?


まずはSourceForgeで最新版の2.0.5をダウンロードし、展開したアーカイブから、distとlibからライブラリを拾って、Webプロジェクトに入れてやる。

こんな感じ。


次に、テンプレートを規定するリゾルバと、テンプレートから解析処理を行うエンジンを作ってやる。

package test;

import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.thymeleaf.TemplateEngine;
import org.thymeleaf.context.WebContext;
import org.thymeleaf.templatemode.StandardTemplateModeHandlers;
import org.thymeleaf.templateresolver.ServletContextTemplateResolver;

@WebServlet(name="ThymeleafTest", urlPatterns={"/test"})
public class ThymeleafTest extends javax.servlet.http.HttpServlet {

    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {

        // Resolverを作成
        ServletContextTemplateResolver resolver = new ServletContextTemplateResolver();
        resolver.setTemplateMode(StandardTemplateModeHandlers.XHTML.getTemplateModeName());
        resolver.setPrefix("/WEB-INF/templates/");
        resolver.setSuffix(".html");
        resolver.setCacheTTLMs(3600000L);

        // Engineを作成
        TemplateEngine engine = new TemplateEngine();
        engine.setTemplateResolver(resolver);

        // テンプレートから解析およびレンダリング
        WebContext ctx = new WebContext(request, request.getServletContext(), request.getLocale());
        engine.process("layout", ctx, response.getWriter());
    }
}


今回は、何個かのコンポーネントを組み合わせて一つのビューにしたいので、レイアウトテンプレートに、ヘッダとコンテンツを入れてみる。
先日、html5で作ったやつを題材にしてやってみよう。

[header.html]
<!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>
<meta charset="UTF-8" />
</head>
<body>
<div id="header" th:fragment="header">
    <header>
        <h1>メニュー</h1>
        <nav>
            <ul>
                <li><a href="#section1">section1</a></li>
                <li><a href="#section2">section2</a></li>
            </ul>
        </nav>
    </header>
</div>
</body>
</html>

レイアウトにはめ込みたい箇所には、th:fragmentで名前をつけておく。

[content.html]
<!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>
<meta charset="UTF-8" />
</head>
<body>
<div id="content" th:fragment="content">
<article>
    <section>
        <h1 id="section1">Section1</h1>
        <p>セクション1</p>
    </section>
    <section>
        <h1 id="section2">Section2</h1>
        <p>セクション2</p>
    </section>
</article>
</div>
</body>
</html>


はめ込まれるテンプレートの方には、th:includeで、テンプレート名とフラグメント名を指定する。
(同じ名前で分かりづらいが・・・サンプル悪かったかなw)

[layout.html]
<!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>
<meta charset="UTF-8" />
<style type="text/css">
<!--
    h1:target {
        color: red;
    }
// -->
</style>
</head>
<body>

    <div id="menu" th:include="header :: header"></div>

    <div id="content" th:include="content :: content"></div>

</body>
</html>

これで完成。では実行してみる。



日本語化けてるし・・・orz
まぁ、目的は達成できたから、ひとまず良しとするかw
あとは、インクルードするテンプレートの個数を可変にできれば御の字だ。


それでは次回(あるのか?)。