【问题标题】:Magento: show products from a specific category in the footerMagento:在页脚中显示特定类别的产品
【发布时间】:2012-09-05 15:48:23
【问题描述】:

我正在为页脚构建一个“本月产品”块。它应该加载一个类别的产品并显示第一个。

这是我的模板文件custom/featured-product.phtml:

<?php $_productCollection = $this->getLoadedProductCollection() ?>

<div class="featured-product">
    <h2><?php echo $this->__('Product of the Month') ?></h2>

    <?php foreach ($_productCollection as $_product): ?>
        <div class="item">
            <a class="product-image" href="<?php echo $_product->getProductUrl() ?>">
                <img src="<?php echo $this->helper('catalog/image')->init($_product, 'small_image')->resize(200); ?>" alt="<?php echo $this->htmlEscape($this->getImageLabel($_product, 'small_image')) ?>" />
            </a>

            <a class="product-name" href="<?php echo $_product->getProductUrl() ?>"><?php echo $this->htmlEscape($_product->getName()) ?></a>

            <?php echo $this->getPriceHtml($_product, true) ?>
        </div>

        <?php
        // Note: Exit after first product.
        break;
        ?>
    <?php endforeach ?>
</div>

这只是 Magento 产品列表模板的简化版:catalog/product/list.phtml


工作中

在 CMS 页面中嵌入块时,它可以正常工作。示例:

{{block type="catalog/product_list" category_id="13" template="custom/featured-product.phtml" }}


不工作

当通过local.xml 嵌入块时,它会失败。返回正确的标记,但未加载指定的类别。而是加载了随机(我不知道它们是如何选择的)一组产品。

我的代码在local.xml:

<default>
    <reference name="footer">
        <block type="catalog/product_list" name="custom.featuredProduct" as="product_of_the_month" category_id="13" template="custom/featured-product.phtml" />
    </reference>
</default>

为了完整起见,我在page/html/footer.phtml 中显式渲染该块,如下所示:

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


有什么想法吗?

我的最佳猜测是我的local.xml 不正确。我需要加载父块吗?


[更新]

我的原始代码使产品页面崩溃。解决方法是将代码如此依赖于 Magento 核心文件:catalog/product/list.phtml。特别避开这一行:

<?php $_productCollection = $this->getLoadedProductCollection() ?>


[解决方案]

这里包含一个带有用于 CMS 页面和 LayoutXML 示例的工作版本: https://stackoverflow.com/a/12288000/1497746

【问题讨论】:

  • local.xml - 这个文件在哪里? (完整路径)
  • @FlorinelChis — 这不是主题回退层次结构的问题。这是自定义包的正常位置:/app/design/frontend/custom/custom/layout/local.xml

标签: magento


【解决方案1】:

根据 Alan Storm 的建议找到了可行的解决方案。

/template/custom/featured-product.phtml

<?php
$_categoryId = $this->getCategoryId();

$_productCollection = Mage::getModel('catalog/category')->load($_categoryId)
    ->getProductCollection()
    ->addAttributeToSelect('*')
    ->addAttributeToFilter('status', 1)
    ->addAttributeToFilter('visibility', 4)
    ->setOrder('price', 'ASC');
?>

<div class="featured-product">
    <h2><?php echo $this->__( $this->getLabel() ); ?></h2>

    <?php foreach ($_productCollection as $_product): ?>
        <div class="item">
            <a class="product-image" href="<?php echo $_product->getProductUrl() ?>">
                <img src="<?php echo $this->helper('catalog/image')->init($_product, 'small_image')->resize(200); ?>" alt="<?php echo $this->htmlEscape($this->getImageLabel($_product, 'small_image')) ?>" />
            </a>

            <a class="product-name" href="<?php echo $_product->getProductUrl() ?>"><?php echo $this->htmlEscape($_product->getName()) ?></a>

            <?php echo $this->getPriceHtml($_product, true) ?>
        </div>

        <?php
        // Note: Exit after first product.
        break;
        ?>
    <?php endforeach ?>
</div>

简而言之,集合是手动生成的,而不是接收集合(就像我最初的尝试那样):

<?php $_productCollection = $this->getLoadedProductCollection() ?>
<?php $_collectionSize = $_productCollection->count(); ?>


在 CMS 页面中使用:

{{block type="core/template" category_id="13" label="Product of the Month" template="custom/featured-product.phtml" }}


在模板中使用:

/layout/local.xml

<default>
    <reference name="footer">
        <block type="core/template" name="custom.featuredProduct" as="featured_product" template="custom/featured-product.phtml">
            <action method="setData"><key>category_id</key><value>13</value></action>
            <action method="setData"><key>label</key><value>Product of the Month</value></action>
        </block>
    </reference>
</default>

/template/page/html/footer.phtml

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


有用的资源:

如何获得产品集合:

使用魔法 getter/setter:

【讨论】:

  • 注意到&lt;?php echo $this-&gt;getPriceHtml($_product, true) ?&gt; 似乎没有渲染。
  • 你找到渲染价格的解决方案了吗? @brendan-falkowski
【解决方案2】:

首先,多年来我遇到了随机问题,使用布局更新 xml 属性节点来设置块上的值(templateasnametypeclass 除外,所以尝试这样的事情

<default>
    <reference name="footer">
        <block type="catalog/product_list" name="custom.featuredProduct" as="product_of_the_month" template="custom/featured-product.phtml">
            <action method="setCategoryId"><id>13</id></action>
        </block>
    </reference>
</default>

或者这个

<default>
    <reference name="footer">
        <block type="catalog/product_list" name="custom.featuredProduct" as="product_of_the_month" template="custom/featured-product.phtml">
            <action method="setData"><key>category_id</key><value>13</value></action>
        </block>
    </reference>
</default>

可能会有所帮助,这将是我的第一步。

之后,我会查看加载集合的代码块

#File: app/code/core/Mage/Catalog/Block/Product/List.php
class Mage_Catalog_Block_Product_List extends Mage_Catalog_Block_Product_Abstract
{
    ...
    public function getLoadedProductCollection()
    {
        return $this->_getProductCollection();
    }        
    ...
    protected function _getProductCollection()
    {
        if (is_null($this->_productCollection)) {
            $layer = $this->getLayer();
            /* @var $layer Mage_Catalog_Model_Layer */
            if ($this->getShowRootCategory()) {
                $this->setCategoryId(Mage::app()->getStore()->getRootCategoryId());
            }

            // if this is a product view page
            if (Mage::registry('product')) {
                // get collection of categories this product is associated with
                $categories = Mage::registry('product')->getCategoryCollection()
                    ->setPage(1, 1)
                    ->load();
                // if the product is associated with any category
                if ($categories->count()) {
                    // show products from this category
                    $this->setCategoryId(current($categories->getIterator()));
                }
            }

            $origCategory = null;
            if ($this->getCategoryId()) {
                $category = Mage::getModel('catalog/category')->load($this->getCategoryId());
                if ($category->getId()) {
                    $origCategory = $layer->getCurrentCategory();
                    $layer->setCurrentCategory($category);
                }
            }
            $this->_productCollection = $layer->getProductCollection();

            $this->prepareSortableFieldsByCategory($layer->getCurrentCategory());

            if ($origCategory) {
                $layer->setCurrentCategory($origCategory);
            }
        }

        return $this->_productCollection;
    }                
}

getLoadedProductCollection 方法封装了对_getProductCollection 的调用,_getProductCollection 是实际加载集合的位置。

所以,

中的一些临时调试代码
protected function _getProductCollection()
{
    var_dump(__METHOD__);
    var_dump($this->getCategoryId());
    Mage::Log(__METHOD__);
    Mage::Log($this->getCategoryId());
}

可以帮助确保您的类别 ID 从布局更新 XML 到块。

但是,如果您更深入地查看 _getProductCollection,您会注意到它在一些条件下重置类别 ID。

if ($this->getShowRootCategory()) {
    $this->setCategoryId(Mage::app()->getStore()->getRootCategoryId());
}
...
if (Mage::registry('product')) {
    // get collection of categories this product is associated with
    $categories = Mage::registry('product')->getCategoryCollection()
        ->setPage(1, 1)
        ->load();
    // if the product is associated with any category
    if ($categories->count()) {
        // show products from this category
        $this->setCategoryId(current($categories->getIterator()));
    }
}
...

是否有其他 Magento 代码设置了 show_root_category 属性,或者您在注册表中有产品对象的页面上,Magento 将覆盖您的类别 ID。

让事情变得更加复杂,一旦加载集合,它就会被设置在受保护的属性上

$this->_productCollection = $layer->getProductCollection();

没有公共 getter 方法。

这里有很多方法。如果是我,我会考虑以下之一

  1. 使用自定义块类扩展 Mage_Catalog_Block_Product_List 并具有重置集合上的类别或加载新集合的方法

  2. 自己加载集合,不依赖product/list中的代码

【讨论】:

  • &lt;action method="setCategoryId"&gt;&lt;id&gt;13&lt;/id&gt;&lt;/action&gt; 方法和 &lt;action method="setData"&gt;&lt;key&gt;category_id&lt;/key&gt;&lt;value&gt;13&lt;/value&gt;&lt;/action&gt; 方法适用于 CMS 页面目录视图Product View 引发异常。正在调查...
  • Magento does 似乎覆盖了 Product View 上的集合,导致我不知道如何跟踪的异常,所以我进入了你的最终两个建议。 #2为我工作。很快就会作为答案发布。
【解决方案3】:

我在 Magento CE 1.7.0.2 下成功重现了这个问题。

首先我创建了一个包含以下内容的 local.xml:

<default>
    <reference name="footer">
        <block type="catalog/product_list" name="custom.featuredProduct" as="product_of_the_month" category_id="13" template="custom/featured-product.phtml" />
    </reference>
</default>

我发现,缺少一些包装 XML 元素并添加了一些额外的行:

<?xml version="1.0"?>
<layout>
    <default>
        <reference name="footer">
            <block type="catalog/product_list" name="custom.featuredProduct" as="product_of_the_month" category_id="13" template="custom/featured-product.phtml" />
        </reference>
    </default>
</layout>

添加所需的 XML 元素后,它就可以工作了。

【讨论】:

  • ——好主意,但我的local.xml 也包括这些。我只发布了删节的相关代码。
  • 我是你有一些特殊情况。仅作记录:我仅对主页进行了测试。我还创建了放置 local.xml 和 custom/featured-product.phtml 的虚拟主题,没有安装扩展。使用了产品样本数据,我只更改了类别 ID。
  • 它是否从指定的类别中加载了正确的产品集合?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-04-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多