ドキュメントルート内にHTMLファイルを置いたらSmartyで処理されるようにする

Smartyはよく使っていたものの、既にCakePHPに組み込まれたものを全社で使いまわしていたため、インストールからちゃんとやったことがなかったのでやってみました。それだけじゃ面白くないので、ドキュメントルート内でURLに対応する場所へHTMLファイルを.htmlで置いたらSmartyで処理される設定を考えてみました。

普通のインストールは公式ドキュメントを見てね。
基本的なインストール | Smarty.

そんなわけで、とりあえず基本のインストールはできている前提。適当なPHPファイルでSmartyをrequire()したらSmartyクラスを呼び出せる状態。そんで、普通なら単に

$smarty->display('template.tpl');

みたいな感じですね。

まずは.htmlへのリクエストを全てindex.phpへ回します。別にindex.phpじゃなくてもいいです。smarty.phpとか、_smarty.phpとかでもいいかも。index.phpが特殊でなければindex.phpがいいだろうね。index.phpの場合はこんな感じ。

RewriteEngine on
RewriteCond %{REQUEST_FILENAME} -f
RewriteRule (.*).html index.php [L]

ファイルが存在したら.htmlで終わるURLをindex.phpに飛ばします。

そしたらindex.phpにテンプレートパスの判別を入れます。

if (empty($_SERVER['REDIRECT_URL'])) {
    $tpl = 'index.html';
} else {
    $here = dirname($_SERVER['PHP_SELF']);
    $tpl = substr($_SERVER['REDIRECT_URL'], strlen($here)+1);
}
$smarty->display($tpl)

REDIRECT_URLってのはApacheだけで入れてくれるっぽいので注意ですが、リダイレクトさせると本来表示させるはずだったファイルのパスが入ってくるようです。ちゃんとドキュメント化されてないっぽいし、ソースも見てないので予想です。なので不安な人はREQUEST_URIとかで実装したほうがいいですよ。

REDIRECT_URLが空の場合を分けているのは / とかでアクセスされた時のためです。DirectoryIndexに設定されてないPHPファイルだったら不要な分岐かも。でも、そこに直接アクセスされた場合ってのは考えておいた方がいいと思います。

そんな感じで出来上がりです。ついでにデリミタをコメントスタイルにするのもいいかも?

$smarty->left_delimiter = '<!--{';
$smarty->right_delimiter = '}-->';

まー、好みですけど。