d.hetima RSSフィード

2006-12-17

CakePHP の view の elements がアクセスできる変数

CakePHP で view(thtml) の入れ子を実現するには、elements を使うのが常套のようですが、CakePHP マニュアル日本語訳の 8章 ビュー には、

エレメントはデフォルトでは、どのデータにもアクセスできません。データにアクセスできるようにするには、パラメータに名前を付けて、配列の形で入れます。

と書いてあり、controller で set した値も使えないように読み取れます。本家の CakePHP Manual - Viewsにも「The Element by default has no access to any data.」と書いてあります。elements の thtml で使いたい変数は、

<?php
  echo $this->renderElement('helpbox', array("helptext" => "this text is very helpful."));
?>

という風に明示して渡さないといけないようです。これではいちいち面倒くさいので別の方法を考えないといかんかなあと思ったのですが、controller で set した値は elements の中でも使えてしまいました。ぐぐってみると、(日本語で)この件に関して書かれてあるページは見つからないので、わざわざ取り上げるまでもない常識な気もしてきましたが。


view.php の renderElement() を見てみると、

return $this->_render($elementFileName, array_merge($this->viewVars, $params), false);

と書かれてあり、renderElement() の引数に渡した値と、$this->viewVars がマージされています。つまりは set した値は使えるということです。

CakePHP Wiki :: docs:view:renderelement には「Foo (エレメント) has access to all of the variables that the calling view has」と書かれていました。更に続けて「but! any temporary variables created within the view will NOT be available to the template」とも書かれています。temporary variables というのはつまり thtml ではじめて出現した変数ですね。

//index.thtml
<?php //ここではじめて定義
$local_val='hello'; ?>

<?php echo $local_val; /* OK */ ?>

<?php //この subview.thtml では $local_val を参照できない
echo $this->renderElement('subview'); /* NG */ ?>

<?php //こうすれば $local_val(と同じ内容の変数)を参照できる 
echo $this->renderElement('subview', array('local_val'=>$local_val)); /* OK */ ?>

ちなみに、既に set されている変数と同じ名前の変数を渡すと上書きされます。

マニュアルを書き換えるとしたらこんな感じかな?

elements の中でも controller で set した値がそのまま使えます。追加の変数を使いたい場合は、renderElement() の第2引数に連想配列で渡してください。例えば、ループの中で複数回 elements を呼び出す場合に、ループカウンターあるいは出力したいデータそのものを渡す用途に利用できるでしょう。

とにかくまあ、こういう仕様であれば、簡便に使えそうなので一安心。

sdozonosdozono 2006/12/18 11:17 参考になります。マニュアルの翻訳を変えてしまうのはまずいと思うので、【訳注】でこのページにリンクを張りました。(これくらいはやっていいかなぁと……。)doc に関しても Ticket は出せるみたいですが、どうしましょうかね……。

hetimahetima 2006/12/18 16:26 仕様が変わったけれどマニュアルは古いまま、って感じですかね? Ticketに関しては、私の英語は怪しいので、出すかどうか含めてお任せしてよろしいですか。

cyndycyndy 2008/08/25 14:17 私も今、このことに気づきました。えーー!!と言う感じです。いままで、
renderElementを何回も書いていて、すごくめんどくさいと感じていたのですが。。
マニュアルもまだ変更されてませんね;;

スパム対策のためのダミーです。もし見えても何も入力しないでください
ゲスト

コメントを書くには、なぞなぞ認証に回答する必要があります。