Search code examples
phpcakephplayoutcakephp-2.1

CakePHP set variable in view for use in layout


I've got a CRUD application, and in my views there are links to actions from various controllers e.g.

<?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..

Now, I also have a default.ctp layout with a sidebar that I'd like to dynamically populate with the action links from each view being rendered. I know that I can move the actions from my controllers to their respective models and set variables in a beforeRender() callback within a controller, however i'd like to keep my actions within the controllers, and instead set an array within a view and pass it to the default.ctp layout. Here's what I have so far:

Docs/index.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);

Layouts/default.ctp:

print_r($links);

This returns Notice (8): Undefined variable: links [APP\View\Layouts\default.ctp, line 93] I'm guessing because the layout is being rendered before the view.

What's the best way to go about doing this without moving actions to their models?


Solution

  • $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);
    

    ... should be in the controller.

    The layout will see any variable that is available in the view. So $links will be visible in the layout. (and if you really have to set vars from the view instead of the controller, you don't need to use $this->set() in the view, just use $links = ...).