テンプレート、上から書くか? 下から書くか?

3 min read読了の目安(約3000字

ブログ記事を書いておくことの利点の1つは、Lorem ipsumとして使えるところ。

この記事はXSL Advent Calendar 2020 16日目の遅刻です。

https://adventar.org/calendars/5027

XSL入門を書くっていってもう何日経つのか。今日のは入門のような、そうでもないような。尻切れトンボなので後日修正するかもしれない。

XSLTがテンプレート言語かみたいのは本題ではなく。テンプレートが嫌ならボイラープレートでもスケルトンでも良いんですが。

2000年代はじめくらいのテンプレート言語の本や資料などを見ると、XSLTに限らず「これを実行すればWebページができちゃう!」的なサンプルが結構あります[1]。大枠は決まっていて、ちょこちょこ細かいところを穴埋めすれば動くようになっているやつです。for足したりifしたり。XSLTだとこんな感じですかね。

<?xml version="1.0" encoding="UTF-8" ?>
<page><hoge>Hello, World!</hoge></page>
<?xml version="1.0" encoding="UTF-8" ?>
<xsl:transform version="3.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
	<xsl:output method="html"
		    html-version="5"
		    encoding="UTF-8"
		    indent="yes" />
	<xsl:template match="/">
		<html>
			<head>
				<title>TITLE</title>
				<meta .../>
			</head>
			<body>
				<header id="top">
					<div>ようこそ</div>
				</header>
				<main>
					<xsl:apply-templates />
				</main>
				<footer>
					<div>
						<a href="#top">戻る</a>
					</div>
				</footer>
			</body>
		</html>
	</xsl:template>
	<xsl:template match="hoge">
		<p><xsl:apply-templates /></p>
	</xsl:template>
</xsl:transform>

原始体験としてグラフィカルなものができると嬉しい!みたいな話は否定しませんが、ずっとこの書き方をしているとメンテナンスがファイル単位になって大変ですね。なのでテンプレートの分割など、ちょっとテンプレート言語っぽい機能が登場してくるわけです。

<!-- 宣言部略-->

<xsl:template name="head">
	<head>
		<title>TITLE</title>
		<meta .../>
	</head>
</xsl:template>
<xsl:template name="header">
	<header>
		<div>ようこそ</div>
	</header>
</xsl:template>
...
<template match="/">
	<html>
		<xsl:call-template name="head" />
		<body>
			<xsl:call-template name="header" />
			<main>
				<xsl:apply-templates />
			</main>
			<xsl:call-template name="footer" />
		</body>
	</html>
</xsl:template>

<!-- ルート終了も略 -->

<xsl:param><xsl:attribute-set>も使っていないし、まだまだ弄れるところはありますが、match="/"がちょっとスッキリしました。

最近、いや最近でもないな。Webページの見た目はFigmaなどでグラフィカルなデザインを共有し、実際の構造に落としこんでいくような方式と、React.jsやVue.jsなどパーツ、コンポーネントを作り、適宜載せていくような方式があります。多分。挙げたもののまともに使ったことない気がする。更にフレームワークとかの話始めると際限がないんですが。

これらについて、トップダウンとボトムアップという一般性の高い概念に落としこめるか[2]というと、まあまあ難しい。テンプレートに流しこむのがただのKey-Valueであるうちは割とどうにかなるんですが、構造化文書なんてものを対象にすると厄介さがマシマシです。

最初にパっと出ししたXMLをもう少し捻ってみましょう。

<?xml version="1.0" encoding="UTF-8" ?>
<page>
	<hoge>Hello, World!</hoge>
	<fuga>
		<hoge>Saluton Mondo!</hoge>
	</fuga>
</page>

page/hogepage/fuga/hogeの2つ、愚直に両パターンを書くか、hogeを用意してpagefugaあるいはpage/fugaを書いて適用するかはこのXMLと、変換したいHTML両方を考える必要があります。しかし、登場してもいないhogefugaなる要素やhoge/fugaなる構造を意識しながら書くのもどうよ。XMLアプリの複雑なやつはSpecificationが500ページあるみたいな話になってきて、変換元と変換先で更に倍!と一生の短さについて考えるフェイズに突入しかねません。

というわけで、横から見ます。打ち上げ花火の話です。銀の弾丸はありません。完成予定の構造と、手元の最低限のパーツを見ながら間を埋めていくという泥臭い作業となります。構造があって、それを解釈し構築しなければならないというのはすべてのテンプレート言語共通の話です。そこにフレームワークを含めてもよい。

文書構造を考えるにあたり、XMLとしてはDTDなどのスキーマ、そしてSchematronが(、XSLTとしてはxsl:assertといった機能が)あります。これらがある故に敬遠されるXMLやXSLTですが、他のテンプレート言語ではこういった「構造に対する補助」がどこまであるかということを考えると、戦場で裸か服を着ているかくらいに違うのではないでしょうか。

XSLT自体の補助については、15日目にAQさんがユニットテストの記事を書いてくださっていますね。

https://zenn.dev/aq/articles/unit-testing-xslt-with-xspec
脚注
  1. いざ探そうとするとソース見つからないので幻想かもしれない。 ↩︎

  2. この言葉遊びはわざとなので直さない。 ↩︎