Reputation: 1962
Using Magento 1.7.0.2 CE, I would like to try to find a way to make XML layout changes to the Product View page, depending on if the product was searched in-site or found from the category view. Reason being, the custom vertical navigation on the left bar I made for our site uses the "current_category" key in the Magento registry to display correctly.
If there is no category set, it displays our 7 major base categories. If a category is set, it displays only the sub-categories of that base category (~34 sub-cats, expands with active sub-category). So naturally, I would like to even out my sidebar space when the vertical navigation bar is small.
If a product is browsed through a category, the registry keeps the "current_category" key, so my vertical navigation fills the left bar quite well on its own. If it is searched, the navigation bar approaches about 30% of the height when compared with the right bar.
My ideal solution would be a layout update to local.xml, but I'm not sure if there is anything already built in place with Magento to do so.
So my final question is in two parts: Is there a way within Magento's XML Layout to determine if the "catalog_product_view" page was loaded via category or search?
If not: What would be the most efficient way to code in moving a couple blocks from the right bar to the left from the product view page, depending on if the product was searched or browsed?
One possible solution (for the last bit): Would anyone know how to code in a new layout tag? I was thinking of instead of just "catalog_product_view", creating "catalog_product_view_browsed" and "catalog_product_view_searched" that are applied over the default product view.
Edit: I have it working and my answer has been posted below. :)
Upvotes: 0
Views: 1212
Reputation: 1962
In order to use custom layout handles in your local.xml
file, first you have to make an observer for it. To create an observer, you start out by adding it as an extension / module. Create the following files/folders if not present (The names Yourname
and Modulename
can be anything, just make sure it's the same where it shows up, including upper/lower case):
/app/etc/modules/Yourname_Modulename.xml
/app/code/local/Yourname/Modulename/etc/config.xml
/app/code/local/Yourname/Modulename/Model/Observer.php
Now that you have the file structure, let's look at the first file, Yourname_Modulename.xml tucked in the app/etc/modules/ folder:
<?xml version="1.0"?>
<config>
<modules>
<Yourname_Modulename>
<codePool>local</codePool>
<active>true</active>
</Yourname_Modulename>
<modules>
<config>
Now /app/code/local/Yourname/Modulename/etc/config.xml:
<?xml version="1.0"?>
<config>
<global>
<models>
<yournamemodulename>
<class>Yourname_Modulename_Model</class>
</yournamemodulename>
</models>
</global>
<frontend>
<events>
<controller_action_layout_load_before>
<observers>
<yourname_modulename_model_observer>
<type>singleton</type>
<class>Yourname_Modulename_Model_Observer</class>
<method>controllerActionLayoutLoadBefore</method>
</yourname_modulename_model_observer>
</observers>
</controller_action_layout_load_before>
</events>
</frontend>
</config>
And lastly the file /app/code/local/Yourname/Modulename/Model/Observer.php. For this one, you'll need to know what you'd like to name "your_layout_handle" and also how to determine if your layout should be loaded via PHP.
<?php
class Yourname_Modulename_Model_Observer
{
public function controllerActionLayoutLoadBefore( Varien_Event_Observer $observer)
{
//Get Layout Object
$layout = $observer->getEvent()->getLayout();
/*
*Begin Logic to Determine If Layout Handle Should Be Applied.
*Below Determines If We Are On A Product View Page.
*Here is Where You Would Modify The Code For Different Layout Handles
*/
if( Mage::registry( 'current_product' ) ) {
//Check if current_category is set
if( Mage::registry( 'current_category' ) ) {
//Send Layout Update Handle If Product Was Browsed
$layout->getUpdate()->addHandle( 'your_layout_handle' );
}
else {
//Send Layout Update Handle If Product Was Linked or Searched
$layout->getUpdate()->addHandle( 'your_other_handle' );
}
}
}
}
I would say that is all, but of course you now need to do something with your layout handles in app/code/design/frontend/package/theme/layout/local.xml. How it behaves is up to you, but for an example here is the sections that apply in my local.xml. The names I used for my handles were "catalog_product_view_browsed" and "catalog_product_view_searched".
<!-- Jump To Relevant Section -->
<catalog_product_view_browsed>
<reference name="left">
<action method="unsetChild">
<name>left.poll</name>
</action>
</reference>
<reference name="right">
<action method="insert">
<blockName>left.poll</blockName>
<siblingName>right.newsletter</siblingName>
<after>0</after>
</action>
</reference>
</catalog_product_view_browsed>
<catalog_product_view_searched>
<reference name="left">
<action method="insert">
<blockName>right.newsletter</blockName>
<siblingName>left.vertnav</siblingName>
<after>1</after>
</action>
</reference>
<reference name="right">
<action method="unsetChild">
<name>right.newsletter</name>
</action>
</reference>
</catalog_product_view_browsed>
<!-- End Relevant Section -->
You may need to refresh/clean your cache. That should be it.
Upvotes: 3
Reputation: 4071
There's unfortunately no way to track referring pages in Magento's layout XML, but you can tell if someone came to the product page from a search by checking $_SERVER['HTTP_REFERER']
.
If a user comes to a product page from a search, the referring url will look like this: /catalogsearch/result/?q=[SEARCH TERM]
.
Upvotes: 0