読者です 読者をやめる 読者になる 読者になる

M12i.

学術書・マンガ・アニメ・映画の消費活動とプログラミングについて

Thymeleafテンプレートファイルのinclude/repalaceは再帰可能

Java

引き続きThymeleafテンプレートエンジンについて調べたり使ったりしているうちに気がついたのですが、なんと(?)、th:include属性やth:replace属性による外部テンプレート断片の読み込み機能は再帰に対応していることがわかりました。・・・というより、もし対応していないとしたらとっても困ったことになるところでした。

th:include属性とth:replace属性はともに、別テンプレート・ファイル内で定義されているテンプレート断片ファイルをその属性が記述されている位置に取り込む機能です。両者のちがいは、その属性が指定されているタグの "子要素のかたちで" 読み込むか、タグを "置き換えるかたちで" 読み込むかです。

そして例えば以下のようにincluding.htmlincluded_recursively.htmlの2つのテンプレートを用意することで、ツリー構造のような再帰的な構造を持つオブジェクト・グラフをHTMLレンダリングに使用できるのです。

including.html

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:th="http://www.thymeleaf.org" xml:lang="ja" lang="ja">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
</head>
<body>

<div>
	<span th:text="${node.content}">
	(item's content here.)</span>
	<ul>
		<li th:each="node : ${node.children}">
			<div th:replace="included_recursively :: item">
			(sub-nodes here)</div>
		</li>
	</ul>
</div>
	
</body>

このテンプレートはth:replace属性により、Thymeleafテンプレートエンジンに対して、外部のincluded_recursivelyという名前のテンプレートからitemという断片を取り出してレンダリングに使用するよう指示しています。

included_recursively.html

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:th="http://www.thymeleaf.org" xml:lang="ja" lang="ja">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
</head>
<body>

<div th:fragment="item">
	<span th:text="${node.content}">
	(item's content here.)</span>
	<ul>
		<li th:each="node : ${node.children}">
			<div th:replace="included_recursively :: item">
			(sub-nodes here)</div>
		</li>
	</ul>
</div>
	
</body>

一方、included_recursivelyテンプレートのほうでは、th:fragment属性でテンプレート断片を定義しています。そして、その断片内で自分自身を参照しています(th:replace="included_recursively :: item")。

これは強力です。この機能があることで再帰的なオブジェクト・グラフを容易にHTML化できます。この機能がなければ、最大深度を設けて表現可能性を制限するか、HTMLをプログラムコードで生成するかしなくてはならないでしょう。

もっとも再帰可能ということはつまりテンプレート変数の使用方法を誤るとスタックオーバーフローも発生しうるということですが・・・。


Spring関連の訳出記事まとめ - M12i.