2012-09-05 10 views
12

Estoy construyendo un bloque de "Producto del mes" para el pie de página. Debería cargar los productos de una categoría y mostrar la primera.Magento: muestra productos de una categoría específica en el pie de página

Este es mi archivo de plantilla 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> 

Es sólo una versión simplificada de la plantilla de la lista de productos de Magento: catalog/product/list.phtml


TRABAJANDO

al incrustar el bloque en un CMS página, funciona bien. Ejemplo:

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


NOT WORKING

al incrustar el bloque a través de local.xml, falla. Se devuelve el marcado correcto pero no se carga la categoría especificada. En su lugar, se carga un conjunto de productos aleatorios (no sé cómo se seleccionan).

Mi código en 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> 

Para completar, estoy haciendo que el bloque de forma explícita en page/html/footer.phtml así:

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


¿Alguna idea?

Mi mejor estimación es que mi local.xml es incorrecta. ¿Hay un bloque padre que necesito cargar?


[Actualizaciones]

Mi código original se cuela en la página del producto. La solución alternativa es no basando el código tan fuertemente en el archivo de núcleo de Magento: catalog/product/list.phtml. Específicamente evitar esta línea:

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


[Solución]

Una versión de trabajo con ejemplos de uso de CMS Pages y LayoutXML se incluye aquí: problemas aleatorios https://stackoverflow.com/a/12288000/1497746

+0

'local.xml' - donde se encuentra este archivo? (ruta completa) – FlorinelChis

+0

@FlorinelChis: este no es un problema con la jerarquía de repliegue de temas. Es el lugar normal para un paquete personalizado: /app/design/frontend/custom/custom/layout/local.xml –

Respuesta

12

Encontré una solución de trabajo usando el consejo de 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> 

En resumen, la colección se genera manualmente en lugar de recibir una colección (como mi primer intento lo hizo):

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


El uso de un CMS Página:

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


Usando en una plantilla:

/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') ?> 


recursos útiles:

cómo conseguir una recogida del producto:

Usando getters/setters mágicas:

+0

Me di cuenta de que ' getPriceHtml ($ _ product, true)?>' No parece representar. –

+0

¿Encontró una solución para obtener el precio? @ brendan-falkowski – Kenny

+0

@Kenny - No, no estoy seguro de cómo hacer que funcione. –

5

En primer lugar, que he tenido a lo largo de los años, utilizando los nodos de atributo de actualización de diseño para establecer valores en bloques (distintos de template, as, name, type, o class, por lo que intentamos algo como esto

<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> 

o esta

<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> 

pueden ayudar, y sería mi primer paso.

Después de eso, me gustaría ir vistazo al código de bloque que ha de cargar la colección

#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; 
    }     
} 

El método getLoadedProductCollection envuelve una llamada a _getProductCollection y _getProductCollection es donde realmente se carga la colección.

Así, algunos de depuración de código temporal en

protected function _getProductCollection() 
{ 
    var_dump(__METHOD__); 
    var_dump($this->getCategoryId()); 
    Mage::Log(__METHOD__); 
    Mage::Log($this->getCategoryId()); 
} 

puede ayudar a asegurar que su ID de categoría es lo que hace de la actualización del formato XML para el bloque.

Sin embargo, si mira un poco más profundo en _getProductCollection, observará que hay algunas condiciones en las que restablece la categoría 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())); 
    } 
} 
... 

alguna otra pieza de código Magento ha establecido la propiedad show_root_category, o estás en una página donde hay un objeto en el registro del producto, Magento anulará su ID de categoría.

cosas haciendo incluso más complicado, una vez que se carga la colección que está establecido en una propiedad protegida

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

que no tiene un método de obtención pública.

Las formas de proceder aquí son innumerables. Si fuera yo me considero uno de los siguientes

  1. Utilizar una clase de bloque personalizado que se extiende Mage_Catalog_Block_Product_List y tiene un método para restablecer la categoría de una colección o cargar una nueva colección

  2. Carga del colección de mí mismo, sin depender del código en product/list

+0

The '' method and ' category_id' método de trabajo en * CMS Pages * y * Catalog View *. Se lanza una excepción en * Product View *. Investigando ... –

+0

Magento * does * parece anular la colección en * Product View * causando una excepción que no sé cómo rastrear, así que pasé a las dos últimas sugerencias. # 2 funcionó para mí. Se publicará como respuesta en breve. –

1

que recrea con éxito el problema bajo Magento CE 1.7.0.2.

Primero creó una local.xml con este contenido:

<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> 

me di cuenta de que algunos elementos de envoltura XML faltan y ha añadido algunas líneas adicionales:

<?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> 

Después de añadir la necesaria Elementos XML que funcionó.

+0

- Buena idea, pero mi 'local.xml' incluye estos también. Solo publiqué el código abreviado y relevante. –

+0

My be you have some special case. Solo para el registro: lo probé solo para la página de inicio. También creé un tema ficticio donde ponía local.xml y custom/featured-product.phtml Sin extensiones instaladas. Se usaron datos de muestra de productos y solo cambié la identificación de categoría. – ceckoslab

+0

¿Cargó la colección de productos correcta de la categoría especificada? –

Cuestiones relacionadas