QUOIT Blog

Smartyのオプションを作る

この記事は6年以上前の記事です。情報が古い場合がありますのでお気を付け下さい。

僕はSmarty(テンプレートエンジン)をよく使うのですが、ちょっとこういう機能欲しいなーということがありまして、マニュアルを探してみたらなかったので、ないなら作っちゃえばいいじゃんというメモ。

簡単に言うと、Smartyのテンプレート側に埋め込む変数タグ {$hoge} に使うオプション {$hoge|nl2br} みたいなのを自作するっていうこと。

自分で作るとは言ったものの、その前にまずはここを見てください。

Smartyマニュアル 第5章変数の修飾子

別にめんどくさかったら見なくてもいいです。

重要なのは次の部分。

変数の修飾子は、 変数 や カスタム関数 や文字列を修飾して出力することができます。修飾子を適用するには、 変数名の後に | (パイプ) と修飾子の名前を指定します。 また、修飾子はその動作に影響を及ぼす追加のパラメータを受け入れる場合もあります。 そのパラメータは修飾子の後に続き、: (コロン) によって区切られます。 また、すべての PHP 関数は、暗黙的に修飾子として使用でき (あとで説明します)、修飾子は 組み合わせる こともできます。

つまり、独自に設定された修飾子じゃなくても、PHPの変数が普通に使えるってことです。なにそれ便利。

だから、こんなこともできちゃう。

{$hoge|strtr:"みどり":"あか"}

これを見て、なんか自分で拡張できそうだなーと思ったらできました。

やり方は以下。

【目的】 {$hoge|href} と書くと、変数に含まれたURLにリンクを貼るSmartyプラグインを作る
ファイル名を「modifier.href.php」とします。
コードは以下。


function smarty_modifier_href($string)
{
    return preg_replace("/s?https?:\/\/[-_.!~*'()a-zA-Z0-9;\/?:\@&=+\$,%#]+/","$0",$string);
}

他のファイルを参考にするとわかりますが、
・上部に作者情報とかのコメントを書く
・ファイル名とファンクション名を一致させる
というのがSmartyプラグインの通例のようです。

あとはSmartyプラグインのフォルダ(Smarty/plugins)に設置すれば使えます。

まぁコピペすれば使えるんですけど、一応置いておきますね。

ダウンロード

Smartyプラグインのファンクションを生成した場合、第一引数は暗黙的に割り当てた変数の内容が入ります。

他の引数は第二引数以降に入ります。


function smarty_modifier_href($string,$target='_blank')
{
    return preg_replace("/s?https?:\/\/[-_.!~*'()a-zA-Z0-9;\/?:\@&=+\$,%#]+/","$0",$string);
}

とした場合、

{$hoge|href:”_self”}

と書けばよいのです。
ちなみにSmartyでは、「:」で区切ると複数の引数を渡せます。
(例: {$hoge|href:”_self”:”piyo”} )

というわけで、簡単に作れますよというお話でした。

2 comments for “Smartyのオプションを作る

  1. kn
    2011年11月18日 at 9:39 AM

    少し補足&意見を。

    > ファイル名とファンクション名を一致させる
    > あとはSmartyプラグインのフォルダ(Smarty/plugins)に設置すれば使えます。

    これは、オートロードの対象になるための条件ということであって、そこに必ず設置する必要はないようです。

    つまり、smartyを利用するプログラムが読み込むソース中のどこかに、関数定義(smarty_modifier_[オプション名])があれば、今のところ使えるみたいですね。

    もっともこれは、(pluginへ設置しようとも)黒箱破りな方法だし、将来的に利用不可になるかもしれないですね。

    本来は、register_modifier() を使うべきなのでしょう。しかし、引数にクロージャをサポートしないうちは、結局グローバルな関数定義が必要ということですから、個人的には気持ちが悪い。結局、smarty_modifier_[オプション名] を定義してしまったほうがマシかな(?)

  2. yakumo
    2011年11月25日 at 12:39 AM

    knさん>
    コメントありがとうございます。
    なるほど…そこまで考えてませんでした。
    確かに裏技的なやり方なので、本来は推奨されないでしょうね^^;
    手っ取り早いと思って使ってしまいましたが…w
    その点についての注意は必要だったかもしれません。ありがとうございます!