I'm building a "Product of the Month" block for the footer. It should load a category's products and display the first one.
This is my template file 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>
It's just a simplified version of Magento's product list template: catalog/product/list.phtml
When embedding the block in a CMS Page, it works fine. Example:
{{block type="catalog/product_list" category_id="13" template="custom/featured-product.phtml" }}
When embedding the block via local.xml, it fails. The correct markup is returned but the specified category is not loaded. Instead a random (I don't how they're selected) set of products is loaded.
My code in 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>
For completeness, I am rendering the block explicitly in page/html/footer.phtml like so:
<?php echo $this->getChildHtml('product_of_the_month') ?>
My best guess is my local.xml is incorrect. Is there a parent block I need to load?
My original code crashes the product page. The workaround is not basing the code so heavily on the Magento core file: catalog/product/list.phtml. Specifically avoiding this line:
<?php $_productCollection = $this->getLoadedProductCollection() ?>
A working version with examples for use in CMS Pages and LayoutXML is included here: https://stackoverflow.com/a/12288000/1497746
Found a working solution using Alan Storm's advice.
/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>
In short, the collection is manually generated rather than receiving a collection (as my initial attempt did):
<?php $_productCollection = $this->getLoadedProductCollection() ?>
<?php $_collectionSize = $_productCollection->count(); ?>
{{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') ?>
How to get a product collection:
Using magic getters/setters:
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