【问题标题】:Magento - Breadcrumbs on category pageMagento - 类别页面上的面包屑
【发布时间】:2014-08-08 10:57:14
【问题描述】:

我在 catalog/category/view.phtml 页面上定义了这样的面包屑。

echo $this->getChildHtml('breadcrumbs')

我只想在类别页面上显示面包屑。我是否需要添加任何其他内容才能使用上述代码?

我还需要在 xml 文件中定义它吗?

【问题讨论】:

  • 默认情况下,Magento 在类别页面中显示面包屑。您不需要在类别视图页面上再次调用它
  • 我知道,它也显示出来了。但我想把它放在自定义位置而不是默认位置。
  • 好的,然后告诉我你什么时候输入这个代码,它有效吗?默认的是否仍显示在您的类别页面中?最后你只需要在类别页面..而不是在另一个页面?

标签: magento breadcrumbs


【解决方案1】:

Breadcumbs 是 Magento 中的一个结构块。这意味着它是 Magento 结构的一部分。因此,如果您需要重新定位面包屑的位置,您确实需要更改 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() 方法来包含面包屑块。如果您希望该代码工作,那么面包屑块应该是定义categor/view.phtml 的块的子块。定义此模板的块是Mage_Catalog_Block_Category_View。在布局文件中,此块以名称 category.products 引用。你可以在catalog.xml看到这个块

你应该怎么做

先删除breadcrumps

您不需要在每个页面中都包含面包屑,并且您希望更改它现在出现的位置。为此,您应该必须从默认布局中删除面包屑块。这将从每个页面中删除面包屑块。最好的方法如下所示

app/design/&lt;package&gt;/&lt;theme&gt;/layout/local.xml 处创建一个布局文件并将此代码放入其中

<layout>
    <default>
        <reference name="content">
            <remove name="breadcrumbs" />
        </reference>
    </default>
</layout>   

Local.xml 文件是在处理完其他所有布局文件之后最后处理的。所以这是去除面包屑块的理想场所。现在清除缓存并加载页面。您会看到面包屑从每一页中消失。

仅在目录页面中重新定义breadcrumps

现在您只需将面包屑块放在类别页面中。正如我已经提到的,您需要做的是,将 bredcrumbs 块设置为 catalog/category_view 块的子级。但这是另一个问题。一般有两种类别的页面。具有分层导航的类别页面和不具有分层导航的类别页面。 Magento 对这两种类型都有单独的布局结构。因此,您需要为这两种类别类型指定面包屑块。

位置:app/design/&lt;package&gt;/&lt;theme&gt;/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>

工作还没有结束。现在你还需要在模板文件中调用这个面包屑块

文件:app/design/&lt;package&gt;/&lt;theme&gt;/template/catalog/category/view.phtml

<?php echo $this->getChildHtml('breadcrumbss'); ?>

view.phtml 内的任何需要的地方调用它。你完成了。现在清除缓存并再次加载页面。

哎呀!!!!

没有正确显示任何内容?

但我们的街区肯定在那里。为了确认它,打开面包屑模板文件并将任何文本放入其中。现在再次加载页面。您肯定会看到内容。那么上一次发生了什么。让我们看看。

面包屑块是特殊的块,我们需要在它被渲染之前设置一些数据。否则它将提供一个空结果。设置面包屑块的方法是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-&gt;_crumbs。否则它将向面包屑模板传递一个空数组。这不会在前端输出任何内容。这就是现在发生的事情。这意味着 magento 设置$this-&gt;_crumbs 变量的方式随着我们现在所做的更改而发生了一些变化。所以我们现在需要找到默认流程中断的地方。

Magento 使用在面包屑块本身中定义的函数 addCrumb() 设置 $this-&gt;_crumbs 变量。让我们看看那个方法。

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-&gt;_crumbs 变量正在此方法中设置。

对于分类页面,面包屑设置过程从分类视图块开始。让我们看看类别视图块。那是

 `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 中定义了我们的面包屑块。如您所见,此块在其布局中寻找 breadcrumb 块。不幸的是,该块现在不可用,因为该块实际上是在类别视图块内定义的。在此阶段,在类别视图块上方定义的块仅在此处可用。当面包屑块位于 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。它是免费的。

【讨论】:

  • 如果我使用你的模块,一切都会自动设置?或者我需要改变什么?
  • 是的,你需要做一件事。你需要像这样调用我的面包屑块。 &lt;?php echo $this-&gt;getChildHtml('category_breadcrumbs'); ?&gt; 在你的category/view.phtml
  • 还是不行。我已经在 view.phtml 页面中添加了。
  • 我已经在我的系统中开发并检查了它,它工作正常
  • 现在可以使用了。非常感谢你。我已经清除了缓存并重新索引数据,现在它突然开始工作了。
【解决方案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>

我们在布局中所做的只是取消设置原始面包屑块(而不是删除它)并将my_module.breadcrumbs 块添加到 category.products。

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'); ?>
...

【讨论】:

    【解决方案3】:

    app/design/fontend/yourpackage/yourtemplate/layout下创建local.xml

    Remove 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')
    

    【讨论】:

    • 我这样做了。但它不起作用。我将 xml 代码放在 catalog.xml 文件中。我需要把它放在 page.xml 文件中吗?
    • 你改变了什么?我应该把 local.xml 文件放在哪里?
    • 这行不通@AmitBera。看看我的回答。
    猜你喜欢
    • 1970-01-01
    • 2023-03-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多