Add Custom Tabs to the Magento Product Admin

Posted on August 30, 2010 by BT There have been 36 comment(s)

In Magento eCommerce, it is possible to add new attributes to product models and edit the values for these attributes on the Product edit page. This is fine if we only want to add standard data (attributes) to a product, but what if we wanted to do something a little different?

This article explains how to build a simple custom Magento extension that will add a new tab to the product edit page and provide a facility for processing that data when the user hits the Save button.

Creating the Magento Extension

The first step is to create the extension's setup file, which loads the extension into Magento.

app/etc/modules/Fishpig_Customtabs.xml

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

This file will register the extension in Magento, telling it to look in the app/code/local/Fishpig/Customtabs/ directory for the extension's code.

app/code/local/Fishpig/Customtabs/etc/config.xml

The next file we make is the extension's config file. This file is a more detailed setup file, containing information about the extension's classes, layout files and everything else we need to make it work.

Notice the events section of this file (below)? To save the product data, we listen for an event that is triggered when ever a product is saved in the Magento Admin. This allows us to access the custom data we have created in the tab and process/save it.

<?xml version="1.0"?>
<config>
    <modules>
        <Fishpig_CustomTabs>
            <version>0.1.0</version>
        </Fishpig_CustomTabs>
    </modules>
    <global>
        <blocks>
            <customtabs>
                <class>Fishpig_Customtabs_Block</class>
            </customtabs>
        </blocks>
        <models>
            <customtabs>
                <class>Fishpig_Customtabs_Model</class>
            </customtabs>
        </models>
    </global>
    <adminhtml>
    	<layout>
    		<updates>
    			<customtabs>
    				<file>customtabs.xml</file>
    			</customtabs>
    		</updates>
    	</layout>
        <events>
            <catalog_product_save_after>
                <observers>
                    <fishpig_save_product_data>
                        <type>singleton</type>
                        <class>customtabs/observer</class>
                        <method>saveProductTabData</method>
                    </fishpig_save_product_data>
                </observers>
            </catalog_product_save_after>
        </events>
    </adminhtml>
</config>

app/code/local/Fishpig/Customtabs/Block/Adminhtml/Catalog/Product/Tab.php

<?php

class Fishpig_Customtabs_Block_Adminhtml_Catalog_Product_Tab
extends Mage_Adminhtml_Block_Template
implements Mage_Adminhtml_Block_Widget_Tab_Interface {

	/**
	 * Set the template for the block
	 *
	 */
	public function _construct()
	{
		parent::_construct();

		$this->setTemplate('customtabs/catalog/product/tab.phtml');
	}

	/**
	 * Retrieve the label used for the tab relating to this block
	 *
	 * @return string
	 */
    public function getTabLabel()
    {
    	return $this->__('My Custom Tab');
    }

    /**
     * Retrieve the title used by this tab
     *
     * @return string
     */
    public function getTabTitle()
    {
    	return $this->__('Click here to view your custom tab content');
    }

	/**
	 * Determines whether to display the tab
	 * Add logic here to decide whether you want the tab to display
	 *
	 * @return bool
	 */
    public function canShowTab()
    {
		return true;
    }

    /**
     * Stops the tab being hidden
     *
     * @return bool
     */
    public function isHidden()
    {
    	return false;
    }

	/**
	 * AJAX TAB's
	 * If you want to use an AJAX tab, uncomment the following functions
	 * Please note that you will need to setup a controller to recieve
	 * the tab content request
	 *
	 */
	/**
	 * Retrieve the class name of the tab
	 * Return 'ajax' here if you want the tab to be loaded via Ajax
	 *
	 * return string
	 */
#	public function getTabClass()
#	{
#		return 'my-custom-tab';
#	}

	/**
	 * Determine whether to generate content on load or via AJAX
	 * If true, the tab's content won't be loaded until the tab is clicked
	 * You will need to setup a controller to handle the tab request
	 *
	 * @return bool
	 */
#	public function getSkipGenerateContent()
#	{
#		return false;
#	}

	/**
	 * Retrieve the URL used to load the tab content
	 * Return the URL here used to load the content by Ajax
	 * see self::getSkipGenerateContent & self::getTabClass
	 *
	 * @return string
	 */
#	public function getTabUrl()
#	{
#		return null;
#	}

}

This is a big file and is the main code file for our tab. This file extends Mage_Adminhtml_Block_Template, which is the base Adminhtml template and doesn't do much. Your tab block can extend any block file in Magento, for example, in FishPig's WordPress Integration, we use this method to extend the grid class to display a list of WordPress posts.

On it's own, the above code won't do anything as we haven't included it yet. Let's include it now by creating a layout XML file for our extension.

app/design/adminhtml/default/default/layout/customtabs.xml

This is the layout file for the Adminhtml section of the extension. In here we will include the tab on the Magento Product edit page.

<?xml version="1.0"?>
<layout>
	<adminhtml_catalog_product_edit>
		<reference name="product_tabs">
			<action method="addTab">
				<name>my_custom_tab</name>
				<block>customtabs/adminhtml_catalog_product_tab</block>
			</action>
		</reference>
	</adminhtml_catalog_product_edit>
</layout>

This file is quite simple but without it, nothing will show on the product edit page. The last thing to do before we can see our tab in action is to create our new template file.

app/design/adminhtml/default/default/template/customtabs/catalog/product/tab.phtml

<?php
/**
 * Custom tab template
 */
?>
<div class="input-field">
 <label for="custom_field">Custom Field</label>
 <input type="text" class="input-text" name="custom_field" id="custom_field" />
</div>

Although this example is simple, you could enter anything you want in here. Using this and your block hopefully you can see how truly limitless the options are to you.

Testing Our Custom Magento Admin Tab

Now that we have the code in place, let's refresh our cache, go to a product edit page and see the tab in action!

Did it work? If it didn't work, check through your XML again as a slight error in any of that will stop everything working.

Now that we have our tab, let's take a look at how to process the data once the user hits the 'Save' button.

Saving our Custom Tab Data

To access the data during the saving process, we have hooked into an event called catalog_product_save_after (see config.xml above). This event is triggered each time a product model is saved. As we have declared our observer for this event inside the adminhtml block, we will only trigger our code when a product model is saved from the Magento Admin.

app/code/local/Fishpig/Customtabs/Model/Observer.php

<?php

class Fishpig_Customtabs_Model_Observer
{
	/**
	 * Flag to stop observer executing more than once
	 *
	 * @var static bool
	 */
	static protected $_singletonFlag = false;

	/**
	 * This method will run when the product is saved from the Magento Admin
	 * Use this function to update the product model, process the
	 * data or anything you like
	 *
	 * @param Varien_Event_Observer $observer
	 */
	public function saveProductTabData(Varien_Event_Observer $observer)
	{
		if (!self::$_singletonFlag) {
			self::$_singletonFlag = true;

			$product = $observer->getEvent()->getProduct();

			try {
				/**
				 * Perform any actions you want here
				 *
				 */
				$customFieldValue =  $this->_getRequest()->getPost('custom_field');

				/**
				 * Uncomment the line below to save the product
				 *
				 */
				//$product->save();
			}
			catch (Exception $e) {
				Mage::getSingleton('adminhtml/session')->addError($e->getMessage());
			}
		}
	}

	/**
	 * Retrieve the product model
	 *
	 * @return Mage_Catalog_Model_Product $product
	 */
	public function getProduct()
	{
		return Mage::registry('product');
	}

    /**
     * Shortcut to getRequest
     *
     */
    protected function _getRequest()
    {
        return Mage::app()->getRequest();
    }
}

Although this code doesn't do anything with the data, it hopefully illustrates how to access the data, after which you can do what ever you want.

Wrapping it Up

The extension you have just written is a simple extension that will allow you to add custom tabs in the Product edit page of the Magento Admin. This concept can be applied to any of the other sections in Magento (categories, customers etc) so take the time to study the code and understand how it works. For a more practical implementation of this, take a look at the code in FishPig's WordPress Integration as this uses this system to add custom data grid's as AJAX tabs to the Product edit page of the Magento Admin.


This post was posted in Magento Tutorials and was tagged with Magento Advanced, Magento Custom Module

36 Responses to Add Custom Tabs to the Magento Product Admin

  • Tom Tep
    Tom Tep says:

    ohh, it showed. thank you, http://fishpig.co.uk/

    Posted on November 2, 2011 at 8:30 am

  • MagePsycho

    Is there a way to set position of tabs created this way?
    Thanks

    Posted on November 23, 2011 at 6:55 am

  • Vishal
    Vishal says:

    Hi fishpig,

    It is such a great article. but i am using grid in these tab, grid came successfully but data did not save. and on the right side of tab it gave a yellow icon and the tittle of these icon is
    " This tab contains invalid data. Please solve the problem before saving. ".
    and in my tab.php, I Wrote the following code

    $this->addTab('devicetype_section', array(
    'label' => Mage::helper('devicetype')->__('Related Brands'),
    'title' => Mage::helper('devicetype')->__('Related Brands'),
    'content' => $this->getLayout()->createBlock('devicetype/adminhtml_devicetype_relatedbrandgrid')->toHtml(),

    ));
    to create the tab

    and in relatedbrandgrid.php just copy the default grid.php

    plz give me the soluation for these how to remove these error and save data..

    " This tab contains invalid data. Please solve the problem before saving."

    Thanx

    Vishal



    Posted on November 30, 2011 at 4:21 am

  • Russell Albin

    Trying to modify this a bit to use on Customers, but its producing an error, do you have an example of how to tweak this to use on Edit/View Customers, not Products!

    Posted on December 26, 2011 at 7:25 am

  • Jonathan Vu

    Just wanted to say Thanks, this was the exact code I needed to start on my current project

    Posted on January 23, 2012 at 11:16 pm

  • Vijay
    Vijay says:

    Hi fishpig,

    Great post.Thanks for this type of posting and we hope you will continue your posting so that every one like me get so much beneficial from that.

    Thanks
    Vijay Gupta

    Posted on January 30, 2012 at 9:45 am

  • Peter
    Peter says:

    Great post. I need to make my custom field required. How can i do that?

    Posted on January 31, 2012 at 10:56 am

  • Haney
    Haney says:

    I'm looking for to add a new tabpage under category in magento admin, which loads the category grid. Idea is to associate multiple categories to one category and on the front end, when you click on that particular category, it should show products from all the associated categories. Is there any better solution then create a new tabpage with categories grid?
    If not then can anybody help me to guide how to create a new tabpage under category in admin...

    Posted on February 3, 2012 at 3:23 pm

  • ranjeet
    ranjeet says:

    Very nice it is very helpful for me i used this info to add new column in admin order page. Thanks

    Posted on February 24, 2012 at 10:30 am

  • hoping
    hoping says:

    Thanks. good

    Posted on March 7, 2012 at 4:16 am

  • Bart
    Bart says:

    Great article FishPig. Thanks for posting.

    Posted on March 8, 2012 at 4:58 am

Items 26 to 36 of 36 total

Page:
  1. 1
  2. 2
Have your say...

You must be logged in to post a comment.