Chapter 10. Zym_Navigation

Chapter 10. Zym_Navigation

10.1. Introduction

Zym_Navigation is a component for managing hierarchical structures of (logical representations of) web pages. Simply put: It can be used for creating menus, breadcrumbs and sitemaps, or serve as a container or model for other purposes a project might find by having a hierarchical representation of pages.

10.1.1. Pages and Containers

There are two ground concepts in Zym_Navigation:

1. Pages

A page in Zym_Navigation – in its most basic form – is a holder object for label and href, where href is a link to the page. There are of course a number of other other properties related to pages, all of which are covered in the section on pages. In addition to properties specific to the page, a page can also be container for other pages.

2. Containers

A navigation container (Zym_Navigation_Container) is a container class for pages. It contains methods for adding, retrieving, deleting and iterating pages. It implementes the SPL interaces RecursiveIterator and Countable, so it may be iterated recursively, either by using the SPL class RecursiveIteratorIterator class, or by implementing recursive iteration yourself using foreach loops.

Both Zym_Navigation and Zym_Navigation_Page extend Zym_Navigation_Container, so both can contain any number of hierarchic levels of pages.

Containers have finder methods for retrieving pages. Those are findOneBy($property, $value), findAllBy($property, $value), and findBy($property, $value, $all = false). Those methods will recursively search the container for pages matching the given $page->$property == $value. The first method, findOneBy() will return a single page matching the property with the given value, or null if it cannot be found.

The finder methods can also be used magically with appending property name to the method, e.g. findOneByLabel('Home') to return the first matching page with label Home. Other combinations are findByLabel(..), findOnyByTitle(...), findAllByController(...), and so on.

Example 10.1. Using finder methods

<?php
$nav = new Zym_Navigation(array(
    array(
        'label' => 'Page 1',
        'uri'   => 'page-1',
        'foo'   => 'bar',
        'pages' => array(
            array(
                'label' => 'Page 1.1',
                'uri'   => 'page-1.1',
                'foo'   => 'bar',
            ),
            array(
                'label' => 'Page 1.2',
                'uri'   => 'page-1.2',
                'class' => 'my-class',
            ),
            array(
                'type'   => 'uri',
                'label'  => 'Page 1.3',
                'uri'    => 'page-1.3',
                'action' => 'about'
            )
        )
    ),
    array(
        'label'      => 'Page 2',
        'id'         => 'page_2_and_3',
        'class'      => 'my-class',
        'module'     => 'page2',
        'controller' => 'index',
        'action'     => 'page1'
    ),
    array(
        'label'      => 'Page 3',
        'id'         => 'page_2_and_3',
        'module'     => 'page3',
        'controller' => 'index'
    )
));
 
// The 'id' is not required to be unique, but be aware that
// having two pages with the same id will render the same id attribute
// in menus and breadcrumbs.
$found = $nav->findBy('id', 'page_2_and_3');       // returns Page 2
$found = $nav->findOneBy('id', 'page_2_and_3');    // returns Page 2
$found = $nav->findBy('id', 'page_2_and_3', true); // returns Page 2 and Page 3
$found = $nav->findById('page_2_and_3');           // returns Page 2
$found = $nav->findOneById('page_2_and_3');        // returns Page 2
$found = $nav->findAllById('page_2_and_3');        // returns Page 2 and Page 3
 
// Find all matching CSS class my-class
$found = $nav->findAllBy('class', 'my-class'); // returns Page 1.2 and Page 2
$found = $nav->findAllByClass('my-class');     // returns Page 1.2 and Page 2
 
// Find first matching CSS class my-class
$found = $nav->findOneByClasS('my-class');     // returns Page 1.2
 
// Find all matching CSS class non-existant
$found = $nav->findAllByClass('non-existant'); // returns array()
 
// Find first matching CSS class non-existant
$found = $nav->findOneByClass('non-existant'); // returns null
 
// Find all pages with custom property 'foo' = 'bar'
$found = $nav->findAllBy('foo', 'bar'); // returns Page 1 and Page 1.1
 
// To achieve the same magically, 'foo' must be in lowercase.
// This is because 'foo' is a custom property, and thus the
// property name is not normalized to 'Foo'
$found = $nav->findAllByfoo('bar');
 
// Find all with controller = 'index'
$found = $nav->findAllByController('index'); // returns Page 2 and Page 3

[Note] Note

Zym_Navigation_Container is abstract, and can not be instantiated directly. Use Zym_Navigation if you only want a container.

[Note] Note

The difference between Zym_Navigation and Zym_Navigation_Page is that the former does not contain page properties, so it can only be used as an outer container for pages.

10.1.2. Separation of logic structure and rendering

The classes in the Zym_Navigation namespace do not deal with rendering. This responsibility is delegated to the navigation view helpers. However, pages may contain information that is used by view helpers when rendering, such as; CSS class, title attribute, lastmod and priority properties for sitemaps, etc.

Read more about navigation rendering navigation objects in the manual section on navigation view helpers.