By February 2010, more than 30,000 online merchants were using the Magento platform. By some estimates, those merchants had managed $25 billion in transactions, making Magento one of the most popular and most used ecommerce platforms available.
Magento also offers a unique opportunity for web designers and developers who can help merchants launch or redesign Magento stores or who can develop Magento themes for resale.
About This Magento Theme Series
For the past several weeks, I have been demonstrating how to develop a Magento theme. Although, I spend a significant amount of time on things like CSS, I do so in the context of the Magento platform. My primary focus is to help you become familiar with Magento and how to maneuver through its model, view, controller (MVC) structure.
In this episode, I wrestle with cross browser compatibility issues, implementing a JavaScript fix for rounded corners in Microsoft's Internet Explorer (IE).
The Magento Theme Series, To Date
- Part One: Prolegomena
- Part Two: Page Planning, Templates, & HTML 5
- Part Three: HTML Validation and "Your" Labels
- Part Four: The CSS Work Begins
- Part Five: The Home Page CSS Continues
- Part Six: Product Navigation and CSS Rounded Corners
- Part Seven: More Rounded Corners
- Part Eight: The Boring Middle
- Part Nine: A Content Slider
- Part Ten: The Home Page Home Stretch
- Part Eleven: The Footer
- Part Twelve: The Search Form
- Part 13: Turning the Page
- Part 14: Facing the Horror
- Part 15: Style and Graphics for the Category Page Sidebar
- Part 16: Category Page Image and Font
- Part 17: The Category Page Grid
- Part 18: CSS for the Product Detail Page
- Part 19: Smooth Sliding Tabs
Rounded Corners
The theme that I am developing features rounded corners for the main product navigation. So, in the previous episode, I used CSS to create this effect. If every potential shopper used Mozilla Firefox, Google Chrome, or Apple's Safari, I'd be done. But, unfortunately, I also need to build my theme to work with IE, which does not support CSS rounded corners.
To overcome this hurdle, I am going to use a free JavaScript called CurvyCorners. CurvyCorners will look for the border-radius attribute in my CSS, locate the appropriate elements in my HTML, and, finally, when a visitor is using IE or Opera, it will create a series of tiny div elements in order to emulate the rounded corners possible in other web browsers.
CurvyCorners is offered under a GNU General Public License Version 2, which will allow me to sell my theme with CurvyCorners on board. But the author does ask that if you use CurvyCorners for a commercial purpose that you make a donation, so I would encourage you to do so.
Adding the CurvyCorners JavaScript File
To begin, I download the curvycorners.js file and place it in the JavaScript library folder in my theme's file hierarchy. That folder is located at js > lib.
Calling CurvyCorners
Next, I need to reference the curvycorners.js file in the <head> section of the theme HTML. In Magento, all of the required JavaScript files are inserted into the <head> using PHP and an XML layout file, so adding a file is a snap. Simply navigate to page.xml, which is located at app > design > frontend > default > pine > layout. Remember, Pine is the name of my theme; you need to use your theme name in the path and locate the list of included JavaScript and CSS files. It should look like this:
<block type="page/html_head" name="head" as="head">
<action method="addJs"><script>prototype/prototype.js</script></action>
<action method="addJs" ifconfig="dev/js/deprecation"><script>prototype/deprecation.js</script></action>
<action method="addJs"><script>prototype/validation.js</script></action>
<action method="addJs"><script>scriptaculous/builder.js</script></action>
<action method="addJs"><script>scriptaculous/effects.js</script></action>
<action method="addJs"><script>scriptaculous/dragdrop.js</script></action>
<action method="addJs"><script>scriptaculous/controls.js</script></action>
<action method="addJs"><script>scriptaculous/slider.js</script></action>
<action method="addJs"><script>varien/js.js</script></action>
<action method="addJs"><script>varien/form.js</script></action>
<action method="addJs"><script>varien/menu.js</script></action>
<action method="addJs"><script>mage/translate.js</script></action>
<action method="addJs"><script>mage/cookies.js</script></action>
<action method="addCss"><stylesheet>css/reset.css</stylesheet></action>
<action method="addCss"><stylesheet>css/boxes.css</stylesheet></action>
<action method="addCss"><stylesheet>css/menu.css</stylesheet></action>
<action method="addCss"><stylesheet>css/clears.css</stylesheet></action>
I locate the transition between JavaScript and CSS files, and insert a new line.
<action method="addJs"><script>lib/curvycorners.js</script></action>
That's it. The active tab in the product navigation has rounded corners in IE.
But What About When I Hover
Unfortunately, I am not done. If I hover over the next link in line, I still get a square tab, instead of one with rounded corners. That is because the class that describes the background color and those rounded corners were dynamically created after curvycorners.js had already run.
Solving this problem proved harder than I would have expected. I tried several methods, most of which were too "messy" for my web design and development tastes. What I came up with is not perfect, so if you have suggestions, please leave them in the comments.
My solution amounts to this. I am going to create an additional element (specifically, a span) and position it directly behind the navigation link, and let CurvyCorners make it round. Next, I will set its CSS display attribute to none so that it doesn't show up on the page. And finally, I will use some JavaScript to toggle its display attribute when someone hovers over it.
Adding the New Element
There are a number of ways to add this element. I decided to place it using PHP, so I need to open Navigation.php, which can be found at app > code > core > Mage > Catalog > Block.
This file contains the PHP loop that creates a link and list item for each product category designated in the admin. (Remember, the navigation is organized as an unordered list with several subordinate list items). I want to append my new element to the end of each list item. To do this, I need to locate the point in the loop that closes the <li> tag. In my Navigation.php file this happens at about line 186. The code I want to find looks like this.
$html.= '<a href="'.$this->getCategoryUrl($category).'"><span>'.$this->htmlEscape($category->getName()).'</span></a>'."\n";
Just after this line of code, I am going to insert the following.
//For Rounded Corners
if ($hasChildren || ($level < 1) ) {
$html.= ' <span id="bling" style="display:none;"></span>';
}
//end For Rounded Corners
This simple bit of PHP will add a span with an id and class of "bling" just after each of the top-level list items.
IE Specific Style
Next, I want to declare some styles for this "bling," but I only want these styles to be used when IE is the browser. In Magento there is already an IE specific stylesheet, iestyles.css, which is located at skin > frontend > default > pine > css.
To this file, I am going to add the following styles.
#nav {position: relative; z-index: 1; }
#nav li.over {background: transparent; border: 1px solid transparent; }
ul.level0 {z-index: 2;}
.bling {position: absolute; z-index: -1; top: 0; left:0; height: 100%; width: 100%; -webkit-border-top-left-radius: 20px; -webkit-border-top-right-radius: 20px; /* Safari */ background:#372016;}
As you can see, I am using relative positioning in #nav and absolute positioning in .bling so that I can stack these on top of each other. The border-radius attributes are not read by IE's Trident engine, but they are what CurvyCorners uses to identify which elements to process.
Add the Effect with JavaScript
Now I simply need to add some JavaScript so change the display attribute of my new span. I am going to create a copy of ie-hover.js from js > varien. I will rename this copy to iecorners.js and save it into the lib folder at js > lib.
I am going to take advantage of the fact that Magento uses the Prototype JavaScript Library, so that I only need to add two lines of code.
$('bling').show();
And . . .
$('bling').hide();
So the this file now reads:
function toggleMenu(el, over)
{
if (Element.childElements(el)) {
var uL = Element.childElements(el)[1];
var iS = true;
}
if (over) {
Element.addClassName(el, 'over');
if(iS){ uL.addClassName('shown-sub')};
//var liWide = $$('over').getWidth;
//Element.insert(el, '<span id="bling">INSERTED</span>');
//$('bling').style.width = liWide;
$('bling').show();
}
else {
Element.removeClassName(el, 'over');
if(iS){ uL.removeClassName('shown-sub')};
//$('bling').remove();
$('bling').hide();
}
}
Next, I need to include this new JavaScript file in the <head>, so I open page.xml, which is the same file I opened when I added curvycorners.js.
To page.xml, I am going to add the following line, which will include my new JavaScript.
<action method="addItem"><type>js</type><name>lib/iecorners.js</name><params/><if>IE</if></action>
Summing Up
This one was a bit of a challenge, and I am still not quite done with this category navigation. With luck, I’ll finish this section in the next episode.
