Insert dynamical menu in Magento’s Admin

Hello everyone! I’ve recently got frustrated with Magento’s core functionality which requires XML definition for Administration menus. And I really wanted to add quick website / store links to it. Solution was to overwrite one of Magento’s Adminhtml blocks, and inject my non-XML, dynamic menu to it. If you’re interested in how I did it, read on.
To make it upgradeable, and painless, I’ve decided to make an extension just for this. It consists of only 2 Files, config.xml, and one Block rewrite.
First, I’ve created config.xml, and set it like this:
<?xml version="1.0" encoding="UTF-8"?>
<config>
<modules>
<Inchoo_ExtendedMenu>
<version>0.1.0</version>
</Inchoo_ExtendedMenu>
</modules>
<global>
<blocks>
<configurable>
<class>Inchoo_Configurable_Block</class>
</configurable>
<adminhtml>
<rewrite>
<page_menu>Inchoo_ExtendedMenu_Block_Adminhtml_Menu</page_menu>
</rewrite>
</adminhtml>
</blocks>
</global>
</config>
And since Magento parses XML as always, ideal solution for me was to hook on that parsed data just before printing the menu. So, block I mentioned earlier is “Mage_Adminhtml_Block_Page_Menu”. And here, I was interested in getMenuArray() method, and since it looks like this:
/**
* Retrieve Adminhtml Menu array
*
* @return array
*/
public function getMenuArray()
{
return $this->_buildMenuArray();
}
This was the bes place to interfere in Magento’s core. I’ve created my own class “Inchoo_ExtendedMenu_Block_Adminhtml_Menu” with source code:
<?php
class Inchoo_ExtendedMenu_Block_Adminhtml_Menu extends Mage_Adminhtml_Block_Page_Menu
{
public function getMenuArray()
{
//Load standard menu
$parentArr = parent::getMenuArray();
//Prepare "View Sites" menu
$parentArr['view_sites'] = array(
'label' => 'View Sites',
'active'=>false ,
'sort_order'=>0,
'click' => 'return false;',
'url'=>'#',
'level'=>0,
'last'=> true,
'children' => array()
);
$app = Mage::app();
$j = 0;
$allWebsites = $app->getWebsites();
$totalWebsiteCount = count($allWebsites) - 1;
foreach ($allWebsites as $_eachWebsiteId => $websiteVal){
$_storeName = $app->getWebsite($_eachWebsiteId)->getName();
$_websiteUrl = array(
'label' => $_storeName,
'active' => false ,
'url' => '#',
'click' => "return false",
'sort_order' => $j++ * 10,
'level' => 1,
'children' => array()
);
if(count($parentArr['view_sites']['children']) == $totalWebsiteCount){
$_websiteUrl['last'] = true;
} else {
$_websiteUrl['last'] = false;
}
$parentArr['view_sites']['children'][$j - 1] = $_websiteUrl;
$allStores = $app->getWebsite($app->getWebsite($_eachWebsiteId)->getId())->getStores();
$totalCount = count($allStores);
$i = 0;
foreach ($allStores as $_eachStoreId => $val){
$_websiteId = $app->getStore($_eachStoreId)->getWebsiteId();
if($_websiteId == $j){
$_storeName = $app->getStore($_eachStoreId)->getName();
$baseUrl = $app->getStore($_eachStoreId)->getUrl();
$_websiteUrl = array(
'label' => $_storeName,
'active' => false ,
'click' => "window.open(this.href, 'Website - ' + this.href); return false;",
'sort_order' => $i++ * 10,
'level' => 2,
'url' => $baseUrl
);
if(count($parentArr['view_sites']['children'][$j - 1]['children']) + 1 == $totalCount or $totalCount == 0)
$_websiteUrl['last'] = true;
else
$_websiteUrl['last'] = false;
$parentArr['view_sites']['children'][$j - 1]['children'][$i] = $_websiteUrl;
}
}
}
return $parentArr;
}
}
What I did her was overwrite of “getMenuArray()” call on parent method, and population of resulting array with my own dynamic menu.
Result looks like this on default Magento 1.5.0.1 installation:
And you can download it here.
Note:
As always, please make backup before installation, as this is provided for usage at your own risk.
By the way, this is the Inchoo’s 500th post!
Cheers!
7 comments
Another way to do that which I think is much cleaner beacause it does not do any rewrite.
Tested on Magento CE 1.9 and EE 1.14
https://gist.github.com/herveguetin/7c78e3991687744f164b
in ExtendedMenu module is implemented success fully in local store but when i add this code in online site, Admin Panel is totally blank, so please help me for solution for it…
i create news and event modules and i set as menu links every thing is fine, but there is a loading time difference between other menus and my own module menus, other menu links are loaded very fast when compare to my own module menu.
pls give the solution
Nice decision. I’ve used it to show/hide admin menu items according to module configuration. But there is one problem. When changing config and menu item should appear, it won’t because of block cache. Have any idea how to overcome this?
Hey bro cool extension by the way..but how would i go about getting this to appear in, lets say, the CMS section, maybe under static blocks…
can you guide us for,
How to create “Magento Vertical Accordion Menu”
THANKS
in advance
Congrats on the 500th Post!