Magento – Linking back to specific current categories from the product view page

catalogcategorycollection;

Current Scenario

I'm trying to link back to a product's current category on the product pages themselves, something along the lines of 'View more Mira Showers from Showermania' (like the screenshot below shows).

linking back to product's current category

The problem with this is that some products are assigned to multiple categories, so initially, I'm only displaying this link on products within a specific category.

I am getting the current category like so:-

$currentCatIds = $_product->getCategoryIds();
$categoryCollection = Mage::getResourceModel('catalog/category_collection')
                    ->addAttributeToSelect('name')
                    ->addAttributeToSelect('url')
                    ->addAttributeToFilter('entity_id', $currentCatIds)
                    ->addIsActiveFilter();

And then once the collection is loaded, I can output the link using the following:-

<?php foreach ($currentCatIds as $catid) { ?>
    <?php if ($catid == 160) { ?>
        <p>View more <a href="<?php echo Mage::getModel('catalog/layer')->getCurrentCategory()->getUrl(); ?>/filter/<?php echo strtolower ($manufacturerName = $_product->getAttributeText('manufacturer')) ?>" onclick="_gaq.push(['_trackEvent', 'Internal Linkage', 'Product Back To Links', '<?php echo $manufacturerName = $_product->getAttributeText('manufacturer') ?> <?php echo Mage::getModel('catalog/layer')->getCurrentCategory()->getName(); ?>',, false]);"><?php echo $manufacturerName = $_product->getAttributeText('manufacturer') ?> <?php echo Mage::getModel('catalog/layer')->getCurrentCategory()->getName(); ?></a> from Showermania.</p>
    <?php } ?>  
<?php } ?>

This is working pretty well in the sense that if the product is in category ID 160, we'll output 'View more [manufacturer name] [category name] from Showermania'.

The Issues

The canonical URL's for product's are currently domain.com/productURL so these are the versions being indexed in search engines (this is fine though). If you visit these pages, the link doesn't get the correct category name, it gets the default root category (like the screenshot below shows).

linking back to product's current category

This means that the link back to the product's current category only displays correctly if the product page is reached via the navigation menu and via the category paths.

Due to the potential problems that arise with this scenario, perhaps Mage::getModel('catalog/layer')->getCurrentCategory() is not the best approach to this? Or maybe it could be modified further still to avoid this problem – maybe by excluding specific category ID's so it falls back to only the ones we wish to use?

Either way, I looked into different approaches…

By trying the below, I outputted all categories that a product belongs to on the product view page:-

<?php $categories = $_product->getCategoryIds(); ?>
<?php foreach($categories as $k => $_category_id): ?>
<?php $_category = Mage::getModel('catalog/category')->load($_category_id) ?> 
<a href="<?php echo $_category->getUrl() ?>"><?php echo $_category->getName() ?></a>
<?php endforeach; ?>

Great, this correctly gets each category that the product belongs to.

  • All products are assigned to the default root category.
  • Many products are in categories labelled like 'Special Offers' or 'Homepage' for display on various areas of the website.
  • All products are also assigned to the parent categories in addition to the bottom level category.

For example, this product would be in all of these categories:-

  • <a href="/catalog/category/view/s/default-category/id/2/">Default Category</a>
  • <a href="/showering">Showering</a>
  • <a href="/special-offers">Special Offers</a>
  • <a href="/showering/showers">Showers</a>
  • <a href="/homepage">Homepage</a>

We would only want to link back to the most relevant and appropriate category (from both a search engine and user perspective). In this instance, this would be the Showers category.

If this approach would be best, is the only real way to handle this to exclude countless category ID's to ensure we're only linking back to the correct 'current' category? And if so, how would this best be wrote – something like this?

<?php if ($catid == 500,501,502,503,504,505) { ?>
    <?php //do nothing ?>
<?php } else { ?>
    <?php //do this ?>
<?php } ?>

Your feedback on what we're trying to achieve here is greatly appreciated. Thanks.

Link to the product in question if this is of use to look at in context:-

Best Answer

Okay, so have actually got quite a decent solution to this now using my second approach in my question. I'm unsure of the performance implications as of yet but here is what I have done...

<?php $categories = $_product->getCategoryIds(); ?>
<?php foreach($categories as $k => $_category_id): ?>
<?php $_category = Mage::getModel('catalog/category')->load($_category_id) ?>
<?php $ignoredcats = array(2,360,124,4); ?> <!-- add all category ID's here that we wish to ignore -->
    <?php if (in_array($_category_id, $ignoredcats )){ ?>
        <?php //do nothing ?>
<?php } else { ?>
<?php if($_category->getIsActive()): ?> <!-- make sure the category is active first -->
    <p>View more <a href="<?php echo $_category->getUrl() ?>/filter/<?php echo strtolower ($manufacturerName = $_product->getAttributeText('manufacturer')) ?>" onclick="_gaq.push(['_trackEvent', 'Internal Linkage', 'Product Back To Links', '<?php echo $manufacturerName = $_product->getAttributeText('manufacturer') ?> <?php echo $_category->getName() ?>',, false]);"><?php echo $manufacturerName = $_product->getAttributeText('manufacturer') ?> <?php echo $_category->getName() ?></a> from Showermania.</p>
<?php endif; ?>

This will then output something like the following screenshot shows but by specifying the category ID's in $ignoredcats will only render for the categories of my choice.

linking back to products categories

I can then style or modify the output accordingly. You could alternatively only output this for allowed categories instead of else not allowed instead if wanted.

Does the job effectively for me currently but yet to notice any performance implications or any issues that will arise from this.

Related Topic