我在catalog / category / view.phtml页面上定义了这样的面包屑。
echo $this->getChildHtml('breadcrumbs')
我只想在类别页面上显示面包屑。我需要在代码上面添加其他任何内容吗?
我是否还需要在xml文件中定义它?
答案 0 :(得分:10)
Breadcumbs是Magento的结构块。这意味着它是Magento结构的一部分。因此,如果您需要重新定位breadcumb的位置,您确实需要更改magento布局结构定义。 Breadcump在page.xml
地点:app/design/frontend/base/default/layout/page.xml
<default>
....
<!-- bradcumb block definition -->
<block type="page/html_breadcrumbs" name="breadcrumbs" as="breadcrumbs"/>
....
</default>
显然,在页面布局模板中使用getchildHtml()
方法调用此块。这些模板位于app/design/frontend/base/default/tempate/page/
位置。看看那些文件。这里我将代码包含在1column.phtml模板
<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>
您的代码无法运行。因为您使用getChildHtml()
方法来包含breadcumb块。如果您希望该代码有效,那么breadcumb块应该是定义categor/view.phtml
的子块块。定义此模板的块为Mage_Catalog_Block_Category_View
。在布局文件中,此块使用名称category.products
引用。您可以在catalog.xml
breadcrumps
您不需要在每个页面中使用面包屑,而您想要改变现在看来的位置。为此,您必须从默认布局中删除breadcrumb块。这将从每个页面中删除breadcrumb块。最好的方法如下所示
在app/design/<package>/<theme>/layout/local.xml
创建一个布局文件,并将此代码放在
<layout>
<default>
<reference name="content">
<remove name="breadcrumbs" />
</reference>
</default>
</layout>
在处理完所有其他布局文件后, Local.xml
文件最后是进程。所以这是去除breadcrumps块的理想场所。现在清除缓存并加载页面。你会看到breadcrump从每一页都消失了。
breadcrumps
现在您只需将breadcrumb块放在类别页面中。正如我已经提到的,你需要做的是,使bredcrumbs阻塞catalog/category_view
块的子代。但这是另一个问题。通常,有两种类型的页面。具有分层导航的类别页面和没有分层导航的类别页面。 Magento为这两种类型分别布局结构。因此,您需要为这两个类别类型指定面包屑块。
地点: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>
工作尚未结束。现在你需要在模板文件中调用这个breadcrumbs块
档案:app/design/<package>/<theme>/template/catalog/category/view.phtml
<?php echo $this->getChildHtml('breadcrumbss'); ?>
在view.phtml
内的任何地方拨打电话。你完成了。现在清除缓存并再次加载页面。
OOOPSSSS !!!!!
没有显示任何正确的内容?
但我们的区块肯定在那里。要确认它,请打开面包屑模板文件并在其中放置任何文本。现在再次加载页面。您肯定会看到内容。那么之前发生的事情。让我们来看看。
Breadcrumbs块是特殊块,我们需要在渲染之前设置一些数据。否则它将提供空结果。用于设置breadcrumbs块的方法是addCrumb()
。看看面包屑块Mage_Page_Block_Html_Breadcrumbs
。我们需要查看_toHtml()方法,这就是将这个块转换为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();
}
因此,在调用此方法之前设置$this->_crumbs
至关重要。否则,它会将一个空数组传递给breadcrumbs模板。这将在前端输出任何内容。这就是现在发生的事情。这意味着magento设置$this->_crumbs
变量的方式随着我们现在的变化而变化。所以我们需要找到现在默认流程的破坏位置。
Magento使用函数$this->_crumbs
设置addCrumb()
变量,该函数在breadcrumbs块本身中定义。让我们看一下这种方法。
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;
}
正如您所看到的,这是负责使面包屑块处于活动状态的方法。您可以在此方法中看到$this->_crumbs
变量已设置。
对于类别页面,面包屑设置过程在caetgory视图块中开始。我们来看看类别视图块。那是
`Mage_Catalog_Block_Category_View::_prepareLayout()`
protected function _prepareLayout()
{
parent::_prepareLayout();
$this->getLayout()->createBlock('catalog/breadcrumbs');
....
}
在这里,您可以看到它在布局准备期间创建了新的面包屑块Mage_Catalog_Block_Breadcrumbs
。所以我们需要找到这个块的作用。
#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();
}
是的,是的。类别块的面包屑由此块设置。现在为什么它现在对我们没有用。这是我们需要了解的最棘手的领域。
事情就是这样。我们在catalog categoy view page
内定义了breadcrumbs块。正如您可以看到此块在其布局中查找breadcrumb
块。不幸的是,该块现在不可用,因为该块实际上是在类别视图块内定义的。在此阶段,仅在此处可用的类别视图块上定义的块。当breadcrumbs阻止了insdie page.xml文件时,这个块将在这里可用。因此该方法将完美地工作。
现在我们怎么能超越这个?在我看来,有两种方法可以做到这一点
1. Use observer method
2. Change the definition of breadcrumbs block.
我想采用第二种方法。因为它是我们现在可用的最佳方法。这里我们需要做的是,我们需要复制Mage_Catalog_Block_Breadcrumbs
块所执行的功能。相应地应用更改后,您的面包屑页面现在看起来像
<?php
/**
* Html page block
*
* @category Mage
* @package Mage_Page
* @author Magento Core Team <core@magentocommerce.com>
*/
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 . ' ';
}
}
请注意,我只是通过_construct
,_prepareLayout()
和getTitleSeparator()
将我们上面看到的内容应用于此块。就是这样。我们完成了
现在再次移除缓存并再次加载页面。它就是。我们的面包屑现在只出现在类别页面上。
注意:不要像我在此处描述的那样编辑核心文件。您需要在不触及核心文件的情况下执行这些操作。您需要根据我在此处提供的详细信息创建模块。
如果你没有时间。 I have made it for you。它是免费的。
答案 1 :(得分:2)
我觉得有更优雅的方式来做到这一点。
Rajeev K Tomy对这个问题的解释很好,但我想提出IMO在布局方面(无需重新定义catalog.products
块)和代码方面(不需要重建面包屑)的清洁解决方案)。
<强>布局强>
<catalog_category_default>
<reference name="root">
<action method="unsetChild">
<!-- For EE - Child to unset may be different in CE -->
<alias>breadcrumbsContainer</alias>
</action>
</reference>
<reference name="category.products">
<!-- Create a block from a custom local module -->
<block type="my_module/breadcrumbs" name="my_module.breadcrumbs"/>
</reference>
</catalog_category_default>
<catalog_category_layered>
<reference name="root">
<action method="unsetChild">
<!-- For EE - Child to unset may be different in CE -->
<alias>breadcrumbsContainer</alias>
</action>
</reference>
<reference name="category.products">
<!-- Create a block from a custom local module -->
<block type="my_module/breadcrumbs" name="my_module.breadcrumbs"/>
</reference>
</catalog_category_layered>
我们在布局中所做的一切都是取消设置原始面包屑块(而不是删除它)并在category.products中添加my_module.breadcrumbs
块。
My_Module_Block_Breadcrumbs代码
class My_Module_Block_Breadcrumbs extends Mage_Catalog_Block_Breadcrumbs
{
protected function _prepareLayout()
{
// Create a breadcrumbs block in order to parent::_prepareLayout to do its job
$this->getLayout()->createBlock(
'page/html_breadcrumbs',
'breadcrumbs',
array('template' => 'page/html/breadcrumbs.phtml')
);
return parent::_prepareLayout();
}
protected function _toHtml()
{
return $this->getLayout()->getBlock('breadcrumbs')->toHtml();
}
}
此代码的想法是重新创建我们在布局中删除的缺少的breadcrumbs
块。只要存在此breadcrumbs
块,Mage_Catalog_Block_Breadcrumbs::_prepareLayout
即可生效!然后它将正确地创建面包屑,而无需我们重新编码。
最后,我们创建了_toHtml()
方法,我们在其中检索现在填充的breadcrumbs
块并吐出其HTML内容。
最后要做的是在正确的模板文件中调用我们的my_module.breadcrumbs
块。
在主题的目录/类别/ view.phtml文件中
如catalog.xml
核心布局文件中所述,我们在上面的布局文件中使用的category.products
引用所使用的模板是catalog/category/view.phtml
。因此,我们所要做的就是在此模板中呈现my_module.breadcrumbs
的HTML。
...
<?php echo $this->getChildHtml('my_module.breadcrumbs'); ?>
...
答案 2 :(得分:0)
在 app / design / frontend / your package / your template / layout
下创建local.xmlRemove breadcrumbs all pages using xml
then add breadcrumbs for catalog pages.
代码,如果local.xml是
<?xml version="1.0"?>
<layout version="0.1.0">
<default>
<reference name="root">
<remove name="breadcrumbs"/>
</reference>
</default>
<catalog_category_default translate="label">
<reference name="category.products">
<block type="page/html_breadcrumbs" name="onlybreadcrumbs" as="onlybreadcrumbs"/>
</reference>
</catalog_category_default>
<catalog_category_layered translate="label">
<reference name="category.products">
<block type="page/html_breadcrumbs" name="onlybreadcrumbs" as="onlybreadcrumbs"/>
</reference>
</catalog_category_layered>
</layout>
把代码放到view.phtml
echo $this->getChildHtml('onlybreadcrumbs')