24

i have a layout used by all my views and i need to assign a variable from a controller to this layout , if i use this method on a controller it doesn't work :

public function indexAction()
{
    return new ViewModel( array(
        'testvar' => 'bla',
    ));
}

anyone can help me ?

thanks

3
  • it will work, how do you try to access 'testvar'? Commented Nov 13, 2012 at 11:56
  • i use $testvar , but i forgot to say the layout is in the folder Application/view/layout , and my controller is in an other module .. maybe it's the problem .. i thought the layouts in application could be used anywhere . Commented Nov 13, 2012 at 12:03
  • 2
    Ah, you want to use the var at layout.phtml and not inside your action view-scripts? Commented Nov 13, 2012 at 12:15

6 Answers 6

67

There are three ways to achieve this in ZF2 (in your controller):

First:

$this->layout()->someVariableName = 'Some value for the variable';

Second:

$this->layout()->setVariable('someVariableName', 'Some value for the variable');

Third:

$this->layout()->setVariables(array(
    'someVariableName' => 'Some value for the variable',
    'anotherVariable'  => 'Some value for another variable',
);
Sign up to request clarification or add additional context in comments.

2 Comments

How would you then access them?
@FrancescoD.M. Simply access them by their names inside your layout file like any other variable like echo $someVariableName;.
38

Rob Allen has posted a great article about how to access view variables in another view model (e.g.: layout)

Basically the following code, placed inside your layout.phtml, will match your needs:

<?php
$children = $this->viewModel()->getCurrent()->getChildren();
$child = $children[0];
?>
<!-- some HTML -->
<?php echo $this->escape($child->myvar);?>

6 Comments

Thanks for this suggestion, it works - but still looks complicated :/ blaming-zf2
@MonkeyMonkey This is because a thing like this shouldn't usually be neccessary. There's better ways (like ViewHelpers / Widgets), than doing this kind of thing. But it can be usable if you really have a use case.
I can see how this shouldn't be necessary, but how would you suggest doing it the right way then? Because accessing viewhelpers through the pluginmanager is also against the semantic rules as you can read all around the web. It's pretty common to set a header description/title action-specific--or load some javascript/dom parts based on what API you might need(facebook) that you only might need on a specific action..
There is a headTitle() ViewHelper - can you further explain your "against semantic rules as u can read all around the web"? This statement appears quite "wrong" :P
hehe. what i meant was, accessing viewhelpers in controllers isn't advised and also considered doing it wrong. but like you said, the head* family is there to change the title and meta, and its quite normal to chance the title and description action-wise, for SEO reasons or whatever.. so if accessing viewhelpers in your controller isn't "semantically right", as i named it, how would you do this?
|
8

Have you tried:

$this->layout()->testvar = 'bla';

Using the layout controller plugin you can retrieve the ViewModel object that is used in layout.phtml.

Comments

3

Because ZF2 ViewModel is tree structure, the layout actually is the root node of ViewModel, the ViewModel in your controller will be add as a child node of layout.

You could access layout ViewModel by access MvcEvent, try this in your controller:

public function indexAction()
{
    $events = $this->getServiceLocator()->get('Application')->getEventManager();
    $events->attach(MvcEvent::EVENT_RENDER, array($this, 'setVariableToLayout'), 100);
}

public function setVariableToLayout($event)
{
    $viewModel = $this->getEvent()->getViewModel();
    $viewModel->setVariables(array(
        'testvar' => 'bla',
    ));
}

Comments

1

See the add View Variable section below

add it in your module.php file.

You can also do this using view helper.

/**
     * Remember to keep the init() method as lightweight as possible
     * 
     * @param \Zend\ModuleManager\ModuleManager $moduleManager
     */
    public function init(ModuleManager $moduleManager) 
    {        
        $events = $moduleManager->getEventManager();
        $events->attach('loadModules.post', array($this, 'modulesLoaded'));
        $events->attach('onBootstrap', array($this, 'bootstrap'));

        $sharedEvents = $events->getSharedManager();
        $sharedEvents->attach(__NAMESPACE__, 'bootstrap', array($this, 'bootstrap'), 100);
        $sharedEvents->attach(__NAMESPACE__, 'bootstrap', array($this, 'initializeView'), 100);
        $sharedEvents->attach(__NAMESPACE__, 'dispatch', array($this, 'addViewVariables'), 201);        
    }


/**
 * 
 * @param \Zend\Mvc\MvcEvent $e
 */
public function loadConfiguration(MvcEvent $e) 
{        
    $e->getApplication()->getServiceManager()
            ->get('ControllerPluginManager')->get('AclPlugin')
            ->checkAcl($e); //Auth/src/Auth/Controller/AclPlugin      
}

/**
 * 
 * @param \Zend\EventManager\EventInterface $e
 */
public function bootstrap(Event $e) {

    $eventManager = $e->getParam('application')->getEventManager();
    //$app->getEventManager()->attach('dispatch', array($this, 'checkAcl'), 100);
}

/**
 * pass variables to layout
 * 
 * @param \Zend\EventManager\EventInterface $e
 */
public function addViewVariables(Event $e) 
{
    $route = $e->getRouteMatch();
    $viewModel = $e->getViewModel();
    $variables = $viewModel->getVariables();
    if (false === isset($variables['controller'])) {
        $viewModel->setVariable('controller', $route->getParam('controller'));
    }
    if (false === isset($variables['action'])) {
        $viewModel->setVariable('action', $route->getParam('action'));
    }

    $viewModel->setVariable('module', strtolower(__NAMESPACE__));        
}

/**
 * 
 * @param \Zend\Mvc\MvcEvent $e
 */
public function initializeView(Event $e) 
{

}

and in your layout you can simply access those variables using their name such as $module, $action, $controller according to above example

Comments

0

If you want to pass values to your layout globally then you can refer this : https://stackoverflow.com/a/21455737/2190889

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.