Advertisement

Magento for Designers: Part 6

by
This post is part of a series called Magento for Designers.
Magento for Designers: Part 5
Magento for Designers: Multi-Store Functionality

Magento is a stunningly powerful e-commerce platform. In this miniseries, we'll learn how to get started with the platform, get to know the terminologies, set up a store and all related aspects of it and finally learn how to customize it to make it our very own.

In this sixth part, we'll be building one of the most reader requested feature: getting a featured product slider in the home page. Excited? Let's get started!

The Full Series


A Quick Recap

In the last part, we built the product information page and took a good look at how data is extracted and displayed in a typical Magento theme.

We also took a look at the various core methods that our theme uses to get various media and data about our product. I hope you remember at least a sliver of that information because we'll be using it again today.


What are We Building Today?

Today, we'll build the all important home page. As always, I'll keep it as simple as possible and omit any extraneous features. Different stores have different content in their home pages. One of the most popular and definitely one of the most requested features is displaying a JavaScript powered content slider featuring special featured products. I know it sounds interesting and you're itching to get started. Let's get started!


Goals for the Page

As with our other pages, our goals for this specific page are relatively simple. We want a simple slider that displays specific products in a neat slider. Thus, I've drawn up a short list of elements that I think it needs:

  • JavaScript slider on the home page
  • Slider needs a catchy image on the left to attract attention to the product
  • In the right portion, we'll be including the product's name, price and a short description
  • A mini navigation within the slider to switch between different slides
  • And most important of all, not rely on an extension to obtain the featured items

That's it. I want to keep it as simple as possible and thus opted to not over do it. We will of course need to work with both the front end and back end to accomplish all our goals.


The Basic Look

The page basically has to look like so:


Step 1 - The HTML

We'll first look at the HTML for the content part alone. I'm assuming you're fairly fluent in HTML and CSS so I'll skip to the fairly important parts.

<div id="home-slideshow">

    <div class="slide">

        <div class="product-image">
            <a href="#" title="Zonda F">
                <img src="images/zonda.jpg" alt="Zonda F" title="Zonda F" />
            </a>
        </div>

        <div class="product-details">
            <h2>Zonda F</h2>
            <div class="price">700,000.00 </div>
            <p>The Pagani Zonda is a mid-engined sports car produced by Pagani in Italy. </p>
        </div>

    </div>

<!-- More slides for successive products -->

</div>

At this point, this is all pretty basic. home-slideshow is the container we're wrapping the entire slideshow with and will be passed on to the JavaScript responsible for the slider.

Each slide is wrapped by a div called slide. Inside we have two floated containers: one for the image and the second for the information about the product itself.

That's about all there is to it. We can move on to the styling part now.


Step 2 - The CSS

/* Home page */

.slide {
    clear: both;
    overflow: auto;
    padding: 10px;
    width: 898px;
    border: 1px solid #E1E1E1;
    background: #F6F6F6;
}

.product-image {
    float: left;
    width: 650px;
    padding: 10px;
    border: 1px solid #E1E1E1;
    background: #FAFAFA;
	
}

.product-details {
    float: left;
    width: 190px;
    margin: 0 0 0 20px;
}

.product-details .price {
    margin: -15px 0 0 0;
    color : #7db000;
}

.product-details p{
    margin: 10px 0 0 0;
}

#nav {
    position: absolute;
    top: 255px;
    right: 250px;
    z-index: 2000;
}

#nav a { 
    margin-right: 10px; 
    height: 5px;
    width: 5px; 
    z-index: 1000;
    float: left;
    text-indent: -9999px;
    cursor: pointer;
    border: 1px solid #fff;
    background:  #eee;
}

#nav a:hover { 
    border: 1px solid #fff;
    background:  #999;
}

#nav a.activeSlide { 
    border: 1px solid #444;
    background:  #333;
}

Nothing fancy here. Very basic CSS to place the elements in position.

The only point to note is the declaration for the class activeSlide. This class is assigned to the current slide's respective navigation anchor.


Step 3 - Setting up Our Store

The first thing we need to do is setup a separate category to which we can assign all the products that we need to appear on our slider. Click on the catalog menu and then on categories. Choose add new root category.

Magento for Designer: Part VI

Key in a name of your choice and then choose no for the is active dropdown. We don't want it displaying in other parts of the site.

Magento for Designer: Part VI

Once the new category has been saved, you can find the ID it has been assigned to. Note this down. We'll need it for later.


Step 4 - Creating Our Core Code

We'll be using a single template file to pull out the relevant information, format it as needed and display everything. You have complete freedom regarding the name and location of this file but in the interest of keeping it simple, I've named it featured.phtml and placed it in catalog/product/featured.phtml. Remember, this goes into your template folder, not your layout folder.

The contents of the file looks like so. Don't worry about the length, we'll look at each part works after the code.

<?php 
$cat_id = "2"; 
$_productCollection = Mage::getResourceModel('catalog/product_collection')
->addAttributeToSelect(array('name', 'price', 'small_image', 'short_description'), 'inner')
->addCategoryFilter(Mage::getModel('catalog/category')->load($cat_id));

if(!$_productCollection->count()): 
    echo $this->__('There are no products matching the selection.'); 
else: ?>

    <div id="home-slideshow">
        <?php $i=0; foreach ($_productCollection as $_product): ?>

        <div class="slide">

            <div class="product-image">
                <a href="<?php echo $_product->getProductUrl() ?>" title="<?php echo $this->htmlEscape($this->getImageLabel($_product, 'small_image')) ?>">
                <img src="<?php echo $this->helper('catalog/image')->init($_product, 'small_image')->resize(650, 250); ?>" alt="<?php echo $this->htmlEscape($this->getImageLabel($_product, 'small_image')) ?>" title="<?php echo $this->htmlEscape($this->getImageLabel($_product, 'small_image')) ?>" /></a>
            </div>

            <div class="product-details">
                <h2><?php echo $_product->getName(); ?></h2>
                <div class="price"><?php echo number_format($_product->getFinalPrice(),2);?> </div>
                <p><?php echo $_product->getShortDescription(); ?></p>
            </div>

        </div>
        <?php endforeach ?>

    </div>

<?php endif; ?>

Here's the first piece:

$cat_id = "2";

First, we'll need to specify the ID of the category from which we want to pull in our products. In our case, this will be 2, the ID of the category we just created.

$_productCollection = Mage::getResourceModel('catalog/product_collection')
->addAttributeToSelect(array('name', 'price', 'small_image', 'short_description'), 'inner')
->addCategoryFilter(Mage::getModel('catalog/category')->load($cat_id));

This looks slightly complicated but let me assure you, it's very simple. To put it in layman's terms, we essentially pass in the ID of the category we need through the variable cat_id and ask Magento to retrieve the name, price, image and short description of the products that match. Right now, I'd advise you to not fiddle with the rest unless you're well versed in MVC and other aspects of Magento's architecture.

if(!$_productCollection->count()): 
echo $this->__('Sorry, no items matched your selection criteria'); 
else: ?>

We will need to check whether we have matching items, don't we? That's what we're doing here. Just making sure we have matching items. If not, we display an error.

<?php $i=0; foreach ($_productCollection as $_product): ?>

Let's start looping through our product collection!

<a href="<?php echo $_product->getProductUrl() ?>" title="<?php echo $this->htmlEscape($this->getImageLabel($_product, 'small_image')) ?>">
<img src="<?php echo $this->helper('catalog/image')->init($_product, 'small_image')->resize(650, 250); ?>" alt="<?php echo $this->htmlEscape($this->getImageLabel($_product, 'small_image')) ?>" title="<?php echo $this->htmlEscape($this->getImageLabel($_product, 'small_image')) ?>" /></a>
<h2><?php echo $_product->getName(); ?></h2>
<div class="price"><?php echo number_format($_product->getFinalPrice(),2);?> </div>
<p><?php echo $_product->getShortDescription(); ?></p>

If you've read the previous part of this series, this code must be pretty familiar to you. We use Magento's baked in methods to retrieve media pertaining to our product.

The second snippet may look a little different because instead of using slightly more abstracted methods, I used closer-to-bone methods to directly acquire the data we need.

If you're feeling a little confused here, just go through the above code one more. The name of the methods are pretty explanatory. The only stumbling block should be how we acquire the image itself: we ask one of our helpers to acquire the image and resize it to the size we need. Nothing more to it.

Note that we open and close a slide div each time our loop runs. This is to encapsulate each product's information with a container element to make it easy for us to create a slider later.

And with this, our base PHP code is complete.


Step 5 - The JavaScript

It makes no sense to completely reinvent the wheel here since the core focus of this series is on Magento. Thus, we'll be using an excellent plugin to create our slider today: the jQuery Cycle plugin.

But first, go to root/js and create a folder named cirrus. Different people have different methods of organizing here. I prefer having a theme's JS separate instead of organizing them by source. We'll need a copy of jQuery [1.4 hopefully], the latest cycle plugin and a custom script file, which I'm naming mocha.

Here's the content of our JS file.

(function($) { 

$(document).ready(function(){
     $('#home-slideshow')
	 	.before('<div id="nav">')
		.cycle({
		fx: 'fade',
		speed:    1500, 
 		timeout:  5000,
 		pause: 1,
 		delay:  5000, 
		pager: '#nav'
	});
});
 })(jQuery)

First up, notice that we're wrapping everything inside a (function($) { //Code })(jQuery) block. This is make sure jQuery doesn't conflict with any other included library.

The document ready block, as always, is to make sure that our code runs only after all the page's assets are loaded since Magento likes to put our JavaScript files at the top.

Initializing the plugin is pretty simple. Just type in the ID of the main container, home-slideshow in our case, and away we go. I've just tweaked some of the options to make it do our bidding.

Something to take note of is that we're dynamically creating and positioning our container for the navigation elements inside the DOM with JavaScriptS. This element is only needed if JavaScript is enabled. If it isn't, we don't want empty, useless code in our page.

We also pass in the selector the navigation container to the slider plugin.

That's it. The JavaScript part of our code is done.


Step 6 - Setting up Our Home Page

Now that all our groundwork has been completed, we can finally configure our home page now.

Magento for Designer: Part VI

Click on the CMS menu and choose the pages option. Click on home page in the resulting page.

Magento for Designer: Part VI

The first tab should be pretty self explanatory. Make sure that our page is enabled.

Magento for Designer: Part VI

In the content tab, make sure you enter the following after disabling the editor:

{{block type="catalog/product_list" block_id="featured.products"  template="catalog/product/featured.phtml"}}

This is Magento's method of including required blocks. We just give it an ID to refer it by and point it to our custom template.

Magento for Designer: Part VI

In the design tab, change the layout template to 1 column since we're using it for everything and then enter the following into the layout update xml field.

<reference name="head">
          <action method="addCss"><stylesheet>css/home.css</stylesheet></action>
          <action method="addJs"><script>cirrus/jquery-1.4-min.js</script></action>
          <action method="addJs"><script>cirrus/cycle.js</script></action>
          <action method="addJs"><script>cirrus/mocha.js</script></action>
</reference>

Remember how when building the product page, we included custom CSS in the page's layout file to make sure the entire codebase isn't loaded for every page? We're doing essentially the same here. Instead of creating a XML file just for this, Magento lets us enter this directly through the interface.

We just load our custom CSS, our JS libraries and the script file that contains all our code.

Click on "save" to save up all our progress, empty Magento's cache and watch the beautiful slider on your home page slide through in its excruciatingly lovely glory!


What We'll be Building in the Next Part

.. is completely up to you. I've already covered almost all relevant information for customizing any view and going through each and every view is completely counter-intuitive. Thus, I've concluded that all that's left is how to create a custom module and I think by then this series will have runs its course. I may write a quick Magento tweaks and optimization how-to if enough people show interest for such an article.

If you do feel that something else needs to be covered before this series comes to a close, don't hesitate to leave a comment below to let me know!


The Last Word

And we are done! Today, we learnt how to create a custom home page complete with a slider displaying featured products. We also learnt to do all this without relying on a third party extension and instead coding all this ourselves. Hopefully this has been useful to you and you found it interesting. Since this is a rather new topic for a lot of readers I'll be closely watching the comments section so chime in there if you're having any doubts.

Questions? Nice things to say? Criticisms? Hit the comments section and leave me a note. Happy coding!