2012-09-05 18 views
12

Sto creando un blocco "Prodotto del mese" per il footer. Dovrebbe caricare i prodotti di una categoria e mostrare il primo.Magento: mostra i prodotti di una categoria specifica nel footer

Questo è il mio file di modello 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> 

E 'solo una versione semplificata del modello di elenco dei prodotti di Magento: catalog/product/list.phtml


FUNZIONA

Quando incorporare il blocco in un CMS pagina, è funziona bene. Esempio:

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


NON FUNZIONANTE

Quando l'incorporamento del blocco via local.xml, fallisce. Viene restituito il markup corretto ma la categoria specificata non viene caricata. Invece un casuale (non so come sono selezionati) viene caricato un set di prodotti.

Il mio codice 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> 

Per completezza, sto rendendo il blocco in modo esplicito nel page/html/footer.phtml in questo modo:

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


Tutte le idee?

La mia ipotesi migliore è che il mio local.xml non sia corretto. C'è un blocco genitore che devo caricare?


[Aggiornamento]

mio codice originale si blocca la pagina del prodotto. La soluzione alternativa è non basando così tanto il codice sul file principale Magento: catalog/product/list.phtml. In particolare evitando questa linea:

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


[Soluzione]

una versione funzionante con esempi per l'uso in CMS pagine e LayoutXML è incluso qui: https://stackoverflow.com/a/12288000/1497746

+0

'local.xml' - dove si trova questo file? (percorso completo) – FlorinelChis

+0

@FlorinelChis - Questo non è un problema con la gerarchia di fallback dei temi. È il posto normale per un pacchetto personalizzato: /app/design/frontend/custom/custom/layout/local.xml –

risposta

12

Trovato una soluzione di lavoro utilizzando il consiglio di 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> 

In breve, la collezione viene generata manualmente invece di ricevere una collezione (come il mio tentativo iniziale ha fatto):

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


Utilizzando in un CMS Pagina:

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


Utilizzo in un modello:

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


risorse utili:

come ottenere una collezione di prodotti:

usando la magia getter/setter:

+0

Notato che ' getPriceHtml ($ _ product, true)?>' Non sembra renderizzare. –

+0

hai trovato una soluzione per rendere il prezzo? @ brendan-falkowski – Kenny

+0

@Kenny - No, non sono sicuro di come farlo funzionare. –

5

In primo luogo, ho avuto problemi casuali nel corso degli anni utilizzando i nodi di attributo di aggiornamento layout xml per impostare valori su blocchi (diversi da template, as, name, type o class, quindi provare qualcosa di simile a questo

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

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

può aiutare, e sarebbe il mio primo passo.

Dopo di che, mi piacerebbe andare a vedere il codice di blocco che sta caricando la raccolta

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

Il metodo getLoadedProductCollection avvolge una chiamata a _getProductCollection, e _getProductCollection è dove la raccolta è effettivamente caricato.

Così, un po 'di codice di debug temporaneo

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

può contribuire a garantire la vostra categoria id sta rendendo l'aggiornamento di layout XML al blocco.

Tuttavia, se si guarda un po 'più profondo a _getProductCollection, noterete che ci sono alcune condizioni in cui azzera l'ID della categoria.

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())); 
    } 
} 
... 

qualche altro pezzo di codice Magento ha impostato la proprietà show_root_category, o sei in una pagina dove c'è un oggetto prodotto nel Registro di sistema, Magento avrà la precedenza la categoria id.

cose che fanno ancora più complicate, una volta che la collezione viene caricato è impostato su una proprietà protetta

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

che non ha alcun metodo getter pubblico.

I modi per procedere qui sono una miriade. Se fossi stato io piacerebbe prendere in considerazione una delle seguenti

  1. Utilizzo di una classe di blocco personalizzato che si estende Mage_Catalog_Block_Product_List e ha un metodo per resettare la categoria su una collezione o il caricamento di una nuova collezione

  2. Caricamento del raccolta me stesso, senza fare affidamento sul codice in product/list

+0

Il '' metodo e ' category_id' metodo funziona su * Pagine CMS * e * Vista catalogo *. Viene generata un'eccezione su * Vista prodotto *. Investigating ... –

+0

Magento * fa * sembra sovrascrivere la raccolta su * Product View * causando un'eccezione che non so come tracciare, quindi mi sono spostato sui tuoi due suggerimenti finali. # 2 ha funzionato per me. Pubblicherò come risposta a breve. –

1

ho ricreato con successo il problema sotto Magento CE 1.7.0.2.

Per prima cosa ho creato un local.xml con questo contenuto:

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

ho capito, che alcuni elementi di avvolgimento XML mancano e ha aggiunto alcune linee extra:

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

Dopo aver aggiunto il necessario Elementi XML ha funzionato.

+0

- Buona idea, ma anche il mio 'local.xml' include questi. Ho pubblicato solo il codice abbreviato e pertinente. –

+0

Il mio essere hai qualche caso speciale. Solo per la cronaca: l'ho provato solo per la home page. Inoltre ho creato un tema fittizio in cui inserire local.xml e custom/featured-product.phtml non sono state installate estensioni. Sono stati utilizzati i dati di esempio dei prodotti e ho solo modificato l'ID della categoria. – ceckoslab

+0

Ha caricato la giusta raccolta di prodotti dalla categoria specificata? –

Problemi correlati