Mid September 2010
April 29th, 2009 • Posted in Magento
Tweet
One of the key benefits of developing ecommerce sites on the Magento platform is the flexibility of the system. Almost every area of the system can be tweaked and modified to meet exact client requirements. However it’s also worth noting that Magento is a young platform (only just over a year in production) and new versions of the software are released on a regular basis. With this in mind it’s important to try and make sites as upgradeable as possible in order to make life easier in the future. Quite often people see that a change is required and jump straight in to edit the core code – bad idea. Here I will show you how simple it is to extend an existing class to add new functionality to satisfy a specific requirement.
In the example below I will simply be extending the navigation class to create a slightly modified version of the drawItem class which Magento uses to draw out the main menu. This modified version will be free of the javascript calls and spans of the original to enable me to provide a cleaner HTML output.
There are 4 basic steps in the process:
In this case I have taken the existing Magento drawItem function and modified it to create a cleaner output and renamed it drawItemClean. This file should be saved to /app/code/local/Magetips/Catalog/Block/Navigation.php – note you should use whatever name you prefer for your modifications. I have placed all of my modifications in a namespace called Magetips for convenience.
<?php/** * Magetips Layout Modifications * * NOTICE OF LICENSE * * This source file is subject to the Open Software License (OSL 3.0) * that is available online at this URL: * http://opensource.org/licenses/osl-3.0.php * * @category Magetips * @package Magetips_Layout * @author Simon Young * @copyright Copyright (c) 2009 Simon Young (http://magetips.com) * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) * * LEGAL DISCLAIMER * * Please note particularly the disclaimer in section 8 of Open Software License ("OSL") v. 3.0 * * Limitation of Liability. Under no circumstances and under no legal theory, whether in tort * (including negligence), contract, or otherwise, shall the Licensor be liable to anyone for * any indirect, special, incidental, or consequential damages of any character arising as a * result of this License or the use of the Original Work including, without limitation, damages * for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other * commercial damages or losses. This limitation of liability shall not apply to the extent * applicable law prohibits such limitation. * * EXTENSION INFORMATION * * This extension creates an additional function to enable the generation of a 'clean' * main navigation structure - i.e. removing class names and javascript calls from default * Magento drawItem function * **/
class Magetips_Catalog_Block_Navigation extends Mage_Catalog_Block_Navigation{
public function drawItemClean($category, $level=0, $last=false) { $html = ''; if (!$category->getIsActive()) { return $html; } if (Mage::helper('catalog/category_flat')->isEnabled()) { $children = $category->getChildrenNodes(); $childrenCount = count($children); } else { $children = $category->getChildren(); $childrenCount = $children->count(); } $hasChildren = $children && $childrenCount; $html.= '<li'; $html.= ' id="nav-'.str_replace('/', '-', Mage::helper('catalog/category')->getCategoryUrlPath($category->getRequestPath())).'"'; $html.= ' class="level'.$level; if ($this->isCategoryActive($category)) { $html.= ' active'; } if ($last) { $html .= ' last'; } if ($hasChildren) { $cnt = 0; foreach ($children as $child) { if ($child->getIsActive()) { $cnt++; } } $html .= ' parent'; } $html.= '">'."\n"; $html.= '<a href="'.$this->getCategoryUrl($category).'" title="'.$this->htmlEscape($category->getName()).'">'.$this->htmlEscape($category->getName()).'</a>'."\n";
if ($hasChildren){
$j = 0; $htmlChildren = ''; foreach ($children as $child) { if ($child->getIsActive()) { $htmlChildren.= $this->drawItemClean($child, $level+1, ++$j >= $cnt); } }
if (!empty($htmlChildren)) { $html.= '<ul class="sub-nav" id="sub-nav-'.str_replace('/', '-', Mage::helper('catalog/category')->getCategoryUrlPath($category->getRequestPath())).'">'."\n" .$htmlChildren .'</ul>'; }
} $html.= '</li>'."\n"; return $html; }
}Once you have extended the base class you need to let Magento know about this when it is loading the framework. To do this you create an XML configuration file which should be saved to /app/etc/modules/Magetips_Layout.xml – remember the name will depend on the namespace you have chosen for your code modifications.
<?xml version="1.0"?> <config> <global> <blocks> <catalog> <rewrite> <navigation>Magetips_Catalog_Block_Navigation</navigation> </rewrite> </catalog> </blocks> </global></config>This file basically tells Magento you have a local modification for Catalog Navigation and it will find and execute your Navigation.php file from step 1.
Once the new function is available we can either modify the existing Magento template to output the results of the new function or add a new custom template for maximum flexibility. The location of the file will depend on the interface and theme in use – in our case the location is /design/frontend/blank/default/template/catalog/navigation/custom-home.phtml
<?php/** * NOTICE OF LICENSE (MIT License) * * Copyright (c) 2009, One Eighty Studios Limited * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. * * This license is also available online at: * http://opensource.org/licenses/mit-license.php * * DISCLAIMER * * This code has been tested against Magento v1.3.1 * This code may not function as intended in future versions of Magento. * If you wish to customize Magento for your needs please refer * to http://www.magentocommerce.com for more information. * **/?>
<div id="nav-home"> <ul id="cat-nav"> <?php foreach ($this->getStoreCategories() as $_category): ?> <?php echo $this->drawItemClean($_category) ?> <?php endforeach ?> </ul></div>This code will output our categories into a pre-prepared unordered list and nest subcategories within further child ul tags. You will still need to apply some CSS to match your site design however this code will provide the perfect clean base – I then customised this further with Son of Suckerfish CSS-only dropdown menus which is outside the scope of this initial article.
Finally with all of the code in place we need to add a reference to the appropriate layout XML file to ensure it is shown in the front end of the website. In our case we want the new clean menu to be shown on all pages where a left hand menu exists and so we add the code below to /design/frontend/blank/default/layout/page.xml. Again, your file location will vary depending on where you wish to display your new menu but you should add it inside your existing block for the area of the page you wish to edit.
<reference name="left"> <block type="catalog/navigation" before="-" name="catalog.custom-left" template="catalog/navigation/custom-left.phtml" /></reference>These four steps enable you to generate a modified menu function by extending an existing Magento class whilst avoiding modifying your core installation – therefore keeping your base installation easily upgradeable. The same concepts can be applied to extending any other area of Magento once you have found the correct base class to extend.
If you have any suggestions for changes/improvements to this method please feel free to add these in the comments.
Gyniolatry
January 31, 2010 at 5:41 am
Thanks Simon – Fantastic post – Explains customising perfectly
Looks like a typo in the link in step 3 description
“/design/frontend/blank/default/template/catalog/navigation/custom-home.phtml”
Should read
“/design/frontend/blank/default/template/catalog/navigation/custom-left.phtml”
Gaurav
February 18, 2010 at 12:52 pm
thanks, bro nice blog. i got better understanding from here
i have one problem in using observer.
i have to save data into customer_type table. after saving on main table. so i use observer here.
it working bt saving data twice.. y. i don’t understand.???
so if u know other way , ot best solution then please rep.
thanks
Gaurav
gast
March 1, 2010 at 12:52 am
Thanks man!
What about if I want to extend the core (I want to add a new languaje).
I create a new config.php, but I’m lost when I have to create the xml file.
Thanks!!