0

Why doesn't this:

<adminhtml_report_product_sold>
    <reference name="menu">
        <action method="setActive">
            <menupath>mymodulesmenupath</menupath>
        </action>
    </reference>
</adminhtml_report_product_sold>

make my module's menu active but instead the Reports menu remains active? For context, I have a menu item which redirects to the products ordered report but I want my modules menu to be active as if the user is still in my menu.

1

Magento's core code is calling _setActiveMenu after it loads the layout. So your setActive gets called, but then Magento calls setActive again, so Magento wins.

Details: To render a Magento layout, the author of a controller action method needs to call

$this->loadLayout();
$this->renderLayout();

When they call loadLayout, that's the method which goes through the layout update XML, instantiates the configured blocks, and calls any <action/> methods.

In the report controllers, the soldAction method looks like this

#File: app/code/core/Mage/Adminhtml/controllers/Report/ProductController.php
public function soldAction()
{
    $this->_title($this->__('Reports'))
         ->_title($this->__('Products'))
         ->_title($this->__('Products Ordered'));

    $this->_initAction()
        ->_setActiveMenu('report/product/sold')
        ->_addBreadcrumb(Mage::helper('reports')->__('Products Ordered'), Mage::helper('reports')->__('Products Ordered'))
        ->_addContent($this->getLayout()->createBlock('adminhtml/report_product_sold'))
        ->renderLayout();
}

So where's the call to loadLayout? Is happens in _initAction.

#File: app/code/core/Mage/Adminhtml/Controller/Report/Abstract.php
public function _initAction()
{
    $this->loadLayout()
        ->_addBreadcrumb(Mage::helper('reports')->__('Reports'), Mage::helper('reports')->__('Reports'));
    return $this;
}

So, since the report controller calls loadLayout first, and then sets the active menu, your layout update XML can never win.

One possible solution is an event observer for controller_action_layout_render_before, and if the listener set the active menu if you're on the correct page (otherwise just return early from the observer)

| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.