This article introduces a best practice about magento admin grid customizations.
When you want to customize a magento grid (for instance, add new columns), you can use the magento rewrite mechanism to achieve your goal :

The old fashioned method

1. Declare the rewrite in your module config.xml file :

<sales_order_grid> MyCompany_MyModule_Block_Adminhtml_Sales_Order_Grid</ sales_order_grid >

2. Create the new class that extends the grid :

class MyCompany_MyModule_Block_Adminhtml_Sales_Order_Grid extends Mage_Adminhtml_Block_Sales_Order_Grid

3. Add your columns :

$this->addColumn(‘MyColumn’, array(
    ‘header’ => Mage::helper(MyModule )->__( ‘My Column’),
  ‘index’ => ‘entity_id’,
    ‘renderer’  => MyCompany_MyModule _Block_Widget_Grid_Column_Renderer_MyRenderer’ ,
  ‘sortable’  => false

4. It works :


Even if this methods works perfectly, it causes a major issue : if another magento extension rewrites the same grid, there will be a conflict and one of the 2 extension will not properly work.
Hopefully, using Magento mechanism we can find a workaround

The smart method

The best method is too use Magento events rather than rewrites.


1. Listen to events raised when user displays the sales order grid page :

<events> <controller_action_layout_render_before_adminhtml_sales_order_index>

            < MyModule >
                < type>singleton</ type>
                                        < class>MyModule/Observer</ class>
                <method>controller_action_layout_render_before_adminhtml_sales_order_index </method>
            </ MyModule >


2. In the event handler, dynamically retrieve the grid block and raise a new event with that grid in parameters:


public function controller_action_layout_render_before_adminhtml_sales_order_index(Varien_Event_Observer $observer)

    $gridBlock = Mage::getSingleton( ‘core/layout’)->getBlock(‘sales_order.grid’);

    if ($gridBlock)

        Mage::dispatchEvent( ‘sales_order_grid_before_render’ , array( ‘grid’=>$gridBlock ));

    return $this;




3. Listen that event yourself (this part is optionnal, you can integrate the following code in #2) :

<sales_order_grid_before_render >
                  <MyModule >
            < type>singleton</ type>
                              < class>MyModule /Observer</ class>
            <method>sales_order_grid_before_render </method>
                 </MyModule >
</sales_order_grid_before_render >


4. Catch this event to add your own column :


public function sales_order_grid_before_render(Varien_Event_Observer $observer) {$grid = $observer->getEvent()->getgrid();

    $grid ->addColumnAfter(MyColumn , array(
        ‘header’=> Mage::helper( MyModule )->__(My Column ),
        ‘align’ => ‘center’,
‘entity’ => ‘order’,
‘filter’ => false,
‘sortable’ => false,
                 ‘width’ => ’60px’
    return $this;


5. It works too :





6. In fact, it partially works :

If you try to sort / filter or change the page on this grid, you’ll see that our column will disappear. The reason is that the grid is updated in ajax, and then request a diffferent url.
To fix the problem, add an additionnal listener to your config.xml :

<controller_action_layout_render_before_adminhtml_sales_order_grid >
type>singleton</ type>
class>AdvancedStock/Observer</ class>
method>controller_action_layout_render_before_adminhtml_sales_order_index </method>
AdvancedStock>    </observers></controller_action_layout_render_before_adminhtml_sales_order_grid>

And now, it works perfectly !

Want to say something ?