Using Zend\Navigation in your Album Module
In this tutorial we will use the Zend\Navigation component
to add a navigation menu to the black bar at the top of the screen, and add
breadcrumbs above the main site content.
Preparation
In a real world application, the album browser would be only a portion of a working website. Usually the user
would land on a homepage first, and be able to view albums by using a standard navigation menu. So that we
have a site that is more realistic than just the albums feature, lets make the standard skeleton welcome 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 the
AlbumController‘s default action. Let’s undo this route change so we have two discrete entry points to the
app, a home page, and an albums area.
module/Application/config/module.config.php:
| 'home' => array(
'type' => 'Zend\Mvc\Router\Http\Literal',
'options' => array(
'route' => '/',
'defaults' => array(
'controller' => 'Application\Controller\Index', // <-- change back here
'action' => 'index',
),
),
),
|
This change means that if you go to the home page of your application
(http://zf2-tutorial.localhost/), you see the default skeleton
application introduction. Your list of albums is still available at the
/album route.
Setting Up Zend\Navigation
Firstly, we need to tell our application which NavigationFactory to
use when using the bundled navigation view helpers. Thankfully, ZF2
comes with a default factory that will suit our needs just fine. To tell
ZF2 to use this default factory, we simply add a navigation key to
the service manager. Its best to do this in the Application module,
because, like the translation data, this is specific to the entire
application, and not just to our album pages:
module/Application/config/module.config.php:
| 'service_manager' => array(
'factories' => array(
'navigation' => 'Zend\Navigation\Service\DefaultNavigationFactory', // <-- add this
),
),
|
Configuring our Site Map
Next up, we need Zend\Navigation to understand the hierarchy of our
site. Thankfully, if we add a navigation key to our merged config,
the navigation factory will automagically create the container and pages
needed to use the view helpers. Let’s do this in the Application
module:
module/Application/config/module.config.php:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33 | return array(
...
'navigation' => array(
'default' => array(
array(
'label' => 'Home',
'route' => 'home',
),
array(
'label' => 'Album',
'route' => 'album',
'pages' => array(
array(
'label' => 'Add',
'route' => 'album',
'action' => 'add',
),
array(
'label' => 'Edit',
'route' => 'album',
'action' => 'edit',
),
array(
'label' => 'Delete',
'route' => 'album',
'action' => 'delete',
),
),
),
),
),
...
);
|
This configuration maps out the pages we’ve defined in our controller,
with labels linking to the given route names. You can define highly
complex hierarchical sites here with pages and sub-pages linking to route
names, controller/action pairs or external uris. For more information
see the docs
here.
Adding Breadcrumbs
Adding breadcrumbs is initially just as simple. In our layout.phtml
we want to add breadcrumbs above the main content pane, so our foolish
user knows exactly where they are in our complex website. Inside the
container div, before we output the content from the view, let’s add a
simple breadcrumb by using the
breadcrumbs view helper:
module/Application/view/layout/layout.phtml:
| ...
<div class="container">
<?php echo $this->navigation('navigation')->breadcrumbs()->setMinDepth(0); // <-- Add this!! ?>
<?php echo $this->content; ?>
</div>
...
|
This adds a simple but functional breadcrumb to every page (we simply
tell it to render from a depth of 0 so we see all level of pages) but we
can do better than that! Because Bootstrap has a styled breadcrumb as
part of it’s base CSS, so let’s add a partial that outputs the UL in
bootstrap happy CSS. We’ll create it in the view directory of the
Application module (this partial is application wide, rather than
album specific):
module/Application/view/partial/breadcrumb.phtml:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 | <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="<?php echo $page->getHref(); ?>"><?php echo $page->getLabel(); ?></a>
<?php
// otherwise, just output the name
else:
?>
<?php echo $page->getLabel(); ?>
<?php endif; ?>
</li>
<?php endforeach; ?>
</ul>
|
Notice how the partial is passed a Zend\View\Model\ViewModel instance with the pages
property set to an array of pages to render. Now all we have to do is
tell the breadcrumb helper to use the partial we have just written:
module/Application/view/layout/layout.phtml:
| ...
<div class="container">
<?php
echo $this->navigation('navigation') // <-- Update this!!
->breadcrumbs()
->setMinDepth(0)
->setPartial('partial/breadcrumb.phtml');
?>
<?php echo $this->content; ?>
</div>
...
|
Refreshing the page now gives us a lovely styled set of breadcrumbs on
each page.