SmartyでDjangoみたいなテンプレート継承してみた
仕事で1年ぶりにPHPを使った。テンプレートエンジンはSmartyということだったのだけど、今見直すとテンプレート継承できないのがつらいので、できるようなプラグインを書いた。多段階の継承もできるよ。
はじめに
DjangoとかZopeのTALとかrhacoとか最近のテンプレートエンジンはみんなテンプレート継承ができる。で、Smartyでもできたらいいのになぁ、ということで作った。
テンプレート継承は、オブジェクト指向の継承だと、親クラスで定義されたメソッドを子供のクラスでオーバーライドしたり、abstractなやつを実装したりして、子供のほうで詳細な部分を指定していく。ソレと同じように、親テンプレートで定義してあるブロックを、子供テンプレートでオーバーライドしたりできたらいいなぁ、というもの。
なんでテンプレート継承がしたいかというと・・・。Smartyのテンプレートの作り方って言うと、hoge.tplの中で最初にinclude file=”header.tpl”つぎに内容を書いて、include file=”footer.tpl”ってやるかんじ。
で、それだとだるいよねって感じで、 SmartyでRailsライクなレイアウトテンプレートを使う という記事があったりする。しかし、この方法だとコンテンツに表示するテンプレートファイルを別途PHPのコード側で指定しないといけなくて、できればそれはテンプレートの側で完結していてほしいなぁ、と思った。
使い方
ソースコード
index.php:
<?php
require_once 'Pearified/Smarty/Smarty.class.php';
$smarty = new Smarty();
SmartyBlocks::registerTo(&$smarty);
$smarty->display('subtemplate1.html');
?>
base.html:
<html>
<head>
{include file="block:css"}
{include file="block:javascript"}
</head>
<body>
<div class="base">
base template
</div>
<div class="base">
{include file="block:sub"}
</div>
</body>
</html>
subtemplate1.html:
{block name="sub"}
<div class="subtemplate1">
subtemplate1
{include file="block:subsub"}
</div>
{/block}
{block name="css" mode="append"}
<link rel="stylesheet" href="subtemplate1.css" type="text/css" />
{/block}
{include file="base.html"}
結果
こんなかんじ:
<html>
<head>
<link rel="stylesheet" href="subtemplate1.css" type="text/css" />
</head>
<body>
<div class="base">
base template
</div>
<div class="base">
<div class="subtemplate1">
subtemplate1
</div>
</div>
</body>
</html>
構成要素
blockブロックプラグイン
{block name=”body”} 今日はいい天気だ。雪だけど。 {/block}
として使える。そうすると、後でblockスキーマを使ってインクルードできる。
- nameパラメータ
- 任意の文字列
- このタグで囲まれた内容を、なんと言うブロックに割り当てるか
- modeパラメータ
- [insert|replace|append]のいずれか
- タグの内容をnameに指定されたブロックの先頭に追加するのか、置き換えるのか、最後に追加するのか。多段継承するときに便利。
blockリソースプラグイン
{include file=”block:body”} でつかえる。
事前にblockブロックプラグインを用いて定義されたブロックを{include file=”block:body”}とかして読み込む。
制限
- 継承するテンプレートの指定は必ずテンプレートの最後で行う。先にblockブロックプラグインでブロックに入る内容を定義して、そのあとでblockスキーマでインクルードする。
- block:のリソースプラグインではキャッシュが効かない。常に現在の時刻を返すので。これはなんとかできそう。
参考
Trackbacks
Use the following link to trackback from your own site:
http://www.jaro68.jp/sett4/blog/trackbacks?article_id=smarty-template-inheritance&day=03&month=02&year=2008