views:

39

answers:

2

I'm trying to create a custom report in the Magento back-end; my strategy is to first make my new module mimic the existing Reports/Sales/Orders functionality in the admin panel, and then make the required changes once I've seen how the pieces fit together. I've added my new menu item, and the module loads the basic admin layout and some breadcrumbs, so the module config and controller config are set up properly enough. However, layout blocks aren't loading. Here's the problem code. Assume that I have a copy of the relevant block file at app/code/local/BULX/Reports/Block/Report/Sales/Sales/Grid.php:

class BULX_Reports_IndexController extends Mage_Adminhtml_Report_SalesController { 

  public function salesAction {

  //...otherwise identical to parent class

  //should load reference to Grid block
  $gridBlock = $this->getLayout()->getBlock('report_sales_sales.grid');

  /* in original Mage module, will output Mage_Adminhtml_Block_Report_Sales_Sales_Grid
     in BULX_Report, outputs nothing. */
  echo get_class($gridBlock)."<br>";

My config file has

<global>
  <blocks>
    <bulx_reports>
      <class>BULX_Reports_Block</class>
    </bulx_reports>
  </blocks>
  ...
</global>

If I change the code to

$gridBlock = $this->getLayout()->getBlock('bulx_reports/test');

with the following file at app/code/local/BULX/Reports/Block/Test.php

class BULX_Reports_Block_Test extends Mage_Core_Block_Abstract
{
 protected function _toHtml() {
  echo 'to html';
 }
}

I get the same result: no 'to html' output, no output from the get_class call

I added log statements as suggested here: http://www.fontis.com.au/blog/magento/magento-debugging-loading-blocks-layouts-and-config-files

and it's clear from that Magento isn't finding any layout blocks in my new module. Alan Storm's tutorials are usually incredibly helpful, but I'm not finding what I need in alanstorm.com/magento_admin_controllers (sorry not enough reputation to have two hyperlinks); as far as I can tell, I've set up my configuration identically. A difficulty is that the 'report_sales_sales.grid' string doesn't appear anywhere-those Grids appear in lots of places in the admin, and they get built dynamically by a structure that I haven't found.

What am I missing? This is Enterprise Edition, 1.8. Thanks!

+1  A: 

Check the file app/design/adminhtml/default/default/layout/sales.xml for the section <adminhtml_report_sales_sales> - which matches the requested URL. It has a block of type "adminhtml/report_sales_sales" which is a grid container, grid containers automatically create their child grid block.

So the missing block "report_sales_sales.grid" is created by having a "adminhtml/report_sales_sales" block defined in the layout. Since your page is new it's URL won't yet have a matching section in a layout XML file, so no grid container, so no grid. Copy the <adminhtml_report_sales_sales> section from sales.xml to your own layout file and name it to match your page URL.

clockworkgeek
Ok, that makes some sense. I defined bulxreports.xml in the module config and copied the adminhtml_report_sales_sales section into it, renaming it bulxreports_index_sales, but that didn't have any effect. Should I be renaming the parameter that passes to the getBlock to match the url? What else can I look for?
kevinpaulconnor
Try installing LayoutViewer from Alanstorm.com , that will tell you what layout handles are in the current request for you to work with. Or his commercebug extension.
Jonathan Day
LayoutViewer is great and I use it regularly on the front end. I didn't realize that it works in the admin panel-thanks.
kevinpaulconnor
+1  A: 
  1. General PHP debugging tip, never "echo" to the browser, always var_dump($var). This will do smart things, such as actually print out "false" for a boolean false instead of a blank string, which is what I think is happening here.

  2. Your attempt to get the block named "report_sales_sales.grid" is most likely returning false. That's because a block by this name hasn't been added to The Layout.

  3. I'm not certain, but my guess is a block by this name is added somewhere in the execution chain set off by the particular layout update in app/design/adminhtml/default/default/layout/sales.xml

    store_ids created_at_order Order Created Date updated_at_order Order Updated Date report_type note Order Updated Date report is real-time, does not need statistics refreshing.

Most likely, the block named sales.report.grid.container (with a URI adminhtml/report_sales_sales which coresponds to the class Mage_Adminhtml_Block_Report_Sales_Sales) adds a sub-block (but don't quote me on that)

The larger point being, you general approach here was good, but you didn't copy enough. The request to the Magento page runs with the Layout handle "adminhtml_report_sales_sales". A request to your page is going to run with a Layout handle something like "adminhtml_report_index_sales", which means the above layout block doesn't get loaded into the system. (if this made no sense, read up on Layout Handles.)

You either need to

  1. Configure your module to use a custom layout files that adds the block for your handles

  2. Use a local.xml to do the same as the above (caveat, I'm not sure local.xml is used for the Admin layout system)

  3. Pragmatically add the needed blocks in your controller action.

Alan Storm
Does an admin layout handle always have to start with adminhtml? Perhaps that's my problem: my handle goes bulxreport_index_sales, but perhaps it should be adminhtml_bulxreport_index_sales. That doesn't seem to work either, however. I've had to put this aside for a few days and won't be able to put it back up for a few more, unfortunately
kevinpaulconnor