Author: | Shogo Kawahara <kawahara@bucyou.net> Twitter: @ooharabucyou |
---|---|
Date: | 2010-12-05 |
License: | Creative Commons Attribution 3.0 Unported License |
Symfony アドベントカレンダー2010 の5日目です。
symfonyの設定ファイルは柔軟性が高くて好きです。YAMLが気に食わないと思えば Configuration Handler を変えることでそれが実現できます。
今回は、元からある view.yml の Configuration Handler を魔継承してオレオレルールを作りましょう。
view.yml の デフォルトの Configuration Handler を少し覗きます。
$sf_symfony_lib_dir/config/sfViewConfigHandler.class.php より引用
<?php
class sfViewConfigHandler extends sfYamlConfigHandler
{
public function execute($configFiles)
{
// parse the yaml
$this->yamlConfig = self::getConfiguration($configFiles);
// init our data array
$data = array();
$data[] = "\$response = \$this->context->getResponse();\n\n";
// 省略...
// compile data
$retval = sprintf("<?php\n".
"// auto-generated by sfViewConfigHandler\n".
"// date: %s\n%s\n",
date('Y/m/d H:i:s'), implode('', $data));
return $retval;
}
// 以下省略
と、なんとかしてPHPのコードを生成して返しているのがわかります。
ここで返されたやつが、キャッシュになるわけですね。
なるほど。Configuration Handler がやることはわかりました。
Note
この仕組については
A Gentle Introduction to symfony | 第19章 - symfony の設定ファイルをマスターする
を読むと、より納得ができるかもしれません。
プロジェクトの config/ に config_handlers.yml を置いて、独自の Configuration Handler を設定するという手段もありますが、 僕は1つプラグインをつくって、いろいろなプロジェクトで使い回しをするというのが大好です。 つまり、 symfony プラグインを作成することにします。
とりあえず、今回は sfViewYamlExtraPlugin という名前にしました。 ちゃちゃっと使うディレクトリなどを用意します。
例
$ mkdir plugins/sfViewYamlExtraPlugin
$ cd plugins/sfViewYamlExtraPlugin
$ mkdir config
$ mkdir lib
$ mkdir lib/config
とりあえず例なので、 view.yml に記述された flag の設定値を取り出し、 sfConfig に flag という設定として書きこむという簡単な拡張を書きます。
plugins/sfViewYamlExtraPlugin/lib/config/sfViewConfigHandlerExtra.class.php
<?php
class sfViewConfigHandlerExtra extends sfViewConfigHandler
{
public function execute($configFiles)
{
// 通常の結果を取得 <?php ..... という形で来る
// この処理は YAMLのロードを含むので最初にやる
$pResult = parent::execute($configFiles);
// sfViewConfigHandler のやり方を真似ています。
$data = array();
$first = true;
foreach ($this->yamlConfig as $viewName => $values)
{
// all は無視
if ($viewName == 'all')
{
continue;
}
// テンプレート用の設定がある場合
$data[] = ($first ? '' : 'else ')."if (\$this->actionName.\$this->viewName == '$viewName')\n".
"{\n";
$data[] = $this->addFlag($viewName);
$data[] = "}\n";
$first = false;
}
$data[] = ($first ? '' : "else\n{")."\n";
// デフォルトの設定
$data[] = $this->addFlag();
$data[] = ($first ? '' : "}")."\n";
// 通常の結果と今回拡張したものを連結
$retval = $pResult.sprintf(
"// auto-generated by sfViewConfigHandlerExtra\n%s\n",
implode('', $data));
return $retval;
}
protected function addFlag($viewName = '')
{
// getConfigValue() で継承関係を配慮して設定値を取り出します
$flag = $this->getConfigValue('flag', $viewName);
if (null !== $flag)
{
return sprintf(" sfConfig::set('flag', %s);", var_export($flag, true))."\n";
}
return "";
}
}
Note
PHPのコード生成途中で、$this を埋め込んでいます。 これは実際に動くときには sfPHPView のインスタンスになります。
sfPHPView::configure() を見ると、謎が解けるかもしれません。
plugins/sfViewYamlExtraPlugin/config/config_handlers.yml
modules/*/config/view.yml:
class: sfViewConfigHandlerExtra
file: %SF_PLUGINS_DIR%/sfViewYamlExtraPlugin/lib/config/sfViewConfigHandlerExtra.class.php
プラグインを有効にするのを忘れずに。
config/ProjectConfiguration.class.php のsetup()中に以下を追加
$this->enablePlugins('sfViewYamlExtraPlugin');
これで、view.yml に対して sfViewConfigHandlerExtra が使われるようになります。
試しに、どこかのモジュールの config/view.yml に、
all:
flag: true
などと書いてみて、テンプレートで
<?php var_dump(sfConfig::get('flag')); ?>
とすると、設定した値が表示されます。
皆が Symfony2 or Doctrine2 に飛び込んでいくなかで、まだまだ現役なsymfony1.4のネタをやらせていただきました! この情報が誰かの役にたったのならば嬉しいです。
次は hidenorigoto さんがやるようです。楽しみですね!
別で進行中の OpenPNE3.6 Advent Calendar も応援してください!
Symfony Advent 2010では12月1日から12月24日までを使って日替わりでsymfonyでイイなと思った小さなtipsから内部構造まで迫った解説などをブログ記事にして公開していくイベントです。
参加については ATND で参加表明の上、
GoogleGroupの Symfony Advent 2010 に追加リクエストを送信ください。
Symfony Advent 2010チーム一同、あなたの参加をお待ちしております。
Note
Symfony Advent 2010はsymfony好きな有志で集まったチームです。