I have defined breadcrumbs like this on catalog/category/view.phtml page.
echo $this->getChildHtml('breadcrumbs')
I want to show breadcrumbs on category page only. Do I need to add anything else to use above code ?
Do I need to define this in xml file as well ?
Breadcumbs is a structural block in Magento. That means it is a part of Magento structure. So if you need to reposition the breadcumb's position, you really need to alter the magento layout structure definition. Breadcump is defined in page.xml
Location: app/design/frontend/base/default/layout/page.xml
<default>
....
<!-- bradcumb block definition -->
<block type="page/html_breadcrumbs" name="breadcrumbs" as="breadcrumbs"/>
....
</default>
Obviously this block is called using getchildHtml()
method in the page layout templates. These templates are present in the location app/design/frontend/base/default/tempate/page/
. Take a look on those files. Here I include the code inside 1column.phtml template
<div class="main">
<?php echo $this->getChildHtml('breadcrumbs') ?>
<div class="col-main">
<?php echo $this->getChildHtml('global_messages') ?>
<?php echo $this->getChildHtml('content') ?>
</div>
</div>
Your code will not going to work. Because you used getChildHtml()
method to include the breadcumb block. If you want that code work, then breadcumb block should be a child block of block that defines categor/view.phtml
. The block that define this template is Mage_Catalog_Block_Category_View
. In layout file this block is referenced with a name category.products
. You can see this block in catalog.xml
breadcrumps
firstYou don't need breadcrumbs in every page and you want to change the position where it now seems. For this you should have to remove the breadcrumb block from default layout. This will remove the breadcrumb block from every page. The best way to do this is shown below
create a layout file at app/design/<package>/<theme>/layout/local.xml
and put this code inside
<layout>
<default>
<reference name="content">
<remove name="breadcrumbs" />
</reference>
</default>
</layout>
Local.xml
file is processes at last after every other layout files are processed. So this is the perfect place to remove breadcrumps block. Now clear the cache and load the page. You will see breadcrump get dissappeard from every pages.
breadcrumps
in catalog page onlyNow you need to put breadcrumb block in category pages only. As I already mentioned, what you need to do is, make the bredcrumbs block child for catalog/category_view
block. But here is anothe problem. Generally there are two types of category pages . Category page with layered navigation and category page without layered navigation. Magento has seperate layout structure for both these types. So you need to specify breadcrumbs block for both of these category types.
Location: app/design/<package>/<theme>/layout/catalog.xml
<catalog_category_default>
....
<reference name="content">
<block type="catalog/category_view" name="category.products" template="catalog/category/view.phtml">
<block type="page/html_breadcrumbs" name="breadcrumbss" as="breadcrumbss"/>
...
</block>
...
</reference>
....
</catalog_category_default>
<catalog_category_layered>
....
<reference name="content">
<block type="catalog/category_view" name="category.products" template="catalog/category/view.phtml">
<block type="page/html_breadcrumbs" name="breadcrumbss" as="breadcrumbss"/>
...
</block>
...
</reference>
....
</catalog_category_layered>
Work is not over. Now you need to call this breadcrumbs block in template file also
File : app/design/<package>/<theme>/template/catalog/category/view.phtml
<?php echo $this->getChildHtml('breadcrumbss'); ?>
Call this wherever you needed inside view.phtml
. You are done. Now clear cache and load the page again.
OOOPSSSS!!!!!
Not showing anything right ?
But our block is there definitely. In order to confirm it, open the breadcrumbs template file and put any text inside it. Now load the page again. You will see the content for sure. So what happend previous time. Let us look.
Breadcrumbs blocks are special block in which we need to set some data before it get rendered. Otherwise it will provide an empty result. The method used to set breadcrumbs block is addCrumb()
. Take a look on breadcrumb block Mage_Page_Block_Html_Breadcrumbs
. We need to look _toHtml() method, this is what coverts this block into html.
protected function _toHtml()
{
if (is_array($this->_crumbs)) {
reset($this->_crumbs);
$this->_crumbs[key($this->_crumbs)]['first'] = true;
end($this->_crumbs);
$this->_crumbs[key($this->_crumbs)]['last'] = true;
}
$this->assign('crumbs', $this->_crumbs);
return parent::_toHtml();
}
So it is essential that $this->_crumbs
to be set before invoking this method. Otherwise it will pass an empty array to the breadcrumbs template. This will output nothing in frontend. This is what happens now. That means there is some how the way magento set $this->_crumbs
variable changed along with changes that we maded now. So we need to find where the default flow broken now.
Magento sets $this->_crumbs
variable using a function addCrumb()
which is defined in breadcrumbs block itself. Let us have a look on that method.
public function addCrumb($crumbName, $crumbInfo, $after = false)
{
$this->_prepareArray($crumbInfo, array('label', 'title', 'link', 'first', 'last', 'readonly'));
if ((!isset($this->_crumbs[$crumbName])) || (!$this->_crumbs[$crumbName]['readonly'])) {
$this->_crumbs[$crumbName] = $crumbInfo;
}
return $this;
}
As you can see, this is the method that is responsible for making breadcrumb block active. You can see that $this->_crumbs
variable is setting inside this method.
For category page, breadcrumb setting process starts in caetgory view block. Let us have a look on category view block. That is
`Mage_Catalog_Block_Category_View::_prepareLayout()`
protected function _prepareLayout()
{
parent::_prepareLayout();
$this->getLayout()->createBlock('catalog/breadcrumbs');
....
}
Here as you can see it creates new breadcrumb block Mage_Catalog_Block_Breadcrumbs
during layout preparation. So we need to find what this block does.
#Mage_Catalog_Block_Breadcrumbs::_preapareLayout()
protected function _prepareLayout()
{
if ($breadcrumbsBlock = $this->getLayout()->getBlock('breadcrumbs')) {
$breadcrumbsBlock->addCrumb('home', array(
'label'=>Mage::helper('catalog')->__('Home'),
'title'=>Mage::helper('catalog')->__('Go to Home Page'),
'link'=>Mage::getBaseUrl()
));
$title = array();
$path = Mage::helper('catalog')->getBreadcrumbPath();
foreach ($path as $name => $breadcrumb) {
$breadcrumbsBlock->addCrumb($name, $breadcrumb);
$title[] = $breadcrumb['label'];
}
if ($headBlock = $this->getLayout()->getBlock('head')) {
$headBlock->setTitle(join($this->getTitleSeparator(), array_reverse($title)));
}
}
return parent::_prepareLayout();
}
Yes there it is. Breadcrumbs for category block is setting by this block. Now why it didn't work for us now. This is the most trickiest area that we need to understand.
The thing is this. We have our breadcrumbs block is defined inside catalog categoy view page
. As you can see this block looking for breadcrumb
block in its layout. Unfortunately the block will not be availble now, since that block is actually defines inside category view block. At this stage blocks that are defined above category view block only available here. When breadcrumbs block were insdie page.xml file, this block will be available here. So the method will work perfectly.
Now how can we get outside of this? In my mind, there are two ways to do this
1. Use observer method
2. Change the definition of breadcrumbs block.
I would like to go with second method. Since it would be the best method that we have available now. Here what we need to do is, we need to replicate the functions that does by Mage_Catalog_Block_Breadcrumbs
block. After applying changes accordingly, your breadcrumbs page now look like
<?php
/**
* Html page block
*
* @category Mage
* @package Mage_Page
* @author Magento Core Team <[email protected]>
*/
class Rkt_CategoryBreadcrumbs_Block_Page_Html_Breadcrumbs extends Mage_Core_Block_Template
{
/**
* Array of breadcrumbs
*
* array(
* [$index] => array(
* ['label']
* ['title']
* ['link']
* ['first']
* ['last']
* )
* )
*
* @var array
*/
protected $_crumbs = null;
/**
* Cache key info
*
* @var null|array
*/
protected $_cacheKeyInfo = null;
protected $_title = null;
public function __construct()
{
parent::__construct();
$this->setTemplate('page/html/breadcrumbs.phtml');
$this->addCrumb('home', array(
'label'=>Mage::helper('catalog')->__('Home'),
'title'=>Mage::helper('catalog')->__('Go to Home Page'),
'link'=>Mage::getBaseUrl()
));
$this->_title = array();
$path = Mage::helper('catalog')->getBreadcrumbPath();
foreach ($path as $name => $breadcrumb) {
$this->addCrumb($name, $breadcrumb);
$this->_title[] = $breadcrumb['label'];
}
}
protected function _prepareLayout(){
if ($headBlock = $this->getLayout()->getBlock('head')) {
$headBlock->setTitle(join($this->getTitleSeparator(), array_reverse($this->_title)));
}
return parent::_prepareLayout();
}
public function addCrumb($crumbName, $crumbInfo, $after = false)
{
$this->_prepareArray($crumbInfo, array('label', 'title', 'link', 'first', 'last', 'readonly'));
if ((!isset($this->_crumbs[$crumbName])) || (!$this->_crumbs[$crumbName]['readonly'])) {
$this->_crumbs[$crumbName] = $crumbInfo;
}
return $this;
}
/**
* Get cache key informative items
*
* @return array
*/
public function getCacheKeyInfo()
{
if (null === $this->_cacheKeyInfo) {
$this->_cacheKeyInfo = parent::getCacheKeyInfo() + array(
'crumbs' => base64_encode(serialize($this->_crumbs)),
'name' => $this->getNameInLayout(),
);
}
return $this->_cacheKeyInfo;
}
protected function _toHtml()
{
if (is_array($this->_crumbs)) {
reset($this->_crumbs);
$this->_crumbs[key($this->_crumbs)]['first'] = true;
end($this->_crumbs);
$this->_crumbs[key($this->_crumbs)]['last'] = true;
}
$this->assign('crumbs', $this->_crumbs);
return parent::_toHtml();
}
public function getTitleSeparator($store = null)
{
$separator = (string)Mage::getStoreConfig('catalog/seo/title_separator', $store);
return ' ' . $separator . ' ';
}
}
Note that I simply applied what we seen above to this block via _construct
,_prepareLayout()
and getTitleSeparator()
. That's it . We are done
Now again remove cache and load the page again. There it is . Our breadcrumbs only appear for category pages now.
Note: Do not edit core files as I described here. You need to do these things without touching the core files. You need to create a module according to the details that I have given here.
If you don't have time. I have made it for you. Its free.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With