9

I would like to add an extra tab to the product details ( backend ) and I don't want to perform any override, if possible.

What is the best way to accomplish this ?

16

Personally I would go for a layout/action approach using the addTab() provided by Mage_Adminhtml_Block_Widget_Tabs

So 2 main action are involved here:

  1. add XML layout changes
  2. create the tab class
  3. ( all this can be accomplish creating a new module, out of the scope here )

-- 1. Layout changes --

<?xml version="1.0"?>
<layout>
     <adminhtml_catalog_product_edit>
        <reference name="product_tabs">
            <block type="MODULENAME/adminhtml_catalog_product_edit_tab" name="custom_tab"/>
            <action method="addTab">
                <name>Custom Tab</name>
                <block>custom_tab</block>
            </action>
        </reference>
    </adminhtml_catalog_product_edit>
</layout>

-- 2. Tab Class --

<?php
class NAMESPACE_MODULENAME_Block_Adminhtml_Catalog_Product_Edit_Tab extends Mage_Adminhtml_Block_Widget
    implements Mage_Adminhtml_Block_Widget_Tab_Interface
{
    public function canShowTab()
    {
        return true;
    }
    public function getTabLabel()
    {
        return $this->__('Custom Tab');
    }
    public function getTabTitle()
    {
        return $this->__('Custom Tab');
    }
    public function isHidden()
    {
        return false;
    }
    public function getTabUrl()
    {
        return $this->getUrl('*/*/customtab', array('_current' => true));
    }
    public function getTabClass()
    {
        return 'ajax';
    }
} 

Note:
There is very few documentation about backend development, I feel like Magento Devs. are kind of shy to share knowledge about this area (and that is why of the above question.)

Source:
This technique can be found here:
- http://www.webspeaks.in/2012/02/create-custom-tab-in-magento-product-addedit-page.html and also in the comments of this Inchoo article:
- http://inchoo.net/ecommerce/magento/how-to-add-custom-product-relations-in-magento/

4

Here is how I do it.

Create an observer for the event core_block_abstract_prepare_layout_after. Not sure if it's the best event though.

<adminhtml>
    ...
    <events>
       <core_block_abstract_prepare_layout_after>
            <observers>
                <[namespace]_[module]_product>
                    <type>singleton</type>
                    <class>[module]/adminhtml_observer</class>
                    <method>addProductTabBlock</method>
                </[namespace]_[module]_product>
            </observers>
       </core_block_abstract_prepare_layout_after>
    </events>
    ....
</adminhtml>

Then create the observer

class [Namespace]_[Module]_Model_Adminhtml_Observer {
    //this checks if the tab can be added. You don't want to add the tab when selecting the product type and attribute set or when selecting the configurable attributes.
    protected function _canAddTab($product){
        if ($product->getId()){
            return true;
        }
        if (!$product->getAttributeSetId()){
            return false;
        }
        $request = Mage::app()->getRequest();
        if ($request->getParam('type') == 'configurable'){
            if ($request->getParam('attributes')){
                return true;
            }
        }
        return false;
    }
    //the method that actually adds the tab
    public function addProductTabBlock($observer){
        $block = $observer->getEvent()->getBlock();
        $product = Mage::registry('product');
        //if on product tabs block and the tab can be added...
        if ($block instanceof Mage_Adminhtml_Block_Catalog_Product_Edit_Tabs && $this->_canAddTab($product)){
            //in case there is an ajax tab
            $block->addTab('some_identifier_here', array(
                'label' => Mage::helper('catalog')->__('Some Label here'),

                'url'   => Mage::helper('adminhtml')->getUrl('adminhtml/some_url/here', array('_current' => true)),
                'class' => 'ajax', 
            ));
            //in case it's a simple content tab
            $block->addTab('other_identifier_here', array(
                 'label'     => Mage::helper('catalog')->__('Label here'),
                'content'   => $this->getLayout()->createBlock('[module]/block_alias')->toHtml(),
            )); 
        }
        return $this;
    }
}

Just make sure you replace [namespace] and [module] with the values you have for your module.

  • this is not a best practice – Fra Jul 2 '14 at 12:42
  • 2
    @Fra I didn't say it is. The answer started with "Here is how I do it.". And it works. Feel free to challange it, change it or come with a better alternative. – Marius Jul 2 '14 at 13:02
  • it is good to have this approach so we can collect all possible solution in this page. ( check my answer for a more "Magento" way ) – Fra Jul 2 '14 at 13:07
  • @Fra. Interesting. I will try it. – Marius Jul 2 '14 at 13:09
  • @Marius, i want to create a new menu like catalog->manage products. Is there any way to perform.Exact copy of catalog->manage products. – Mujahidh Jan 19 '17 at 12:55
2

Add the following code to your config.xml file

<blocks>
...
    <modulename>
        <class>Company_ModuleName_Block</class>
    </modulename>
    <adminhtml>
        <rewrite>
             <catalog_product_edit_tabs>Company_ModuleName_Block_Adminhtml_Tabs</catalog_product_edit_tabs>
         </rewrite>
     </adminhtml>
...
</blocks>

After this you should create a new file: Company/ModuleName/Block/Adminhtml/Tabs.php

<?php

class Company_ModuleName_Block_Adminhtml_Tabs extends Mage_Adminhtml_Block_Catalog_Product_Edit_Tabs
{
    private $parent;

    protected function _prepareLayout()
    {
        //get all existing tabs
        $this->parent = parent::_prepareLayout();
        //add new tab
        $this->addTab('tabid', array(
                     'label'     => Mage::helper('catalog')->__('New Tab'),
                     'content'   => $this->getLayout()
             ->createBlock('modulename/adminhtml_tabs_tabid')->toHtml(),
        ));
        return $this->parent;
    }
}

Next, create a file: Company/ModuleName/Block/Adminhtml/Tabs/Tabid.php

<?php

class Company_ModuleName_Block_Adminhtml_Tabs_Tabid extends Mage_Adminhtml_Block_Widget
{
    public function __construct()
    {
        parent::__construct();
        $this->setTemplate('modulename/newtab.phtml');
    }
}

app/code/local/Mage/Adminhtml/Block/Catalog/Product/Edit/Tabs.php

) and add the following snippet to the function _prepareLayout()

$this->addTab('tabid', array(
              'label'     => Mage::helper('catalog')->__('New Tab'),
              'content'   => $this->_translateHtml($this->getLayout()
     ->createBlock('modulname/adminhtml_tabs_tabid')->toHtml()),
));

You can always create a local of any core file.

  • rewrite was not welcome, anyway it is good to have this approach so we have all possible solution here – Fra Jul 2 '14 at 13:05
  • We can always avoid rewriting by creating a local, anyways when you have your personal favorite, its better to proceed with that. Good Luck – TBI Infotech Jul 2 '14 at 13:06
  • this last answer is really not good ... local should only used as last solution, it is really worst than use a rewrite – Fra Jul 2 '14 at 13:09
  • Please suggest how is creating a local worse the rewrite? – TBI Infotech Jul 2 '14 at 13:10
  • have you ever upgrade magento ? local should never used, this is best practice ... local is almost like edit core file. – Fra Jul 2 '14 at 13:15

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.