CakePHPのHtmlHelper->scriptBlock()やscriptStart()は$scripts_for_layoutで出力されない
CakePHP 1.2の事は分かりませんが、1.3系ではHtmlHelperでJavaScriptをViewテンプレートに書いていきます。scriptタグを書いても良いのかもしれませんが、HtmlHelperを使って書いたらスクリプトをバッファに貯めておいて にまとめて出力してくれます。まぁ折角なので使っていたら、layoutファイルに書いても $scripts_for_layout で出力されなくて困りました。
結論
layoutファイルに書いた scriptStart() scriptBlock() では array('inline' => true) じゃないとスクリプトが出力されない。
逆を言えば $options = array('inline' => false) を指定しても $scripts_for_layout で出力されない。
なので layoutファイルでは echo $html->scriptBlock('',array('inline'=>true)) や echo $html->scriptStart(array('inline'=>true)) を使う。*1
あと、とりあえず echo はしておいたほうが無難。
echo $html->scriptStart(); echo $html->scriptEnd(); echo $html->scriptBlock();
$html->scriptStart(array('inline' => false)) や $html->scriptBlock('',array('inline' => false)) で使ってるなら、$scripts_for_layout で出力されるので echo は要りません。ただ、array('inline' => true) に変更した場合は、script要素が return されてくるので、echo しないと何も出力されません。CakePHPのHelper は基本的に出力するには echo するスタイルで統一されてるので、これらもとりあえず echo しておいたほうがよさそう。じゃないと、array('inline' => true) に切り替えた時に何も出なくて無駄にはまりそう。
解説
簡単に言えば、layoutのレンダリング時に $scripts_for_layout に値をセットしてからレンダリングするのに、layoutそのものに書いた scriptBlock() はレンダリング時に処理されるからです。
<?php function renderLayout($content_for_layout, $layout = null) { $layoutFileName = $this->_getLayoutFileName($layout); if (empty($layoutFileName)) { return $this->output; } $dataForLayout = array_merge($this->viewVars, array( 'content_for_layout' => $content_for_layout, 'scripts_for_layout' => implode("\n\t", $this->__scripts), )); if (!isset($dataForLayout['title_for_layout'])) { $dataForLayout['title_for_layout'] = Inflector::humanize($this->viewPath); } if (empty($this->loaded) && !empty($this->helpers)) { $loadHelpers = true; } else { $loadHelpers = false; $dataForLayout = array_merge($dataForLayout, $this->loaded); } $this->_triggerHelpers('beforeLayout'); $this->output = $this->_render($layoutFileName, $dataForLayout, $loadHelpers, true); if ($this->output === false) { $this->output = $this->_render($layoutFileName, $data_for_layout); trigger_error(sprintf(__("Error in layout %s, got: <blockquote>%s</blockquote>", true), $layoutFileName, $this->output), E_USER_ERROR); return false; } $this->_triggerHelpers('afterLayout'); return $this->output; }http://api13.cakephp.org/view_source/view/#line-459
<?php $dataForLayout = array_merge($this->viewVars, array( 'content_for_layout' => $content_for_layout, 'scripts_for_layout' => implode("\n\t", $this->__scripts), ));http://api13.cakephp.org/view_source/view/#l-465
View::renderLayout() のここで $scripts_for_layout に出力するデータがセットされてます。
<?php $this->output = $this->_render($layoutFileName, $dataForLayout, $loadHelpers, true);http://api13.cakephp.org/view_source/view/#l-482
そして17行下のここで、layoutがレンダリングされてます。layoutに書いた $html->scriptBlock('',array('inline'=>false)) や $html->scriptStart(array('inline'=>false)) は、ここで初めて実行されますが、その時 $scripts_for_layout の内容は確定済みというわけです。
*1:デフォルト値がarray('inline'=>true)なので省略可能