-1

In my ZF2 application I have a this navigation view script:

$routeMatch = $this->getHelperPluginManager()
    ->getServiceLocator()
    ->get('Application')
    ->getMvcEvent()
    ->getRouteMatch();
$currentRoute = $routeMatch instanceof \Zend\Mvc\Router\RouteMatch ? $routeMatch->getMatchedRouteName() : null;
?>
<?php foreach ($this->container as $page) : ?>
<li <?php echo $currentRoute == $page->getRoute() ? ' class="active"' : null;?>>
    <?php echo $this->navigation()->menu()->htmlify($page, true, false) . PHP_EOL; ?>
</li>
<?php endforeach; ?>

Since the getServiceLocator() is now deprecated, I need another way to get the information about the current route into the navigation view script.

This view script gets set as partial and called in the layout.phtml:

echo $this->navigation('navigation')->menu()->setPartial('navigation/default'); 

So I got the idea to pass the need information via a template variable. I created one in the Module#onDispatch(...):

public function onDispatch(MvcEvent $mvcEvent)
{
    $viewModel = $mvcEvent->getApplication()->getMvcEvent()->getViewModel();
    $routeMatch = $mvcEvent->getRouteMatch();
    $viewModel->currentRoute = $routeMatch instanceof RouteMatch
        ? $routeMatch->getMatchedRouteName() : null
    ;
}

Now I can access it in the layout.phtml. But I don't find a way to pass it into the navigation view script, since the Zend\View\Helper\Navigation\Menu#setPartial(...)` doesn's accept any arguments for variables.

How to pass variables (especially the information about the current route) into the navigation view in Zend Framework 3?

automatix
  • 14,018
  • 26
  • 105
  • 230

1 Answers1

-1

The easiest way to do it using DefaultNavigationFactory.

Lets say we have some routes as the following

'router' => [
    'routes' => [
        'world' => [
            'type'    => Literal::class,
            'options' => [
                'route'    => '/world',
                'defaults' => [
                    'controller' => Controller\IndexController::class,
                    'action'     => 'index',
                ],
            ],
            'may_terminate' => true,
            'child_routes' => [
                'country' => [
                    'type' => Literal::class,
                    'options' => [
                        'route' => '/country',
                        'defaults' => [
                            'controller' => Controller\WorldController::class,
                            'action' => 'country',
                        ],
                    ],
                ],
            ],
        ],
    ],
],

Now we would define our navigation configuration under top-level key navigation and enable zend navigation. You may put this code into your config/autoload/global.php

Depending on the above route configuration our navigation configuration would be like the following

// configure the navigation
'navigation' => [
    'default' => [
        [
            'label' => 'Home',
            'route' => 'home',
        ],
        [
            'label' => 'World',
            'route' => 'world', // this should be the route name not route pattern like '/world'
            'pages' => [
                [
                    'label' => 'Country',
                    'route' => 'world/country',
                ],
            ],
        ],
    ],
],

// Register the navigation
'service_manager' => [
    'factories' => [
        'navigation' => Zend\Navigation\Service\DefaultNavigationFactory::class,
    ],
],

Now we would be able to call the navigation view helper using the top key navigation from the above configuration into the view script. See below

<div class="collapse navbar-collapse">
    <?php 
        echo $this->navigation('navigation')
            ->menu()
            ->setUlClass('nav navbar-nav')
            ->renderMenu(); 
        ?>
</div>

That's it!

The following shows how you can restrict routes to the user and set ACL object or user Role object through the navigation helper's setter methods. Here $this->loggedInUser, $this->acl and $this->userRole has been injected to the view script thus

<div class="collapse navbar-collapse" id="main-menu">

    <?php if ($this->loggedInUser !== null) : ?>
        <?php $this->navigation('navigation')
                ->findBy('route', 'hello')
                ->setParams(array('username' => $this->loggedInUser->getUsername())); ?> // If you need to pass any params

        <?php $this->navigation('navigation')
                ->findBy('route', 'world'); ?>

    <?php endif; ?>

    <?php 
        echo $this->navigation('navigation')
            ->menu()
            ->setUlClass('nav navbar-nav')
            ->setAcl($this->acl) // ACL object
            ->setRole($this->userRole) // Role Object
            ->renderMenu(); 
    ?>

</div>

Hope this would help you!

unclexo
  • 3,691
  • 2
  • 18
  • 26
  • Thanks for your answer, but it's already working. The problem is the setting of the `active` "property" and in general passing variables into the navigation view script. – automatix Jun 25 '17 at 13:21
  • Thanks again for your answer! It solved the problem. – automatix Jun 25 '17 at 13:45