Skip to content

Instantly share code, notes, and snippets.

@juriansluiman
Created August 19, 2012 12:28
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save juriansluiman/3394599 to your computer and use it in GitHub Desktop.
Save juriansluiman/3394599 to your computer and use it in GitHub Desktop.
New Navigation module for Zend Framework 2

Proposal for a new navigation component

This document is a start to get a new navigation component of the ground. The current Zend\Navigation has shown to be a powerful component for navigation purposes. On the other hand, the code is since it's introduction in Zend Framework 1.8 not really updated. The complexity is for some features very difficult to comprehend. In ZF2, the overhaul of the view helpers made it even more difficult to customize the behaviour of Zend\Navigation.

The good parts:

  1. A structure of containers and pages to create hierarchal trees
  2. A set of domain layer-like objects (containers and pages) and view helpers to render them into html
  3. The option to mark pages as "active"
  4. The option to tune visibility of pages
  5. The option to attach an ACL object to the navigation list to show or hide parts based on access permission

The bad parts:

  1. The complexity to set pages active, especially with:
    • MVC pages and the use of route matches;
    • When a page is not active, the check if a page is active is performed every time the method $page->isActive() is called.
  2. The simplicity of visibility of pages, especially when the visibility flag should be context aware. Ie, on the menu the page is not visible, but in the breadcrumbs it is.
  3. The view helper plugin manager, hidden inside a view helper
  4. The extensibility of view helpers is because of #3 very hard to accomplish

Goal of this proposal

The new navigation component will probably live inside a module, maintained by a couple of core zf2 developers. An example might be the ZF-Commons group (having a ZfcNavigation) but it is not the intend of this proposal to become part of Zfc, but rather provide an alternative navigation implementation. The goal is to develop something alike Zend\Navigation but without all the reasons why you wouldn't use Zend\Navigation.

It is a wish to keep as close as possible to Zend\Navigation, because of the simpler learning curve and migration. However, backwards compatibility will probably not be maintained.

Architectural decisions

A Navigation object is a class representing a set of navigation collection. A Collection is a set of pages. A Page is a node inside the tree.

  1. The Navigation can hold multiple collections. An example is the main menu of a website and somewhere in the footer a second navigations structure for pages below the fold. It is recommended to keep the navigation object a shared instance among all consumers of navigation, but this isn't necessarily required.
  2. The Collection is an abstract class representing an object able to store some other collections in a specific order.
  3. The Page is the lowest type in this hierarchy. The page extends a collection and is therefore able to contain several other sub pages. A page also contain information like it has now: a uri, a label (or title), visibility flag etc.

There might be a multitude of page types, of which the uri and mvc page types like they are now the most obvious choices are.

Multiple navigation objects

A sample is a container is stored inside navigation with a key/value based system:

$navigation = new Navigation;

$container = new Container;
$navigation->setContainer('default', $container);

$container = new Container;
$navigation->setContainer('secondary', $container);

The same will be for the navigation view helper:

$this->navigationMenu('secondary')->render();

Active page setting

The Navigation is aware in which collection which page is active. A code sample might be:

$page = $navigation->findByRoute('some/route');
$navigation->setActive($page);

The navigation holds a reference to the page. This makes one of the most common tasks of the navigation (finding the active page) extremely simple. The behaviour can be tuned such that parent pages are automatically set to active too:

$page = $navigation->findByRoute('some/route');
$navigation->setActive($page);
$parent = $page->getParent();

$navigation->isActive($parent); // true
// or
$parent->isActive(); // true

View helpers

The navigation view helpers should be designed like the Zend\Form view helpers. They live in a separate namespace (like Zend\Form\View\Helper) and are constructed with prefixed components names (like formElement, formElementLabel). A plugin manager will hold a default set of view helpers. The current set is a good list of what is initially required:

  1. Menu
  2. Breadcrumbs
  3. Sitemap

Access control

Now ACL is accompanied with a RBAC proposal, the navigation module must be flexible to support any type of permission setting. This is involved in three layers:

  1. The navigation class must have a collection which is accessible
  2. The page in the navigation must be accessible
  3. The view helper must hold a reference to a ACL or RBAC system

For the first one, the use case is an admin menu must be completely hidden from the anonymous visitor. The second one is similar to what Zend\Navigation now already supports.

Skeleton classes

-- tbd --

@macnibblet
Copy link

Visibility is something that you have neglected to mention, The ability to hide certain pages from a view renderer.

@macnibblet
Copy link

of course i meant navigation renderer such as Sitemap or Menu.

Github wont let me edit the previous comment tho...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment