Magento extension: rcah 0.2.0 is released

In previous version of rcah module, if “Use Canonical Link Meta Tag For Categories” is enabled in System >> Configuration >> Catalog >> Search Engine Optimizations,

and if you set a root category as homepage, the homepage html head outputs a link like

<link rel=”canonical” href=”http://MY_DOMAIN/catalog/category/view/s/URL_KEY/id/ROOT_CATEGORY_ID/” />

or if you set a subcategory as homepage (System -> Configuration -> General -> Web -> Default Pages -> Default web URL set to “rcah/index/index/id/SUBCATEGORY_ID”), the homepage html head outputs a link like

<link rel=”canonical” href=”http://MY_DOMAIN/REWRITED_URL” />

In the first scenario, the canonical link is invalid because Magento native code won’t allow root category page be accessed. In the second scenario, the canonical link is valid, but it should be “http://MY_DOMAIN/” in either scenario.

Release 0.2.0 is to fix this problem. Download RootCategoryAsHomepage.tar.gz

Just for your interest, I was going to write IndexController like this to fix the problem.

/**
* most code is from CategoryController::viewAction()
*
* run _modifyCanonial() before render layout
*/
public function indexAction()
{
if ($category = $this->_initCatagory()) {

Mage::getModel('catalog/design')->applyDesign($category, Mage_Catalog_Model_Design::APPLY_FOR_CATEGORY);
Mage::getSingleton('catalog/session')->setLastViewedCategoryId($category->getId());

$update = $this->getLayout()->getUpdate();
$update->addHandle('default');

if (!$category->hasChildren()) {
$update->addHandle('catalog_category_layered_nochildren');
}

$this->addActionLayoutHandles();

$update->addHandle($category->getLayoutUpdateHandle());
$update->addHandle('CATEGORY_'.$category->getId());



if ($category->getPageLayout()) {
$this->getLayout()->helper('page/layout')
->applyHandle($category->getPageLayout());
}

$this->loadLayoutUpdates();

$update->addUpdate($category->getCustomLayoutUpdate());

$this->generateLayoutXml()->generateLayoutBlocks();

if ($category->getPageLayout()) {
$this->getLayout()->helper('page/layout')
->applyTemplate($category->getPageLayout());
}

if ($root = $this->getLayout()->getBlock('root')) {
$root->addBodyClass('categorypath-'.$category->getUrlPath())
->addBodyClass('category-'.$category->getUrlKey());
}

$this->_initLayoutMessages('catalog/session');
$this->_initLayoutMessages('checkout/session');
$this->_modifyCanonial()->renderLayout();
}
elseif (!$this->getResponse()->isRedirect()) {
$this->_forward('noRoute');
}
}

/***
* Find link_rel item in items of head, and modify it
*
* Each item is array of 5 in a format like
* array('type'=>'link_rel',
*         'name'=>'http://domain/path',
*         'params'=>'rel="canonical"',
*         'if'=>null,
*         'cond'=>null);
*/
protected function _modifyCanonial() {
if ($headBlock = $this->getLayout()->getBlock('head')) {
$items = $headBlock->getData('items');
foreach ($items as $key => $value) {
if (false !== strpos($key, 'link_rel')) {
if ($value['type'] == 'link_rel' && $value['params'] == 'rel="canonical"') {
$value['name'] = Mage::getUrl();
$items[$key] = $value;
$headBlock->setData('items', $items);
break;
}

}
}
}
return $this;
}

However, just before release, I found a much better way: just use setCategoryUrl in _initCatagory(). So now IndexController is now as:

protected function _initCatagory()
{
Mage::dispatchEvent('catalog_controller_category_init_before', array('controller_action'=>$this));
$rootCategoryId = Mage::app()->getStore()->getRootCategoryId();
$categoryId = (int) $this->getRequest()->getParam('id', $rootCategoryId);
if (!$categoryId) {
return false;
}

$category = Mage::getModel('catalog/category')
->setStoreId(Mage::app()->getStore()->getId())
->load($categoryId)
//force url as a homepage url to work with canonical link
->setUrl(Mage::getUrl());

if ($categoryId == $rootCategoryId) {
//do nothing. bypass canshow test for root category
}
elseif (!Mage::helper('catalog/category')->canShow($category)) {
return false;
}
Mage::getSingleton('catalog/session')->setLastVisitedCategoryId($category->getId());
Mage::register('current_category', $category);
try {
Mage::dispatchEvent('catalog_controller_category_init_after', array('category'=>$category, 'controller_action'=>$this));
} catch (Mage_Core_Exception $e) {
Mage::logException($e);
return false;
}
return $category;
}

public function indexAction() {
parent::viewAction();
}

Leave a Reply

Your email address will not be published. Required fields are marked *