Auto Populate Cross Sell with Products from Current Category Magento

Posted April 16th, 2011 in Public and tagged , , , by Nick Cron

eCommerce Data is clear – you need to have cross sell items for every product in your catalog to help conversion.  The usual process consists of manually associating items in the Magento Admin interface.  This process works fine if you have hundreds or even a few thousand items – OR – you have this data in back end systems.

What happens if you don’t have the data and you have 15,000+ items in your catalog?

  • Hire someone to associate all products?
  • Randomly apply products in your data feed?
  • Develop custom code?

All of the above items are true for my Medical Supplies business – Medical Delivered so I needed a solution.  I decided to auto assign cross sell products on the front end on product page render.

In action: http://www.medicaldelivered.com/medline-k1-excel-wheelchair.html

Rules:

  1. The item must be “visible”
  2. The item must reside in the same category as the current item
  3. Don’t display the item from the current product detail page

Results:

  1. All products automatically have cross sells displayed
  2. No need to assign products on the back end
  3. BAD:  Less control over items displayed

This solution won’t work for everyone, if you are an advanced retailer you won’t want to lose this control but if you just want cross sells and don’t have the time/resources to define manually you can try the code below.

Path:  app/design/frontend/default/<template>/catalog/product/list/upsell.phtml

(you may need to create this path – make sure to replace <template> with your template name)


<?php
/**
* Magento
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License (AFL 3.0)
* that is bundled with this package in the file LICENSE_AFL.txt.
* It is also available through the world-wide-web at this URL:
* http://opensource.org/licenses/afl-3.0.php
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@magentocommerce.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade Magento to newer
* versions in the future. If you wish to customize Magento for your
* needs please refer to http://www.magentocommerce.com for more information.
*
* @category   design_default
* @package    Mage
* @copyright  Copyright (c) 2008 Irubin Consulting Inc. DBA Varien (http://www.varien.com)
* @license    http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
* @author        Nick Cron
* @authorweb  www.njcmedia.com
*/
?>
<?php
$_related = $this->getProduct();
// get the parent id to skip
$_parentid = $_related->getId();

if ($_related) {
// get collection of categories this product is associated with
$categories =$_related->getCategoryCollection()
->setPage(1, 1)
->load();

// if the product is associated with any category
if ($categories->count())
foreach ($categories as $_category)
{
$cur_category = Mage::getModel('catalog/category')->load($_category->getId());

?>

<div>
<div><h4><?php echo $this->__('You may also be interested in the following product(s)') ?></h4></div>
<table cellspacing="0" id="upsell-product-table">

<tr>

<?php

$visibility = array(
Mage_Catalog_Model_Product_Visibility::VISIBILITY_BOTH,
Mage_Catalog_Model_Product_Visibility::VISIBILITY_IN_CATALOG
);

$products = Mage::getResourceModel('catalog/product_collection')
->addCategoryFilter($_category)
->addAttributeToFilter('visibility', $visibility)
->addAttributeToSelect('small_image');

$products->getSelect()->limit(5);

// count the number of displayed products
$_i=0;

foreach ( $products as $productModel )       {
$_related = Mage::getModel('catalog/product')->load($productModel->getId());
$_realtedid = $_related->getId();

// prevents displaying the same product your are already on
if ($_realtedid != $_parentid && $_i<4):

?>

<td>
<p><a href="<?php echo $_related->getProductUrl() ?>"><img src="<?php echo $this->helper('catalog/image')->init($_related, 'small_image')->resize(125) ?>" width="125" height="125" alt="<?php echo $this->htmlEscape($_related->getName()) ?>" /></a></p>
<h5><a href="<?php echo $_related->getProductUrl() ?>"><?php echo $this->htmlEscape($_related->getName()) ?></a></h5>

<?php echo $this->getPriceHtml($_related, true) ?>
<?php echo $this->getReviewsSummaryHtml($_related) ?>
</td>

<?php
// increment displayed products
$_i++;
endif;
}
?>

</tr>

<?php }
}
?>
</table>
<script type="text/javascript">decorateTable('upsell-product-table')</script>
</div>

Room for improvement:

  1. Display items from the back end if exist
  2. Display only items with images
  3. ..?

I hope this helps someone.  If you have any suggestions for improvement or code upgrades/fixes please let me know in the comments.

Share this Post

  • Lniculescu

    Based on color attribute would be nice. (or eny attribute)

  • Franck

    Excellent !!! Thanks a lot. I don’t understand why nobody already sells an extension like that !

  • Lex

    G E N I A L

    Thanks for sharing

  • Mark

    Dear Nick,

    Can you help me with something?

  • Mark

    This code works for me, but I want to keep the look & feel of my template… How can I do that? Now the images are to small and don’t light up when mouse-over… Hope somebody can help, because my site goes live tomorrow!

    upsell.phtml – em0023 template:

    ?>
    get_upsell_width();
    $h = $image->get_upsell_height();
    $bg = $image->get_upsell_bgcolor(); 
    ?>
    getItemCollection()->getItems())): ?>

        __(‘You may also be interested in the following product(s)’) ?>
       
        setColumnCount(5); // uncomment this line if you want to have another number of columns. also can be changed in layout ?>
        resetItemsIterator() ?>
        <?php for($_i=0;$_igetRowCount();$_i++): ?>
           
            <?php for($_j=0;$_jgetColumnCount();$_j++): ?>
                getIterableItem()): ?>
               
                    <a href="getProductUrl() ?>” title=”htmlEscape($_link->getName()) ?>” class=”product-image”><img style="background-color:” src=”helper(‘catalog/image’)->init($_link, ‘small_image’)->resize($w,$h) ?>” width=”" height=”" alt=”htmlEscape($_link->getName()) ?>” />
                    <a href="getProductUrl() ?>” title=”htmlEscape($_link->getName()) ?>”>htmlEscape($_link->getName()) ?>
                    getPriceHtml($_link, true, ‘-upsell’) ?>
                    getReviewsSummaryHtml($_link) ?>
               
               
           
           
       
       
        decorateTable(‘upsell-product-table’)

  • Nick Cron

    Mark – This is likely a CSS issue. If you send me a link I can take a quick look and see what I can come up with.

  • leozzz

    Products in different category come out! Strange part is , their url has http://xxxxxx/categoryid where the id is the same category of the currently viewing page but the belongs to that related product!

  • leozzz

    Sorry for typo:
    Products in different category come out! Strange part is , their url has
    http://xxxxxx/categoryid where the id is the same category of the
    currently viewing page but “NOT” belongs to that related product!

  • leozzz

    i finally got the bug and solution. That is because my categories has 3-4 levels, by the code you provide, the related product share the most common 1st level category.
    For me, the related product is meant by sharing the same brand, that is the 3rd level category, so i add the “level” filter with value 3

    // get collection of categories this product is associated with
    $categories =$_related->getCategoryCollection()->addFieldToFilter(‘level’,’3′)  ->setPage(1, 1)->load();

  • Mendel Kramer

    Is there any way to do this with “crossselling” as opposed to “upselling” ?? Thanks

  • Nick Cron

    Mendel – this code does not really upsell or cross sell. It just pulls random products from the same category. If you want to set up specific cross or up sells you can do this in the Magento admin.

  • Anonymous

    It looks like the last items are displayed first. is it possible to change the sort order so that the first item of a category is also the first that is displayed? thank you!

blog comments powered by Disqus