Hmm
This is more of a reminder to ::self than a post. Because it took me nearly a full day to figure out how to be able to put just a logo image in the menu with Zend_View_Helper_Navigation_Menu. So here goes.Note 1: I used ZF 1.11
Note 2: For simplicity, I used "fullmoon" where you should use your application name. Take notice of case within the code, it's important and it changes depending on the part of code you're in.
Step 1: Extend Zend_View_Helper_Navigation_Menu
In the library, create your own menu view helper:library/Fullmoon/View/Helper/Navigation/FullmoonMenu.phpwith the following code:
class Fullmoon_View_Helper_Navigation_FullmoonMenu extends Zend_View_Helper_Navigation_Menu
{
public function fullmoonMenu(Zend_Navigation_Container $container = null)
{
return $this->menu($container);
}
}
Step 2: Modify the layout view script
This will allow you to make the following call in your layout view script (application/layouts/scripts/layout.phtml):
echo $this->navigation()->fullmoonMenu();
Step 3: Modify the bootstrap
Inapplication/bootstrap.php, add the following:
/**
* Menu
*/
protected function _initNavigation()
{
// Load menu data from XML file. First argument is the XML file,
// second is the XML node containing the menu XML data
$config = new Zend_Config_Xml(APPLICATION_PATH . '/configs/navigation.xml', 'nav');
// Retrieve the view object
$view = $this->getResource('view');
// Add our own Navigation Menu helper to the view plugins path
$view->addHelperPath(
'Fullmoon/View/Helper/Navigation',
'Fullmoon_View_Helper_Navigation_'
);
// Load the menu into the view
$view->navigation(new Zend_Navigation($config));
}
Note: You can find examples of XML menu files here.
At this point, your menu should be loading normally, albeit still without an image.
Step 4: Adding the image (aahh, finally!)
Adding the image to the XML file:<img> <class>title</class> <src>/img/logo-small.png</src> <module>default</module> <controller>index</controller> <action>index</action> </img>
Step 5: Amending your menu helper
As a final step, we need to render the image (inlibrary/Fullmoon/View/Helper/Navigation/FullmoonMenu.php) by overriding the protected _renderMenu() method from library/Zend/View/Helper/Navigation/Menu.php:
/**
* Renders a normal menu (called from {@link renderMenu()})
*
* @param Zend_Navigation_Container $container container to render
* @param string $ulClass CSS class for first UL
* @param string $indent initial indentation
* @param int|null $minDepth minimum depth
* @param int|null $maxDepth maximum depth
* @param bool $onlyActive render only active branch?
* @return string
*/
protected function _renderMenu(Zend_Navigation_Container $container,
$ulClass,
$indent,
$minDepth,
$maxDepth,
$onlyActive)
{
$html = '';
// find deepest active
if ($found = $this->findActive($container, $minDepth, $maxDepth)) {
$foundPage = $found['page'];
$foundDepth = $found['depth'];
} else {
$foundPage = null;
}
// create iterator
$iterator = new RecursiveIteratorIterator($container,
RecursiveIteratorIterator::SELF_FIRST);
if (is_int($maxDepth)) {
$iterator->setMaxDepth($maxDepth);
}
// iterate container
$prevDepth = -1;
foreach ($iterator as $page) {
$depth = $iterator->getDepth();
$isActive = $page->isActive(true);
if ($depth < $minDepth || !$this->accept($page)) {
// page is below minDepth or not accepted by acl/visibilty
continue;
} else if ($onlyActive && !$isActive) {
// page is not active itself, but might be in the active branch
$accept = false;
if ($foundPage) {
if ($foundPage->hasPage($page)) {
// accept if page is a direct child of the active page
$accept = true;
} else if ($foundPage->getParent()->hasPage($page)) {
// page is a sibling of the active page...
if (!$foundPage->hasPages() ||
is_int($maxDepth) && $foundDepth + 1 > $maxDepth) {
// accept if active page has no children, or the
// children are too deep to be rendered
$accept = true;
}
}
}
if (!$accept) {
continue;
}
}
// make sure indentation is correct
$depth -= $minDepth;
$myIndent = $indent . str_repeat(' ', $depth);
if ($depth > $prevDepth) {
// start new ul tag
if ($ulClass && $depth == 0) {
$ulClass = ' class="' . $ulClass . '"';
} else {
$ulClass = '';
}
$html .= $myIndent . '<ul' . $ulClass . '>' . self::EOL;
} else if ($prevDepth > $depth) {
// close li/ul tags until we're at current depth
for ($i = $prevDepth; $i > $depth; $i--) {
$ind = $indent . str_repeat(' ', $i);
$html .= $ind . ' </li>' . self::EOL;
$html .= $ind . '</ul>' . self::EOL;
}
// close previous li tag
$html .= $myIndent . ' </li>' . self::EOL;
} else {
// close previous li tag
$html .= $myIndent . ' </li>' . self::EOL;
}
// Manage menu image
if ($page->src != '') {
$html .= $myIndent . ' <li class="title">' . self::EOL
. ' <img src="' . $page->src . '" />' . self::EOL;
} else {
// render li tag and page
$liClass = $isActive ? ' class="active"' : '';
$html .= $myIndent . ' <li' . $liClass . '>' . self::EOL
. $myIndent . ' ' . $this->htmlify($page) . self::EOL;
}
// store as previous depth for next iteration
$prevDepth = $depth;
}
if ($html) {
// done iterating container; close open ul/li tags
for ($i = $prevDepth+1; $i > 0; $i--) {
$myIndent = $indent . str_repeat(' ', $i-1);
$html .= $myIndent . ' </li>' . self::EOL
. $myIndent . '</ul>' . self::EOL;
}
$html = rtrim($html, self::EOL);
}
return $html;
}
This part is what does the trick:
// Manage menu image
if ($page->src != '') {
$html .= $myIndent . ' <li class="title">' . self::EOL
. ' <img src="' . $page->src . '" />' . self::EOL;
} else {
// render li tag and page
$liClass = $isActive ? ' class="active"' : '';
$html .= $myIndent . ' <li' . $liClass . '>' . self::EOL
. $myIndent . ' ' . $this->htmlify($page) . self::EOL;
}
Conclusion
I had a hard time gathering the necessary information over the Internet, hopefully this may help out those wanting to add a logo to the menu with Zend Framework.Note that the logo does not have link attached to it, but with a little tweaking of the last code snippet that shouldn't be too difficult ;)
There may be a far simpler solution to this but I don't know of it nor have I found it on the Internet.
Aucun commentaire:
Enregistrer un commentaire