CakePHP在视图中设置变量以用于布局


CakePHP set variable in view for use in layout

我有一个CRUD应用程序,在我的视图中有来自各种控制器的操作链接,例如

<?php echo $this->Html->link(__('List Docs'), array('controller' => 'docs', 'action' => 'index')); ?>
<?php echo $this->Html->link(__('Add Doc'), array('controller' => 'docs', 'action' => 'add')); ?>
<?php echo $this->Html->link(__('List Images'), array('controller' => 'images', 'action' => 'index')); ?>
<?php echo $this->Html->link(__('Add Image'), array('controller' => 'images', 'action' => 'add')); ?>
//etc..

现在,我还有一个带有侧边栏的default.ctp布局,我想用每个渲染视图的动作链接动态填充它。我知道我可以将操作从控制器移动到它们各自的模型,并在控制器内的beforeRender((回调中设置变量,但我希望将操作保留在控制器内,而是在视图内设置一个数组并将其传递到default.ctp布局。到目前为止,我拥有的是:

文档/索引.ctp

$links_array = array(
    'list_docs' => array('controller' => 'docs', 'action' => 'index'),
    'add_doc' => array('controller' => 'docs', 'action' => 'add'),
    'list_images' => array('controller' => 'images', 'action' => 'index'),
    'add_image' => array('controller' => 'images', 'action' => 'add')
    );
$this->set('links', $links_array);

布局/default.ctp

print_r($links);

我猜这会返回Notice (8): Undefined variable: links [APP'View'Layouts'default.ctp, line 93],因为布局是在视图之前渲染的。

在不将动作转移到他们的模型上的情况下,最好的方法是什么?

$links_array = array(
'list_docs' => array('controller' => 'docs', 'action' => 'index'),
'add_doc' => array('controller' => 'docs', 'action' => 'add'),
'list_images' => array('controller' => 'images', 'action' => 'index'),
'add_image' => array('controller' => 'images', 'action' => 'add')
);
$this->set('links', $links_array);

应该在控制器中。

布局将显示视图中可用的任何变量。因此$links将在布局中可见。(如果您真的必须从视图而不是控制器设置vars,则不需要在视图中使用$this->set(),只需使用$links = ...即可(。

您是否考虑过使用View块?该手册甚至使用了侧边栏作为使用示例;使用视图块

// In a view file.
// Create a navbar block
$this->startIfEmpty('navbar');
echo $this->element('navbar', array('links' => $links_array));
$this->end();
// In a parent view/layout
echo $this->fetch('navbar');

这甚至更好:为脚本和css文件使用块

您可以定义块名称,如scriptBottom
将内容附加到它,并在布局或其他视图的正确位置显示。

// In your view
$this->Html->script('carousel', ['block' => 'scriptBottom']);
$this->Html->script('custom', ['block' => 'scriptBottom']);
//or
$this->startIfEmpty('scriptBottom');
$this->append('scriptBottom', $this->script('custom2'));
// In your layout or another view
<?= $this->fetch('scriptBottom') ?>