Magento:显示页脚中特定类别的产品

时间:2012-09-05 15:48:24

标签: magento

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

这是我的模板文件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


WORKING

将块嵌入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 Pages和LayoutXML的示例: https://stackoverflow.com/a/12288000/1497746

3 个答案:

答案 0 :(得分:12)

使用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:

答案 1 :(得分:5)

首先,多年来我使用布局更新xml属性节点来设置块上的值(templateasname,{{1}除外},或type,所以尝试这样的事情

class

或者

<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

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

但是,如果您对protected function _getProductCollection() { var_dump(__METHOD__); var_dump($this->getCategoryId()); Mage::Log(__METHOD__); Mage::Log($this->getCategoryId()); } 稍微深入一些,您会发现有一些条件可以重置类别ID。

_getProductCollection

Magento代码的其他部分是否设置了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将覆盖您的类别ID。

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

show_root_category

没有公开的getter方法。

这里的行进方式无数。如果是我,我会考虑以下其中一个

  1. 使用扩展$this->_productCollection = $layer->getProductCollection(); 的自定义块类,并具有重置集合类别或加载新集合的方法

  2. 自行加载收藏品,而不依赖Mage_Catalog_Block_Product_List

  3. 中的代码

答案 2 :(得分:1)

我在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元素后,它就可以了。