Adding a column to the customers grid in Magento admin. Alternative way

Pretty often we face a task, where we need to add a custom column to the customers/orders grid in Magento admin. The solution is simple and if you google for it, you will get tons of solutions. However, pretty much all of them describe the same way, which isn’t always proper.
Nick described the simple and trivial way of adding columns in his article Adding a custom attribute/column to the orders grid in Magento admin and you are always able to follow it, except the cases, when some other extension already overrides the _prepareColumns() method. At that point, we need some universal solution that won’t conflict with other extensions that may potentially be overwriting the grid block. So, let’s use an observer for our task.
First of all, you need to add your own extension for registering the observer. Create config files and other necessary stuff:

Config to load the extension (app/etc/modules/Atwix_CustomGrid.xml):

<?xml version="1.0"?>
<config>
    <modules>
        <Atwix_CustomGrid>
            <active>true</active>
            <codePool>local</codePool>
        </Atwix_CustomGrid>
    </modules>
</config>

The extension config file (app/code/local/Atwix/CustomGrid/etc/config.xml):

<?xml version="1.0"?>
<config>
    <modules>
        <Atwix_CustomGrid>
            <version>0.4.0</version>
        </Atwix_CustomGrid>
    </modules>
    <global>
        <models>
            <atwix_customgrid>
                <class>Atwix_CustomGrid_Model</class>
            </atwix_customgrid>
        </models>
    </global>
    <adminhtml>
        <events>
            <core_block_abstract_prepare_layout_before>
                <observers>
                    <customgrid_column_append>
                        <type>model</type>
                        <class>Atwix_CustomGrid_Model_Observer</class>
                        <method>appendCustomColumn</method>
                    </customgrid_column_append>
                </observers>
            </core_block_abstract_prepare_layout_before>
        </events>
    </adminhtml>
</config>

The observer itself (app/code/local/Atwix/CustomGrid/Model/Observer.php):

class Atwix_CustomGrid_Model_Observer extends Varien_Event_Observer
{
    /**
     * Adds column to admin customers grid
     *
     * @param Varien_Event_Observer $observer
     * @return Atwix_CustomGrid_Model_Observer
     */
    public function appendCustomColumn(Varien_Event_Observer $observer)
    {
        $block = $observer->getBlock();
        if (!isset($block)) {
            return $this;
        }

        if ($block->getType() == 'adminhtml/customer_grid') {
            /* @var $block Mage_Adminhtml_Block_Customer_Grid */
            $block->addColumnAfter('middlename', array(
                'header'    => 'Middle Name',
                'type'      => 'text',
                'index'     => 'middlename',
            ), 'email');
        }
    }
}

As you can see, the observer retrieves the customer grid block and executes its method addColumnAfter for adding a new column. The column type is “text” and the index is “middlename”. “Middlename” – it’s standard customer’s attribute in Magento, but you are able to add any custom attribute using this way.
The advantage of this method: your code won’t conflict with other third party solutions that also add custom columns. You can use the observer for adding a column to almost any grid in Magento admin. All you need is to change the following condition:

$block->getType() == 'adminhtml/customer_grid')

depending on your grid block. For example, order’s grid block is adminhtml/sales_order_grid.
Good luck and do not hesitate to ask your questions in comments below :)