- 2007-04-11
- php
2007-04-12 追記:※注意!結論の「バッククォートで括ると便利」というのはあってますが、そこまでの過程はほとんどウソでした。そのうち直します。
CakePHPでViewにSmartyViewを使う時、おおざっぱにいうとこんな動きになっています。
- コントローラがビューに変数を渡す
- ビューがSmartyに変数を渡す(ついでに自分自身をviewというSmarty変数に登録する)
- レンダリング
このように、変数のコピーが2度発生します。
{$post.id} // これはSmartyの変数
{$html->link('linkto', $post.id)} // この$postはPHPの(SmartyViewがセットした)変数
ここで困るのは、レンダリング中にセットされた変数はSmartyの世界からしか見えないこうことです。 典型的な例としてはループで使われる変数です。
ブログチュートリアルを例にとると、
<?php foreach ($posts as $post): ?>
<tr>
<td><?php echo $post['Post']['id']; ?></td>
<td>
<?php echo $html->link($post['Post']['title'], "/posts/view/".$post['Post']['id']); ?>
これをSmatryで書くとこうなります。
{foreach from=$posts item=post}
<tr>
<td>{$post.Post.id}</td>
<td>
{*$html->link($post.Post.title, "/posts/view" . $post.Post.id) これはエラー*}
{*$html->link($post.Post.title, "/posts/view/$post.Post.id") これは予想通りに動かない*}
<a href="{$html->url("/posts/view/")}{$post.Post.id}">{$post.Post.title}</a>
$postは実行時にセットされる変数なので、$html->link()から参照することができません。
なので最後の例のように$html->link()ではなく$html->url()を使わないとダメなのかなぁと思っていましたが、
こんな風に書けることに気づきました。
{$html->link($post.Post.title, "/posts/view/`$post.Post.id`")}
Smartyではバッククォートで評価順を制御することができるようです。
ついでにこちらもどうぞ。