zend 2: Automatically inject a template for all ac

2019-09-05 15:57发布

问题:

I am using the Zend skeleton application.

I want to have a sub menu bar (via a template) injected underneath the default site wide menu bar, but I don't want to modify the site wide app settings, I'd like to just have it in the module.

Looking at examples it seems I would have to manually inject the menu bar template in each of my controller's actions and in every template where I want it to appear like this:

public function indexAction() {
    $view = new ViewModel();

    $subNavView = new ViewModel();
    $subNavView->setTemplate('helpdesk/helpdesk/subNav');
    $view->addChild($subNavView, 'subNav');

    return $view;
}

public function someAction() {
    $view = new ViewModel();

    $subNavView = new ViewModel();
    $subNavView->setTemplate('helpdesk/helpdesk/subNav');
    $view->addChild($subNavView, 'subNav');

    ....do something add variables to $view....

    return $view;
}

public function someOtherAction() {
    $view = new ViewModel();

    $subNavView = new ViewModel();
    $subNavView->setTemplate('helpdesk/helpdesk/subNav');
    $view->addChild($subNavView, 'subNav');

    ....do something add variables to $view....

    return $view;
}

...etc

And the "echo $this->subNav" in every template.

Is this the right way to do this or is there a way to have my module automatically include this template for every page (without modifying anything outside of the individual module)?

I read the docs, but I'm still confused on how to achieve this or if this is even possible.

回答1:

If you want to update the view model directly, you could also do that in onBootstratp of your Module class:

public function onBootstrap($e) {
    $view = $e->getApplication()->getMvcEvent()->getViewModel();
    $subNavView = new ViewModel();
    $subNavView->setTemplate('helpdesk/helpdesk/subNav');
    $view->addChild($subNavView, 'subNav');
}

And of course you already have something like this in your layout:

<?php echo $this->subNav; ?>

You could also consider using the standard partial view helper and setting the template path as a variable in your model from your Module.php like this:

public function onBootstrap($e) {
    $viewModel = $e->getApplication()->getMvcEvent()->getViewModel();
    $viewModel->subNav = 'application/navigation/subNav.phtml';
}

Then you modify your /module/Application/view/layout/layout.phtml something like this

<?php if ($this->subNav) {
    echo $this->partial($this->subNav);
} ?>

The drawback to this idea is that then you have a view model variable which will show up in all your models. This can be annoying, for example, in json results.

Last idea, you might want to consider a navigation view helper. You could implement https://github.com/spiffyjr/spiffy-navigation if you don't want to build one from scratch.

If you solve it with a view helper, either custom or pre-existing package such as Spiffy Jr's, then you'd modify your layout so it uses the helper something like this, and all the logic is provided by the helper class:

<?php echo $this->navigationMenu(); ?>

All three ideas will unclutter your controllers and let your Module set up the subNav in a way that is relevant to it, such as which routes it is valid for, etc.