Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to pass variables to layout.phtml globally in ZF2?

I want to pass a series of variables to my layout.phtml throughout the whole application(globally). And by that I mean I don't wanna use

$this->layout()->someVar = someValue;

in each and every action I've got, since it would be a lot of extra work and code. So is there a way to do it in just one place? Or What I mentioned is all I got! Hope not :)

Maybe using sessions ? – Remi Thomas

Thanks for the solution. For the time being that's what I'm using. For logged-in user info, system and layout settings and an ACL list. But the problem is that I have to define a new object in the layout.phtml which I don't think is appropriate, is it? I read somewhere that whatever data we need to use in view models should be passed to it using controller actions. And specially I'm not a fan of cutting corners, so if there's a clean way to do this I'd rather not do it this way. And recently I have to get the number of unread messages for each user and use it in layout.phtml. So if I do it in layout.phtml it's a LOT of php script inside a view model or layout.

Thanks

like image 769
Milad.Nozari Avatar asked Aug 26 '13 08:08

Milad.Nozari


3 Answers

The best and cleanest way is using a ViewHelper, as Orochi suggests. Here some instructions to create your own ViewHelper: http://framework.zend.com/manual/2.2/en/modules/zend.view.helpers.advanced-usage.html. It's not too complex ;)

However your problem could be resolved also in another way. Supposing the variables you need contain values provided by services already present in your application (and then exposed by ZF2 ServiceManager), you could add some lines on the "onBoostrap" function inside your Module.php (e.g. on Application module).

Here an example:

public function onBootstrap($e) {

    $serviceManager = $e->getApplication()->getServiceManager();
    $viewModel = $e->getApplication()->getMvcEvent()->getViewModel();

    $myService = $serviceManager->get('MyModule\Service\MyService');

    $viewModel->someVar = $myService->getSomeValue();

}

In this way you write the assignment in only one place. The variable is then accessible as usual:

$this->layout()->someVar;
like image 54
stefanovalle Avatar answered Nov 14 '22 18:11

stefanovalle


This is exactly what you want...

// Do this inside your Controller before you return your ViewModel
$this->layout()->setVariable('stack', 'overflow');

// Then inside your layout.phtml
echo $this->stack;

No view helpers, no event manager, no service manager or other class method juggling. Why do people on Stack make things so darn complicated sometimes?

like image 38
Timothy Perez Avatar answered Nov 14 '22 18:11

Timothy Perez


Create your own ViewHelper for that.

EDIT:

That's how I do it: Inside your Module's src folder, I create new View folder then in this View folder, I create another folder called Helper. In this folder i create my helper classes. So, for example, I create Navigation.php file. In this file I create a class called Navigation, which extends from AbstractHelper (use Zend\View\Helper\AbstractHelper). Then I write code inside public function __invoke(), which also returns some result. You also have to add your view helper class to 'view_helpers' inside module's config/module.config.php, something like that:

'view_helpers' => array(
    'invokables' => array(
        'nav' => 'Application\View\Helper\Navigation',
    ),
),

Then you can call your 'nav' as a method anywhere inside your view's or layout, for example nav();?>

like image 3
MaTTo Avatar answered Nov 14 '22 19:11

MaTTo