Sending variables to the layout in Zend Framework
Asked Answered
R

8

39

In my project I have a number of dynamic elements that are consistently on every page. I have put these in my layout.phtml

My question is: How can I send variables into my layout from my controllers?

If I want to send things from my controller I can use:

$this->view->whatever = "foo";

And receive it in the view with

echo $this->whatever;

I cannot figure out how to do the same with my layout. Perhaps there is a better way around the problem?

Regen answered 8/10, 2009 at 13:9 Comment(0)
P
47

The layout is a view, so the method for assigning variables is the same. In your example, if you were to echo $this->whatever in your layout, you should see the same output.

One common problem is how to assign variables that you use on every page to your layout, as you wouldn't want to have to duplicate the code in every controller action. One solution to this is to create a plugin that assigns this data before the layout is rendered. E.g.:

<?php

class My_Layout_Plugin extends Zend_Controller_Plugin_Abstract
{
   public function preDispatch(Zend_Controller_Request_Abstract $request)
   {
      $layout = Zend_Layout::getMvcInstance();
      $view = $layout->getView();

      $view->whatever = 'foo';
   }
}

then register this plugin with the front controller, e.g.

Zend_Controller_Front::getInstance()->registerPlugin(new My_Layout_Plugin());

Peacoat answered 8/10, 2009 at 13:47 Comment(4)
cool thanks... I have another solution I'll post now for other peoples referenceRegen
where do I put this plugin (which folder?) and where do I set Zend_Controller_Front::getInstance()->registerPlugin(new My_Layout_Plugin());?Transubstantiate
That line will work anywhere, but the usual place to do this is in your Bootstrap classPeacoat
Please see #2401272 about where to put the plugin.Gigot
A
43

Without using helpers or plugins do :

Zend_Layout::getMvcInstance()->assign('whatever', 'foo');

After this you can use the following in your layout:

<?php echo $this->layout()->whatever; ?>

This will print "foo".

Ashurbanipal answered 10/8, 2010 at 17:46 Comment(4)
For simple assignments, this is a perfectly elegant solution! Love it. 1+Kearns
You can also assign arrays this wayAshurbanipal
Thanks for the tip. There is an extra parenthesis in that first line.Gigot
Note that you need to have called Zend_Layout::startMvc() first.Prance
R
7

I have a implemented a Base Controller which all other controllers extend.

So I have a controller...

<?php
class BaseController extends Zend_Controller_Action
{
  public function init()
  {
    $this->view->foo = "bar";
  }
}

and in the layout and/or view

<?= $this->foo ?>
Regen answered 8/10, 2009 at 14:15 Comment(3)
While I like this idea, I can't help but think a view helper would have been a better idea.Oxalate
Base controller is almost always a very BAD idea. Controller plugins and controller helpers were created specifically to address the base controller inflexibility (which can be summarized as composition over inheritance). So, unless you know all the implications - never rely on custom base controller.Burrussburry
I know I'm raising the deads here but I got the same question. @Victor Farazdagi > But then how would you pass the needed variable to the view helper?Idem
I
3

The standard view variables are available if you use the layout within the MVC. In bootstrap file, include this:

Zend_Layout::startMvc();

You must then tell each controller (or even each action, if you wanted granular control over several different layouts) which layout to use. I put mine in the init() of each controller. Here's an example, if your layout file is named layout.phtml:

$this->_helper->layout->setLayout('layout');
Imogen answered 25/9, 2012 at 14:45 Comment(0)
S
1

Well i guess you can have another solution by creating view helper.. create a file in application/views/helper and name it what ever you want abc.php then put the following code over there.

class Zend_View_helper_abc {

    static public function abc() {
        $html = 'YOUR HTML';
        return $html;
    }
}

So you can use this helper in layout like..

<?= $this->abc() ?>
Sportswear answered 13/10, 2011 at 6:12 Comment(0)
E
1
class IndexController extends Zend_Controller_Action
{

   public function init()
   {
      $this->_layout = $this->_helper->layout->getLayoutInstance();
      $this->_layout->whatever = $this->view->render('test.phtml);
   }
}

In the layout file you can call

<p><?php echo $this->layout()->whatever ?>

If in some actions if you don't want that section then:

public function viewAction()
{
   $this->_layout->whatever = null;
}
Everick answered 21/2, 2013 at 2:35 Comment(0)
P
0

As a side note, if you send json at some point in your app be careful that global view variables are not sent with the response.

Puritan answered 16/4, 2012 at 10:27 Comment(0)
F
0

View Helpers are also a good idea. I had a ecommerce website, which I had a layout.phtml with menus with categories and subcategories that I needed to bring from the database.

For this, I did the following:

Bootstrap.php:

protected function _initHelperPath() 
{

    $view = $this->bootstrap('view')->getResource('view');

    $view->setHelperPath(APPLICATION_PATH . '/views/helpers', 'View_Helper');

}

application.ini:

resources.view[]=

In views/helpers, I had a file called Menus:

class View_Helper_Menus extends Zend_View_Helper_Abstract {

    public function categories(){

       $categories = new Application_Model_DbTable_Categories();

       return $categories->fetchAll();

    }

    public function subCategories(){

        $subCategories = new Application_Model_DbTable_SubCategories();

        return $subCategories->fetchAll();

    }

}

In layout.phtml, I just had to call the specific helper, and call the methods from it:

$menu = $this->getHelper('Menus');
$categories = $menu->categories();
$subCategories = $menu->subCategories();

Hope it helps someone that needs to bring data from database to render the layout.

Fossorial answered 5/11, 2013 at 22:1 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.