1

I'm implementing Criteo Tags in my store, Criteo Tags must be put inside the header, for the category page I must get the Sku of the first 3 product listed in the page.

I'm using a module that get the list of sku using this code

public function getTopProducts() {    
    $layer = Mage::getSingleton('catalog/layer')->getCurrentCategory();  

    $i = 0;
    $list = array();
    foreach ($layer->getProductCollection() as $product) {
      $list [] = $product->getSku();
      if ($i++ >= 2) {
        //stop after 3rd element
        break;
      }
    }

    return json_encode($list);
  }

But in this way i just get 3 sku of the last products created of that category, i must get the real first product that user see in the list that depends on "sort by" select (priv, bame or position), on the direction arrow (hight to low or low to hight)and the page.

UPDATE----- Trying to implement Cristi's solution:

I've created a new module called CriteoTags with this files and directory:

CriteoTags
  - etc
     - config.xml

  - Model
     - observer.php

My config is

<?xml version="1.0" encoding="UTF-8"?>
<config>
    <modules>
        <Lamasas_CriteoTags>
            <version>0.0.1</version>
        </Lamasas_CriteoTags>
    </modules>
    <global>
        <models>
            <lamasas_criteotags>
                <class>Lamasas_CriteoTags_Model</class>
            </lamasas_criteotags>

        </models>

        <events>
            <catalog_block_product_list_collection>
                <observers>
                    <lamasas_criteotags>
                        <class>lamasas_criteotags/observer</class>
                        <method>criteoList</method>
                    </lamasas_criteotags >
                </observers>
            </catalog_block_product_list_collection>
        </events>

    </global>

</config>

My observer is

<?php

class Lamasas_CriteoTags_Model_Observer
{
    /**
 * Observe catalog_block_product_list_collection
 * @param Varien_Event_Observer $observer
 */
    public function criteoList(Varien_Event_Observer $observer)
    {
        $category = Mage::registry('current_category');
        if (!$category) {
            return;
        }

        //get head block
        if ($head = Mage::app()->getLayout()->getBlock('head')) {
            $block = Mage::app()->getLayout()->createBlock('core/template', 'criteo.category');
            $block->setTemplate('criteo/category.phtml');
            $head->append($block);
        }
    }

}

Obviously I've created the xml file for etc/modules

At last I've created the required template file in app/design/frontend/base/default/template/criteo/category.phtml

But Doesn't work, what is wrong with the code?

Thanks!

3

i had the same problem myself - magento loads the collection automatically when rendering the category product list (I think the call was in Toolbar.php, not in List.php, but I don't remember for sure). I solved it by rewriting _getProductCollection in List.php. However, I recommend implementing this using events (in my case, I needed that rewrite anyway). Here's how:

Create a new module, I'll call it mymodule. Then create an observer and listen to catalog_block_product_list_collection:

<core_block_abstract_prepare_layout_after>
    <observers>
        <my_observer>
            <class>mymodule/observer</class>
            <method>addCriteoCategoryTag</method>
        </my_observer>
    </observers>
</core_block_abstract_prepare_layout_after>

In Observer.php, create the addCriteoCategoryTag method:

/**
 * Observe catalog_block_product_list_collection
 * @param Varien_Event_Observer $observer
 */
public function extractPricesAndReviewSummary(Varien_Event_Observer $observer)
{
    $category = Mage::registry('current_category');
    if (!$category) {
        return;
    }

    //get head block
    if ($head = Mage::app()->getLayout()->getBlock('head')) {
        $block = Mage::app()->getLayout()->createBlock('core/template', 'criteo.category');
        $block->setTemplate('criteo/category.phtml');
        $head->append($block);
    }
}

and last, create the required template file in criteo/category.phtml:

<?php 
    $_cat = Mage::registry('current_category');
    if( !$_cat instanceof Mage_Catalog_Model_Category ) { return; }

    $_items = array(); $_k = 0;
    foreach( $_cat->getProductCollection() as $_product ) {
        if( $_k++ == 3 ) { break; }
        $_items[] = $_product->getId();
    }
?>
<script type="text/javascript" src="//static.criteo.net/js/ld/ld.js" async="true"></script>
<script type="text/javascript">
window.criteo_q = window.criteo_q || [];
window.criteo_q.push(
    {event: "setAccount", account: 'ACCOUNTID'},
    <?php if( $this->helper('customer')->isLoggedIn() ): ?>{event: "setCustomerId", id: "<?php echo $this->helper('customer')->getCustomer()->getId(); ?>"},<?php endif; ?> 
    {event: "setSiteType", type: "d"},
    {event: "viewList", item: <?php echo Zend_Json::encode($_items); ?>}
);
</script>

Something like this...

Please note I haven't tested this exact code anywhere, so don't put it in production without thoroughly testing it.

Updated per the comments conversation below: To make this work using the method described above (event listener and appending the block), you'll need to rewrite Mage_Catalog_Block_Product_list:

class Local_Catalog_Block_Product_List extends Mage_Catalog_Block_Product_list
{
    protected function _beforeToHtml()
    {
    }

    protected function _prepareLayout()
    {
        $toolbar = $this->getToolbarBlock();

        // called prepare sortable parameters
        $collection = $this->_getProductCollection();

        // use sortable parameters
        if ($orders = $this->getAvailableOrders()) {
            $toolbar->setAvailableOrders($orders);
        }
        if ($sort = $this->getSortBy()) {
            $toolbar->setDefaultOrder($sort);
        }
        if ($dir = $this->getDefaultDirection()) {
            $toolbar->setDefaultDirection($dir);
        }
        if ($modes = $this->getModes()) {
            $toolbar->setModes($modes);
        }

        // set collection to toolbar and apply sort
        $toolbar->setCollection($collection);

        $this->setChild('toolbar', $toolbar);
        Mage::dispatchEvent('catalog_block_product_list_collection', array(
            'collection' => $this->_getProductCollection()
        ));

        $this->_getProductCollection()->load();
    }
}

This just moves the code that is currently in _beforeToHtml into _prepareLayout. This way, block output won't start and the append will make sense. I think that doing everything in _beforeToHtml is wrong, but from the code comments, I see they might have ran into some issues themselves and used this as a workaround. So make sure to test all areas where catalog/product_list is being used.

Once the rewrite is done, the code should work. I've used a quick test in the template file:

<?php

foreach($this->getCollection() as $product) {
    echo $product->getName() . '<br>';
}

where collection is set from the observer (you can do it like this setTemplate(...)->setCollection($collection)). this will show the product names in the head section (actually on screen), so if you sort and change the page of the collection, you'll be able to see the results in the criteo template.

Hope I covered everything.

  • Thanks cristi maybe I'm doing something wrong in defining the module the XML and observer can you please help thanks – Marco Dec 8 '14 at 10:09
  • update your question with the module setup (config.xml) and I'll take a look – Cristi Dec 8 '14 at 11:12
  • I don't see the config.xml anywhere - you just updated the title, i was asking for the complete xml definition pasted in the question body.... – Cristi Dec 8 '14 at 13:13
  • Sorry didn't understood! Now i've done thanks – Marco Dec 9 '14 at 10:01
  • the event definition should be in a <frontend> tag, which would be a sibling of <global>. See if that works, if not, let me know your magento version. – Cristi Dec 9 '14 at 22:30

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.