When you have to put varnish on a website, you may need to ajaxify the breadcrumbs.
Breadcrumbs by navigation, that’s bad !
On Magento, the breadcrumbs can be different with the customer navigation.
It’s not SEO-friendly for some people who say it’s very creepy.
What the client wants, the developer do
After a little explaination in order to have an unique SEO-friendly breadcrumbs, the client prefers have the native Magento behaviour, but with varnish. So let’s ajaxify it !
The Event
We need to ajaxify the breadcrumbs only on product page :
<frontend> <events> <controller_action_layout_render_before_catalog_product_view> <observers> <init_breadcrumbs_request> <type>singleton</type> <class>mymodule_varnish/observer</class> <method>initAjaxBreadcrumbs</method> </init_breadcrumbs_request> </observers> </controller_action_layout_render_before_catalog_product_view> </events> </frontend>
If you need to do it on categories, the event is controller_action_layout_render_before_catalog_product_view
In order to do it on all the pages : controller_action_layout_render_before
Observer’s Method
public function initAjaxBreadcrumbs(Varien_Event_Observer $observer) { /** @var $layout Mage_Core_Model_Layout */ $layout = Mage::getSingleton('core/layout'); if ($layout) { $request = Mage::app()->getFrontController()->getRequest(); if ((bool) $request->getParam('is_breadcrumbs', false)) { $_SERVER['REQUEST_URI'] = preg_replace('/is_breadcrumbs=\d/i', '', $request->getRequestUri()); Mage::app()->getFrontController()->getResponse()->setHeader('content-type', 'application/json'); $layout->removeOutputBlock('root'); $breadcrumbsBlock = $layout->getBlock('breadcrumbs'); $navAjaxContainer = $layout->createBlock('core/template', 'mymodule_navigation_ajax'); $navAjaxContainer->setData('breadcrumbs', mb_convert_encoding($breadcrumbsBlock->toHtml(), 'UTF-8', 'UTF-8')); $layout->addOutputBlock('mymodule_navigation_ajax', 'toJson'); } } }
With that, all products URL will be checked on the Observer, and if the param “is_breadcrumbs” exists, it will return a JSON with only the breadcrumbs :
We can now do an AJAX call of this URL, retrieve the HTML in javascript, and put it on the div you want 🙂
Et voilà ! You now have your ajax breadcrumbs on product pages on Magento ! If you haven’t got a JSON return, check if the “breadcrumbs” block is on your page layout !
Not cache AJAX call
Don’t forget to not cache the XML call on varnish ! Otherwise, our development is useless 😉
Memorize the last viewed category
In order to show the breadcrumbs, Magento have to know the last viewed category.
I decided to put a javascript variable, which is put in varnish cache for every category page :
<script type="text/javascript"> var catForJson = <?php echo json_encode($_category->getId()); ?> </script>
For every category page (I can know that with the previous declared variable), I launch an ajax call :
// manage breadcrumbs and prev-next links if(typeof catForJson !== 'undefined'){ jQuery.ajax({ method: "POST", data: { catId: catForJson }, url: "/ajaxinfos/header/category", cache :false, success: function(html) { // If you want to do something } }); }
Here is what I do in the ajax call :
public function categoryAction(){ $post = $this->getRequest(); $catId = $post->getParam('catId'); Mage::getSingleton('catalog/session')->setLastVisitedCategoryId($catId); Mage::getSingleton('catalog/session')->renewSession(); }
Go further !
We can do a perfect SEO-friendly breadcrumbs with varnish ! You can specify a breadcrumbs for non-AJAX call. So Googlebots (and the other bots), will see the “default” breadcrumbs, and the customer breadcrumbs will be setted in AJAX !