1. Home
  2. Documentation
  3. Tutorials
  4. MVC Tutorials
  5. Adding zend-navigation to the Album Module

MVC Tutorials

In This Article

Using zend-navigation in your Album Module

In this tutorial we will use thezend-navigation componentto add a navigation menu to the black bar at the top of the screen, and addbreadcrumbs above the main site content.

Preparation

In a real world application, the album browser would be only a portion of aworking website. Usually the user would land on a homepage first, and be able toview albums by using a standard navigation menu. So that we have a site that ismore realistic than just the albums feature, lets make the standard skeletonwelcome page our homepage, with the/album route still showing our album module.In order to make this change, we need to undo some work we did earlier.Currently, navigating to the root of your app (/) routes you to theAlbumController's default action. Let's undo this route change so we have twodiscrete entry points to the app, a home page, and an albums area.

// In module/Application/config/module.config.php:'home' => [   'type' => Literal::class,    'options' => [        'route'    => '/',        'defaults' => [            'controller' => Controller\IndexController::class, // <-- change back here            'action'     => 'index',        ],    ],],

(You can also now remove the import for theAlbum\Controller\AlbumControllerclass.)

This change means that if you go to the home page of your application(http://localhost:8080/ orhttp://zf-tutorial.localhost/), you see thedefault skeleton application introduction. Your list of albums is stillavailable at the/album route.

Setting Up zend-navigation

First, we need to install zend-navigation. From your root directory, execute thefollowing:

$ composer require zendframework/zend-navigation

Assuming you followed theGetting Started tutorial,you will be prompted by thezend-component-installerplugin to injectZend\Navigation; be sure to select the option for eitherconfig/application.config.php orconfig/modules.config.php; since it is theonly package you are installing, you can answer either "y" or "n" to the "Remember thisoption for other packages of the same type" prompt.

Manual configuration

If you are not using zend-component-installer, you will need to setupconfiguration manually. You can do this in one of two ways:

  • Register theZend\Navigation module in eitherconfig/application.config.php orconfig/modules.config.php. Make sure you put it towards the top of the module list, before any modules you have defined or third party modules you are using.
  • Alternately, add a new file,config/autoload/navigation.global.php, with the following contents:
<?phpuse Zend\Navigation\ConfigProvider;return [    'service_manager' => (new ConfigProvider())->getDependencyConfig(),];

Once installed, our application is now aware of zend-navigation, and even hassome default factories in place, which we will now make use of.

Configuring our Site Map

Next up, we need zend-navigation to understand the hierarchy of our site.To do this, we can add anavigation key to our configuration, with the sitestructure details. We'll do that in theApplication module configuration:

// in module/Application/config/module.config.php:return [    /* ... */    'navigation' => [        'default' => [            [                'label' => 'Home',                'route' => 'home',            ],            [                'label' => 'Album',                'route' => 'album',                'pages' => [                    [                        'label'  => 'Add',                        'route'  => 'album',                        'action' => 'add',                    ],                    [                        'label'  => 'Edit',                        'route'  => 'album',                        'action' => 'edit',                    ],                    [                        'label'  => 'Delete',                        'route'  => 'album',                        'action' => 'delete',                    ],                ],            ],        ],    ],    /* ... */];

This configuration maps out the pages we've defined in our Album module, withlabels linking to the given route names and actions. You can define highly complexhierarchical sites here with pages and sub-pages linking to route names,controller/action pairs, or external uris. For more information, see thezend-navigation quick start.

Adding the Menu View Helper

Now that we have the navigation helper configured by our service manager andmerged config, we can add the menu to the title bar to our layout byusing themenu view helper:

<?php // in module/Application/view/layout/layout.phtml: ?><div class="collapse navbar-collapse">    <?php // add this: ?>    <?= $this->navigation('navigation')->menu() ?></div>

The navigation helper is provided by default with zend-view, and uses the servicemanager configuration we've already defined to configure itself automatically.Refreshing your application, you will see a working menu; with just a few tweakshowever, we can make it look even better:

<?php // in module/Application/view/layout/layout.phtml: ?><div class="collapse navbar-collapse">    <?php // update to: ?>    <?= $this->navigation('navigation')        ->menu()        ->setMinDepth(0)        ->setMaxDepth(0)        ->setUlClass('nav navbar-nav') ?></div>

Here we tell the renderer to give the root<ul> the class ofnav (so thatBootstrap styles the menu correctly), and only render the first level of anygiven page. If you view your application in your browser, you will now see anicely styled menu appear in the title bar.

The great thing about zend-navigation is that it integrates with zend-router inorder to highlight the currently viewed page. Because of this, it sets theactive page to have a class ofactive in the menu; Bootstrap uses this tohighlight your current page accordingly.

Adding Breadcrumbs

Adding breadcrumbs follows the same process. In ourlayout.phtml we want toadd breadcrumbs above the main content pane, so our users know exactlywhere they are in our website. Inside the container<div>, before weoutput the content from the view, let's add a breadcrumb by using thebreadcrumbs view helper.

<?php // module/Application/view/layout/layout.phtml: ?><div class="container">    <?php // add the following line: ?>    <?= $this->navigation('navigation')->breadcrumbs()->setMinDepth(0) ?>    <?= $this->content ?></div>

This adds a simple but functional breadcrumb to every page (we tell it to renderfrom a depth of 0 so we see all page levels), but we can do better than that!Because Bootstrap has a styled breadcrumb as part of its base CSS, let's adda partial that outputs the<ul> using Bootstrap styles. We'll create it in theview directory of theApplication module (this partial is application wide,rather than album specific):

<?php // in module/Application/view/partial/breadcrumb.phtml: ?><ul class="breadcrumb">    <?php    // iterate through the pages    foreach ($this->pages as $key => $page):    ?>        <li>            <?php            // if this isn't the last page, add a link and the separator:            if ($key < count($this->pages) - 1):            ?>                <a href="<?= $page->getHref() ?>"><?= $page->getLabel() ?></a>            <?php            // otherwise, output the name only:            else:            ?>                <?= $page->getLabel() ?>            <?php endif; ?>        </li>    <?php endforeach; ?></ul>

Notice how the partial is passed aZend\View\Model\ViewModel instance with thepages property set to an array of pages to render.

Now we need to tell the breadcrumb helper to use the partial we have justwritten:

<?php // in module/Application/view/layout/layout.phtml: ?><div class="container">    <?php // Update to: ?>    <?= $this->navigation('navigation')            ->breadcrumbs()            ->setMinDepth(0)            ->setPartial('partial/breadcrumb') ?>    <?= $this->content ?></div>

Refreshing the page now gives us a styled set of breadcrumbs on each page.

Found a mistake or want to contribute to the documentation? Edit this page on GitHub!