Hi I want to add a column to the catolg > manage products section (not the product but the list of products), this column needs to list any related products the product has
To improve on answer https://stackoverflow.com/a/5994209/1025437 by clockworkgeek:
I decided not to use the observers, in my opinion those events are too global and lead to our observer being called many times. Using the following rewrite in your own module config.xml:
<config>
<global>
<blocks>
<adminhtml>
<rewrite>
<catalog_product_grid>Myname_Catalogextended_Block_Adminhtml_Catalog_Product_Grid</catalog_product_grid>
</rewrite>
</adminhtml>
</blocks>
</global>
</config>
With the following file in
app/code/local/Myname/Catalogextended/Block/Adminhtml/Catalog/Product/Grid.php
containing something like:
<?php
class Myname_Catalogextended_Block_Adminhtml_Catalog_Product_Grid extends Mage_Adminhtml_Block_Catalog_Product_Grid
{
/* Overwritten to be able to add custom columns to the product grid. Normally
* one would overwrite the function _prepareCollection, but it won't work because
* you have to call parent::_prepareCollection() first to get the collection.
*
* But since parent::_prepareCollection() also finishes the collection, the
* joins and attributes to select added in the overwritten _prepareCollection()
* are 'forgotten'.
*
* By overwriting setCollection (which is called in parent::_prepareCollection()),
* we are able to add the join and/or attribute select in a proper way.
*
*/
public function setCollection($collection)
{
/* @var $collection Mage_Catalog_Model_Resource_Product_Collection */
$store = $this->_getStore();
if ($store->getId() && !isset($this->_joinAttributes['special_price'])) {
$collection->joinAttribute(
'special_price',
'catalog_product/special_price',
'entity_id',
null,
'left',
$store->getId()
);
}
else {
$collection->addAttributeToSelect('special_price');
}
parent::setCollection($collection);
}
protected function _prepareColumns()
{
$store = $this->_getStore();
$this->addColumnAfter('special_price',
array(
'header'=> Mage::helper('catalog')->__('special_price'),
'type' => 'price',
'currency_code' => $store->getBaseCurrency()->getCode(),
'index' => 'special_price',
),
'price'
);
return parent::_prepareColumns();
}
}
In this example, an attribute named special_price
is added after column price
. Since this attribute has a store scope, the check for store is added.
I recently (yesterday in fact) had to add a column to the same grid. Partly because it is poor practice and mostly because another module had already used it's own override, I didn't want to replace or override the class completely. Instead here is a clean way to modify the product's grid via events.
app/code/local/My/Module/etc/config.xml
<config>
<adminhtml>
<events>
<adminhtml_block_html_before>
<observers>
<mymodule>
<!-- Add column to catalog product grid -->
<class>mymodule/adminhtml_observer</class>
<method>onBlockHtmlBefore</method>
</mymodule>
</observers>
</adminhtml_block_html_before>
<eav_collection_abstract_load_before>
<observers>
<mymodule>
<!-- Add column to product list -->
<class>mymodule/adminhtml_observer</class>
<method>onEavLoadBefore</method>
</mymodule>
</observers>
</eav_collection_abstract_load_before>
</events>
</adminhtml>
</config>
app/code/local/My/Module/Model/Adminhtml/Observer
class My_Module_Model_Adminhtml_Observer
{
public function onBlockHtmlBefore(Varien_Event_Observer $observer) {
$block = $observer->getBlock();
if (!isset($block)) return;
switch ($block->getType()) {
case 'adminhtml/catalog_product_grid':
/* @var $block Mage_Adminhtml_Block_Catalog_Product_Grid */
$block->addColumn('COLUMN_ID', array(
'header' => Mage::helper('mymodule')->__('COLUMN HEADER'),
'index' => 'COLUMN_ID',
));
break;
}
}
public function onEavLoadBefore(Varien_Event_Observer $observer) {
$collection = $observer->getCollection();
if (!isset($collection)) return;
if (is_a($collection, 'Mage_Catalog_Model_Resource_Eav_Mysql4_Product_Collection')) {
/* @var $collection Mage_Catalog_Model_Resource_Eav_Mysql4_Product_Collection */
// Manipulate $collection here to add a COLUMN_ID column
$collection->addExpressionAttributeToSelect('COLUMN_ID', '...Some SQL goes here...');
}
}
}