Talk about Zend_Navigation

Exit ZF 1.8 delighted us with a few new (and very useful) components. In this article I want to talk about the practice of using Zend_Navigation to build a menus website, a site map, breadcrumbs. Special attention is paid to using Zend_Navigation in combination with Zend_Acl.

This is a translation of an article from my blog. As it is published on multiple sites, then the full version will always be the original (in Ukrainian).

For a start will create a skeleton project using Zend_Tool.
$ zf create project ./


the 1. Menu
To configure a Zend_View add in "application/configs/application.ini" the following code:
; Views
resources.view.encoding = "UTF-8"
resources.view.basePath = APPLICATION_PATH "/views"
resources.view.helperPath.Application_View_Helper = APPLICATION_PATH "/views/helpers"
Then in the file "application/Bootstrap.php" create new method _initNavigation() (please read comments in code):
class Bootstrap extends Zend_Application_Bootstrap_Bootstrap
{

/*
* Initialize the Navigator object and pass it into View
*
* @return Zend_Navigation
*/

public function _initNavigation()
{
// Bootstrapi View
$this->bootstrapView();
$view = $this->getResource('view');

// the Structure is simple menu (can be put in XML)
$pages = array(
array(
'controller' => 'index',
'label' => _('Home'),
),
array(
'controller' => 'users',
'action' => 'index',
// I is wrapped with the text in _(), then to pull his gettext'parser
'label' => _('Users'),
'pages' => array (
array (
'controller' => 'users',
'action' => 'new',
'label' => _('Add user'),
),
)
),
array (
'controller' => 'users',
'action' => 'registration',
'label' => _('Register'),
),
'controller' => 'users',
'action' => 'login',
'label' => _('Authorization'),
),
array (
'controller' => 'users',
'action' => 'logout',
'label' => _('Exit'),
)
);

// Create a new container based on our structure
$container = new Zend_Navigation($pages);
// Pass the container View
$view->menu = $container;

return $container;
}

}

If you follow a healthy logic, then the menu should be present on all pages (or most). This is the perfect Zend_Layout.
$ mkdir application/layouts
$ mkdir application/layouts/scripts
$ touch application/layouts/scripts/default.phtml
Add in template "application/layouts/scripts/default.phtml" output menu and content page:
<div id="menu">
<h3>
<?php echo $this->translate('Menu'); ?>
</h3>

<?php echo $this->navigation()->menu($this->menu); ?>
</div>

<div id="content">
<?php echo $this->layout()->content; ?>
</div>

And in "application/configs/application.ini" stand settings for the resource layout which initialisere Zend_Layout:
; the Layout
resources.layout.layout = "default"
resources.layout.layoutPath = APPLICATION_PATH "/layouts/scripts"

And run (the original article I wrote on the Ukrainian and screenshots remake honestly too lazy :)):
Menus :)
Voila :). See ready, raskladnoy menus! The active item is marked as class="active".

the 2. Bread crumbs
OK, menus are ready. Now I want to use the site, the user could always see your current location. You can use the "bread crumbs".

So the application did not swear on the lack of the appropriate controller or view I am using Zend_Tool create controller Users will add to it necessary action. It's very simple:
$ zf create controller users
$ zf create action new --controller-name users
$ zf create action registration --controller-name users
$ zf create action login --controller-name users
Well, I add some new code to the template layout'a (between menu and content):
<div id="breadcrumbs">
<h3>
<?php echo $this->translate('breadcrumb'); ?>
</h3>
<?php echo $this->navigation()->breadcrumbs($this->menu)->setLinkLast(true); ?>
</div>

Look what happened:
Bread crumbs
Cool :)?
Method setLinkLast(true) means that the last baby you want to display as a link. You can also specify a separator, and a minimum depth — look API

the 3. Sitemap
With sitemapa easy. Everything is done by analogy. That's manualand here is a minimal code:
<?php echo $this->navigation()->sitemap($this->menu); ?>


the 4. Zend_Navigation && Zend_Acl
And now I'll tell you what I liked in Zend_Navigation — the ability to use it in conjunction with Zend_Acl.
Add to Bootstrap roles and privileges to access the page and the initialization Zend_Acl (read the code comments!):
<?php

class Bootstrap extends Zend_Application_Bootstrap_Bootstrap
{

/**
* Initialize the ACL.
* Create roles and resources. Distribute access rights
*
* @return Zend_Acl
*/

protected function _initAcl()
{
$auth = Zend_Auth::getInstance();
// Define the user role.
// If not authorized, it means "guest"
$user = ($auth->hasIdentity() && !empty($auth->getIdentity()->role))
? $auth->getIdentity()->role : 'guest';

$acl = new Zend_Acl();

// Create a role
$acl->addRole(new Zend_Acl_Role('guest'))
->addRole(new Zend_Acl_Role('member'), 'guest')
->addRole(new Zend_Acl_Role('administrator'), 'member');
// Create resources
// I use prefixes for naming resources
// "mvc:" - for pages
$acl->add(new Zend_Acl_Resource('mvc:index'))
->add(new Zend_Acl_Resource('mvc:error'))
->add(new Zend_Acl_Resource('mvc:users'));

// Allow guests on "face" and the error page
$acl->allow('guest', array('mvc:error', 'mvc:index'));

// And also on login page and registration
$acl->allow('guest', 'mvc:users', array('login', 'registration'));
// And the members already, bummer :)
$acl->deny('member', 'mvc:users', array('login', 'registration'));
// Well, etc.
$acl->allow('member', 'mvc:users', array('index', 'logout'));
$acl->allow('administrator', 'mvc:users', array('new'));

// we Catch the ACL to the Zend_Navigation
Zend_View_Helper_Navigation_Helperabstract::setDefaultAcl($acl);
Zend_View_Helper_Navigation_Helperabstract::setDefaultRole($user);

return $acl;
}

/*
* Initialize the Navigator object and pass it into View
*
* @return Zend_Navigation
*/

public function _initNavigation()
{
$this->bootstrapView();
$view = $this->getResource('view');

$pages = array(
array(
'controller' => 'index',
'label' => _('Home'),
),
'controller' => 'users',
'action' => 'index',
// the Resource to check access rights
'resource' => 'mvc:users',
// And a privilege
'privilege' => 'index',
'label' => _('Users'),
'pages' => array (
array (
'controller' => 'users',
'action' => 'new',
'resource' => 'mvc:users',
'privilege' => 'new',
'label' => _('Add user'),
),
)
),
array (
'controller' => 'users',
'action' => 'registration',
'resource' => 'mvc:users',
'privilege' => 'registration',
'label' => _('Register'),
),
array (
'controller' => 'users',
'action' => 'login',
'resource' => 'mvc:users',
'privilege' => 'login',
'label' => _('Authorization'),
),
array (
'controller' => 'users',
'action' => 'logout',
'resource' => 'mvc:users',
'privilege' => 'logout',
'label' => _('Exit'),
)
);

$container = new Zend_Navigation($pages);
$view->menu = $container;
return $container;
}

}
?>

Start:
Menu for guests
Well, see the menu for guests. While bread crumbs are not present because you need to specify a minimum depth equal to zero.

the Results
Just do Zend_Navigation very convenient and flexible component. I also forgot to say that the standard view helpers support Zend_Translate, which is very convenient when creating multilingual sites.
Seems everything. Hope this article is useful to you. And go to our forum zendframework.ru (and also on the site a lot of useful and interesting).

the UPD. Then (or rather already there :)) san dictates that that's the way to do
$view->menu = $container;
not very convenient because you can accidentally overwrite this variable in the controller.
If the site has only one menu, then you can do simply:
$view->navigation($container);

And output it in a view as follows:
<?php echo $this->navigation()->menu(); ?>
<?php echo $this->navigation()->breadcrumbs(); ?>


UPD2.
Herpolsheimer jarool made a good point:
For most applications, one builds the navigation object and one ACL list. So you menus to put in Zend_Registry::set('Zend_Navigation', $AppNavigation) — helpers will find themselves and do not need to layout to push and specify when you call the helper.
Article based on information from habrahabr.ru

Комментарии

Популярные сообщения из этого блога

Car navigation in detail

PostgreSQL: Analytics for DBA

Google has launched an online training course advanced search