Do You PHP はてブロ

Do You PHPはてなからはてブロに移動しました

sfSmartyViewPluginあれこれ

「えー!sfSmartyViewPlugin使っていいのは小学生(ry」と言われようが、使わざるを得ない状況なので。
sfSmartyViewPluginはsymfonySmartyを使うためのプラグインですが、dinoのブログで叩かれたり(?)してるように、手直ししてやらないと使い勝手が悪いです。
とりあえず、「こんな感じで使ってますよー」的なものをまとめてみました。

Smartyのdefault_modifierでescapeしたいよ

まあ、sfSmartyViewPluginに限らず、Smarty使うときはいつもやってる話ですが。
Smartyのdefault_modifierでescapeを指定できると、変数出力時のエスケープ漏れがなくなるのでかなり良い感じなんですが、Smarty付属のsmarty_modifier_escapeは内部で表示する値の型判定していません。なので、default_modifierにを指定すると「配列やオブジェクトが渡された!」といって怒りまくります。
で、配列をガッと出力するようなことはしてないので、次のような薄いラッパーを作って、default_modifierに指定してます。

<?php
require_once 'modifier.escape.php';
function smarty_modifier_escape_wrapper($string, $esc_type = 'html', $char_set = 'UTF-8')
{
    switch (gettype($string)) {
    case 'string':
        return smarty_modifier_escape($string, $esc_type, $char_set);
    default:
        return $string;
    }
}

テンプレートで$sf_requestとか$sf_contextとか使いたい

ベタベタですが、sfSmartyView.class.phpのrenderFileメソッドに追記してます。あ。先ほどのdefault_modifierの設定もここでやってます。

<?php
                   :
            self::$smarty->assign($this->getAttributeHolder()->getAll());
        }

        /**
         * added
         */
        self::$smarty->default_modifiers = array('escape_wrapper:"html"');
        self::$smarty->assign('app_template_dir', sfConfig::get('sf_app_template_dir'));

        self::$smarty->assign('sf_context', $this->getContext());
        self::$smarty->assign('sf_params', $this->getContext()->getRequest()->getParameterHolder());
        self::$smarty->assign('sf_request', $this->getContext()->getRequest());
        self::$smarty->assign('sf_user', $this->getContext()->getUser());
        self::$smarty->assign('sf_view', $this);

        $er = error_reporting();
                   :

Helperをどうにかする

開発環境などでは「/frontend_dev.php」、本番環境では「/」でアクセスさせたい訳なんですが、sfPHPViewだとUrlHelperを使うとこの辺をうまくやってくれます(実際にはlink_to関数から呼ばれるurl_for関数)。で、Smartyのテンプレートでどうするかなんですが、とりあえずmodifierでurl_for関数を呼び出すようなHelperを作ることで対応してます。

<?php
class SmartyUrlHelper {
    public static function url_for($internal_uri, $absolute = false)
    {
        return url_for($internal_uri, $absolute);
    }
}

sfSmartyView::registerModifier('url_for', array('SmartyUrlHelper', 'url_for'));

テンプレートでは、見栄え悪いですが

<a href="{"@setting"|url_for}" ...

な感じで、

  • /frontend_dev.php/setting
  • /setting

を出し分けられます。
こんな感じで、ほかのHelperも使おうと思えば使えるはずです。

そもそもHelperが足りない

dinoのブログにもありますが、インストール直後は「Unable to load "SmartyHelperHelper?.php" helper in...」が出ますが、Helperファイルが足りないことが原因です。http://www.symfony-project.org/forum/index.php/fa/699/ から不足しているHelperをダウンロードして、

[プロジェクト]/plugins/sfSmartyViewPlugin/lib/helper/

に上書き保存すればOKです。

まとめ(?)

ここしばらくsymfony+sfSmartyView+Smartyで使っていますが、symfonyのsfPHPViewで使えるはずのHelperなどの便利機能がそのままでは使えません。また、View用のプラグインとか多くのドキュメントとか、その辺のリソースも素のままでは使えません。これは結構でかいと思います。
Smartyテンプレートに慣れている人的リソースが多い」とか「Smartyで作られている現行システムを単純にsymfonyに載せ替えたい」という場合は選択肢の1つとしても良いかもしれません。
採用するかどうかは、これらの天秤ですかねぇ。。。ちなみに、今このプラグインを使っている理由は後者です。