3

I am trying to add module specific navigation items from within the module. I may be doing this completely wrong. What I have so far is:

config/autoload/navigation.global.php (this works so far)

<?php
return array(
  'navigation' => array(
    'default' => array(
      array(
        'label' => 'Home',
        'route' => 'home',
        'order' => -100,
        'pages' => array(
        ),
      ),
    ),
  ),
);

module/Books/Module.php: (I am trying to add 'Books' navigation items under Home (not inline with))

class Module
{
  public function onPreDispatch($e) {
    $pages = array(
      array(
        'label' => 'Books',
        'route' => 'books',
      ),
    );
    $navigation = $e->getParam('application')->getServiceManager()->get('navigation');
    $navigation->findOneByRoute('home')->addPages($pages);
  }
  /* ... */
}

So in the above example (the route is correct), I do not get an error, the event trigger on pre-dispatch, but nothing gets added to the navigation container.

What I want to accomplish is Navigation as follows:

  Home
    |-> Books
    |-> Module2
    |-> etc..
Stoyan Dimov
  • 5,250
  • 2
  • 28
  • 44
Aaron Murray
  • 1,920
  • 3
  • 22
  • 38

1 Answers1

11

You don't need to hook on an event. Just put the module specific navigation configuration in the module's module.config.php. The configuration of every module is merged and if you have caching this will be better in terms of performance if you do it for many modules.

Important is to give names to your items in the navigation. In config/autoload/navigation.global.php add a name for the home item:

<?php
return array(
    'navigation' => array(
        'default' => array(
            'home' => array(      // <-- name "home" added (name is arbitrary)
                'label' => 'Home',
                'route' => 'home',
                 'order' => -100,
            ),
        ),
    ),
);

and then in the module/Books/config/module.config.php

return array(
    'navigation' => array(
        'default' => array(
            'home' => array(
                'pages' => array(
                    'home/book' => array(   // <-- name is arbitrary
                        'label' => 'Books',
                        'route' => 'books',
                     ),
                 ),   
             ),
         ),
     ),
);

In the end both configurations merge and you have one navigation key:

return array(
    'navigation' => array(
        'default' => array(
            'home' => array(
                'label' => 'Home',
                'route' => 'home',
                'order' => -100,
                'pages' => array(
                    'home/book' => array(
                        'label' => 'Books',
                        'route' => 'books',
                     ),
                 ),   
             ),
         ),
     ),
);

Hope this helps :)

Stoyan

Stoyan Dimov
  • 5,250
  • 2
  • 28
  • 44
  • Was just writing pretty much the same answer :P Well explained – Sam Mar 25 '13 at 09:15
  • As far as i know, the merged config will be cached - meaning all Modules combined. But i do not know about the life-span on this. – Sam Mar 25 '13 at 09:49
  • Sorry, I removed the question because I think it is better suited as a new s.o.f. question. But thanks anyway. – Stoyan Dimov Mar 25 '13 at 09:53
  • Ah ha! That is so much easier, (and the named keys was what I was missing when I originally tried that way, which is why I started down the addPages / event path in the first place. I will try that tonight. – Aaron Murray Mar 25 '13 at 15:56
  • But what should I do if navigation item depends on the state of the module (for example on privileges or login)? – Tomek Kobyliński Jul 23 '13 at 07:53
  • 1
    @TomekKobyliński Setting permissions for each page is a different concern from navigation and therefore should be set somewhere else. However, if you want you navigation's link to reflect permissions check out the page's visible property. You can set the visibility of pages in the nav depending on your the permissions. An elegant way that doesn't break good practices is to create an array that has similar structure as the navigation configuration. Then fill this array only with the 'visible' property and/of a page. During factorying nav merge the nav config array with the permissions array. – Stoyan Dimov Jul 24 '13 at 06:11