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.
Best Answer
From what I am reading, the only way to do this is by the depends tag, even if you made your module name ZZZ... The module list is re-ordered after being fetched based on dependencies...