So I'm running into a strange issue. I'm trying to do a layout update by latching onto the handle for the controller action that corresponds to this URL: ".../index.php/admin/catalog_category/index/".
Essentially, in the admin panel, when the user clicks Catalog->Categories->Manage Categories, this is the URL that appears. In my own module, I am attempting to latch onto this controller action using the following update:
<layout>
<admin_catalog_category_index>
<reference name="content">
<block type="categorysearch/adminhtml_categorysearch_search" name="categorysearch" />
</reference>
</admin_catalog_category_index>
</layout>
I am unsure of why this isn't working correctly. I'm having a lot of trouble figuring out why my block isn't being added.
Thank you for any help you can offer!
EDIT: Also, I forgot to mention that in the construct function of my block, I am simply echoing out "got here" and killing the app. I have tested the block with other handles and controller actions to confirm that the block is loading correctly. I also have placed other handles in the xml file I am using to make sure that the xml file is being loaded.
Update I tried using the LayoutViewer module that is provided by alanstorm at this url: "http://alanstorm.com/layouts_blocks_and_templates". In using this tool, it turns out that no handles are present, how is this possible?
It looks like you're using the wrong layout handle, although it's easy to see why folks would get tripped up by this.
If I use Commerce Bug to view the layout handles (self link, Commerce Bug is the commercial debugging extension I created and sell) for that page, I see the following
So that's admin_catalog_category_edit
instead of admin_catalog_category_index
.
Why edit
instead of index
? If I use Commerce Bug's Request tab to find the controller file
and then look at the index action method.
#File: app/code/core/Mage/Adminhtml/controllers/Catalog/CategoryController.php
public function indexAction()
{
$this->_forward('edit');
}
Ah ha! The indexAction
method forwards to the edit
action. When you forward a request in Magento, you're saying
Hey Magento, let's pretend the request used this action method instead of the actual action method, without doing an HTTP redirect.
Assuming your Layout XML is in the correct file, change your admin_catalog_category_index
handle to admin_catalog_category_edit
and you'll be good to go.
Update: Assuming, of course, you don't want to update the content block.
The other problem with the category editing page is, when the page load it replaces its content area with an AJAX request. When I added the following to local.xml
<layout>
<admin_catalog_category_index>
<reference name="content">
<!-- <block type="categorysearch/adminhtml_categorysearch_search" name="categorysearch" /> -->
<block type="core/text" name="WednesdayApril32013">
<action method="setText">
<text>This is a test</text>
</action>
</block>
</reference>
</admin_catalog_category_index>
</layout>
The text "This is a test" was rendered in the page source (View -> Developer -> View Source
in Chrome). However, Magento immediately makes a background ajax request to a URL something like this
http://store.example.com/index.php/admin/catalog_category/edit/key/c184cfd77dcf298659d1cb3a31c51852/section/general/?isAjax=true
and replaces the content section. If we take another look at the controller
#File: app/code/core/Mage/Adminhtml/controllers/Catalog/CategoryController.php
if ($this->getRequest()->getQuery('isAjax')) {
// prepare breadcrumbs of selected category, if any
$breadcrumbsPath = $category->getPath();
if (empty($breadcrumbsPath)) {
// but if no category, and it is deleted - prepare breadcrumbs from path, saved in session
$breadcrumbsPath = Mage::getSingleton('admin/session')->getDeletedPath(true);
if (!empty($breadcrumbsPath)) {
$breadcrumbsPath = explode('/', $breadcrumbsPath);
// no need to get parent breadcrumbs if deleting category level 1
if (count($breadcrumbsPath) <= 1) {
$breadcrumbsPath = '';
}
else {
array_pop($breadcrumbsPath);
$breadcrumbsPath = implode('/', $breadcrumbsPath);
}
}
}
Mage::getSingleton('admin/session')
->setLastViewedStore($this->getRequest()->getParam('store'));
Mage::getSingleton('admin/session')
->setLastEditedCategory($category->getId());
// $this->_initLayoutMessages('adminhtml/session');
$this->loadLayout();
$eventResponse = new Varien_Object(array(
'content' => $this->getLayout()->getBlock('category.edit')->getFormHtml()
. $this->getLayout()->getBlock('category.tree')
->getBreadcrumbsJavascript($breadcrumbsPath, 'editingCategoryBreadcrumbs'),
'messages' => $this->getLayout()->getMessagesBlock()->getGroupedHtml(),
));
Mage::dispatchEvent('category_prepare_ajax_response', array(
'response' => $eventResponse,
'controller' => $this
));
$this->getResponse()->setBody(
Mage::helper('core')->jsonEncode($eventResponse->getData())
);
return;
}
We can this this ajax request is handled outside of the normal layout rendering flow.
So, with this additional knowledge, I'd create an event listener for category_prepare_ajax_response
, and then add your content to the response object that's passed in