<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Engineer-ing.com</title>
	<atom:link href="http://www.engineer-ing.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.engineer-ing.com</link>
	<description>Magento-based Software Engineering Services</description>
	<lastBuildDate>Mon, 06 Feb 2012 12:10:47 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.1</generator>
<meta xmlns="http://www.w3.org/1999/xhtml" name="robots" content="noindex,follow" />
		<item>
		<title>Get product name using its sku &#8211; in efficient way &#8211; using collection</title>
		<link>http://www.engineer-ing.com/get-product-name-using-its-sku-in-efficient-way-using-collection/</link>
		<comments>http://www.engineer-ing.com/get-product-name-using-its-sku-in-efficient-way-using-collection/#comments</comments>
		<pubDate>Mon, 06 Feb 2012 12:06:00 +0000</pubDate>
		<dc:creator>Engineer-ing</dc:creator>
				<category><![CDATA[Speeding Up Magento Site]]></category>
		<category><![CDATA[Working With Magento Collections]]></category>

		<guid isPermaLink="false">http://www.engineer-ing.com/?p=662</guid>
		<description><![CDATA[If for some reason you have list of products skus, and for each you need to fetch out it&#8217;s name, you will better not use the old way of $pname = Mage::getSingleton(&#8220;catalog/product&#8221;)->load(Mage::getSingleton(&#8220;catalog/product&#8221;)->getIdBySku($productSku))->getName(); because it will slow up dramatically your site. Better use the following piece of code: &#60;?php $productSku = 'sku1'; $pname = Mage::getSingleton("catalog/product") ->getCollection()&#160;<a href="http://www.engineer-ing.com/get-product-name-using-its-sku-in-efficient-way-using-collection/" class="read-more">Continue Reading</a>]]></description>
			<content:encoded><![CDATA[<p>If for some reason you have list of products skus, and for each you need to fetch out it&#8217;s name,<br />
you will better not use the old way of<br />
$pname = Mage::getSingleton(&#8220;catalog/product&#8221;)->load(Mage::getSingleton(&#8220;catalog/product&#8221;)->getIdBySku($productSku))->getName();</p>
<p>because it will slow up dramatically your site.<br />
Better use the following piece of code:</p>
<pre class="brush:php;">&lt;?php

$productSku = 'sku1';

$pname = Mage::getSingleton("catalog/product")
	    		->getCollection()
	    		->addFieldToFilter('sku', $newpsku)
	    		->addAttributeToSelect('name')
	    		->load()
	    		->getFirstItem()
	    		->getName();
</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.engineer-ing.com/get-product-name-using-its-sku-in-efficient-way-using-collection/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Get the Parent URL of a Child Product</title>
		<link>http://www.engineer-ing.com/get-parent-url-of-a-child-product/</link>
		<comments>http://www.engineer-ing.com/get-parent-url-of-a-child-product/#comments</comments>
		<pubDate>Tue, 16 Aug 2011 11:08:58 +0000</pubDate>
		<dc:creator>Alona</dc:creator>
				<category><![CDATA[Configurable products]]></category>
		<category><![CDATA[configurable products]]></category>
		<category><![CDATA[efficient code with magento]]></category>
		<category><![CDATA[speeding up magento site]]></category>

		<guid isPermaLink="false">http://www.engineer-ing.com/?p=251</guid>
		<description><![CDATA[In this post I will show you how to get the parent URL of a child product EFFICIENTLY (that means, unlike the very common mistake most Magento developers do, it is a way that will not slow your website down). Let&#8217;s say you have configurable products in your Magento site.  Each configurable product has 1&#160;<a href="http://www.engineer-ing.com/get-parent-url-of-a-child-product/" class="read-more">Continue Reading</a>]]></description>
			<content:encoded><![CDATA[<p>In this post I will show you how to get the parent URL of a child product EFFICIENTLY (that means, unlike the very common mistake most Magento developers do, it is a way that will not slow your website down).</p>
<p>Let&#8217;s say you have configurable products in your Magento site. <br />
Each configurable product has 1 parent product (configurable product) and some (let&#8217;s say 2) children (simple product). Let&#8217;s say you wish to display the product list on your category page, but each product should have it&#8217;s parent URL.</p>
<p>Lets implement this:<br />
I assume you wish to implement this in base/default/template/catalog/product/list.phtml</p>
<pre class="brush:php">&lt;?php $i=0; foreach ($_productCollection as $_product):
	$prodId = $_product-&gt;getId();
	$arrayOfParentIds = Mage::getSingleton("catalog/product_type_configurable")-&gt;getParentIdsByChild($prodId);
	$parentId = (count($arrayOfParentIds) &gt; 0 ? $arrayOfParentIds[0] : null);
	$url = $_product-&gt;getProductUrl();
	if(!is_null($parentId)){
		$url = Mage::getModel("catalog/product")-&gt;load($parentId)-&gt;getProductUrl();
	}
?&gt;
</pre>
<p>This implementation will work, but it isn&#8217;t recommended when performing on a large collection (more than 5 products / page). why? Because, the action</p>
<pre class="brush:php">Mage::getModel("catalog/product")-&gt;load($parentId);
</pre>
<p>is pretty expensive in terms of efficiency (in other words &#8211; it takes large amount of time for the server to perform this action). looping on this action more than once or twice will slow your website down dramatically.</p>
<p>So here is the alternative. might be more complicated, but a lot more efficient (implementation):</p>
<pre class="brush:php">&lt;?php
        $rewrite = Mage::getModel('core/url_rewrite');

	$params = array();
	$params['_current']     = false;

	?&gt;
	&lt;?php $i=0; foreach ($_productCollection as $_product):

	$prodId = $_product-&gt;getId();
	$arrayOfParentIds = Mage::getSingleton("catalog/product_type_configurable")-&gt;getParentIdsByChild($prodId);
	$parentId = (count($arrayOfParentIds) &gt; 0 ? $arrayOfParentIds[0] : null);
	$url = $_product-&gt;getProductUrl();
	$idPath = 'product/'.$parentId;
	$rewrite-&gt;loadByIdPath($idPath);

	$parentUrl = Mage::getUrl($rewrite-&gt;getRequestPath(), $params);
	$url = ($parentUrl ? $parentUrl : $url);
	?&gt;
</pre>
<p>This implemenation is much more cheaper in terms of efficiency, because we use</p>
<pre class="brush:php">$rewrite-&gt;loadByIdPath($idPath);
</pre>
<p>instead of the expensive</p>
<pre class="brush:php">Mage::getModel("catalog/product")-&gt;load($parentId);
</pre>
<p>which means, less loading time.</p>
<p>That&#8217;s all <img src='http://www.engineer-ing.com/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> </p>
]]></content:encoded>
			<wfw:commentRss>http://www.engineer-ing.com/get-parent-url-of-a-child-product/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Writing a Magento Extension &#8211; part2</title>
		<link>http://www.engineer-ing.com/writing-magento-extension-part2/</link>
		<comments>http://www.engineer-ing.com/writing-magento-extension-part2/#comments</comments>
		<pubDate>Tue, 09 Aug 2011 22:00:41 +0000</pubDate>
		<dc:creator>Jermy</dc:creator>
				<category><![CDATA[Writing a Magento Extension]]></category>
		<category><![CDATA[hello world]]></category>
		<category><![CDATA[magento extension]]></category>
		<category><![CDATA[magento module]]></category>

		<guid isPermaLink="false">http://www.engineer-ing.com/?p=191</guid>
		<description><![CDATA[On this part, we will make the text &#8220;Hello World&#8221; appear inside the Magento design. For this, go to app/code/local/Engineering/Helloworld/controllers/IndexController.php and change its code to following: &#60;?php class Engineering_Helloworld_IndexController extends Mage_Core_Controller_Front_Action { public function indexAction() { $this-&#62;loadLayout(); $this-&#62;renderLayout(); } } A short explanation: When calling to $this-&#62;loadLayout(); Magento will go to &#8220;app/design/myinterface/mytheme/layout&#8221; (on a fresh&#160;<a href="http://www.engineer-ing.com/writing-magento-extension-part2/" class="read-more">Continue Reading</a>]]></description>
			<content:encoded><![CDATA[<p>On this part, we will make the text &#8220;Hello World&#8221; appear inside the Magento design.</p>
<p>For this, go to app/code/local/Engineering/Helloworld/controllers/IndexController.php and change its code to following:</p>
<pre class="brush:php;">&lt;?php class Engineering_Helloworld_IndexController extends Mage_Core_Controller_Front_Action
{
	public function indexAction()
	{
	    $this-&gt;loadLayout();
            $this-&gt;renderLayout();
	}
}</pre>
<p>A short explanation:<br />
When calling to</p>
<pre class="brush:php;">$this-&gt;loadLayout();</pre>
<p>Magento will go to &#8220;app/design/myinterface/mytheme/layout&#8221; (on a fresh Magento installation, it actually &#8220;app/design/base/default/layout&#8221;) reads all the XML files and searches there for a tag named layout and loads  the found data to &#8220;core/layout&#8221; object.<br />
Now, when calling to</p>
<pre class="brush:php;">$this-&gt;renderLayout();</pre>
<p>the layout will be rendered.</p>
<p>Now lets go to www.mysite.com/helloworld &#8211; we will see some empty standard Magento design. It&#8217;s because only tags get loaded.</p>
<p>Now go to app/code/local/Engineering/Helloworld/etc/config.xml and add some change to it:</p>
<pre class="brush:xml;">&lt;?xml version="1.0"?&gt;
&lt;config&gt;
 &lt;modules&gt;
  &lt;Engineering_Helloworld&gt;
   &lt;version&gt;0.1.0&lt;/version&gt;
  &lt;/Engineering_Helloworld&gt;
 &lt;/modules&gt;
 &lt;frontend&gt;
  &lt;routers&gt;
   &lt;engineering_helloworld&gt;
    &lt;use&gt;standard&lt;/use&gt;
    &lt;args&gt;
     &lt;module&gt;Engineering_Helloworld&lt;/module&gt;
     &lt;frontName&gt;helloworld&lt;/frontName&gt;
    &lt;/args&gt;
   &lt;/engineering_helloworld&gt;
  &lt;/routers&gt;
  &lt;layout&gt;
   &lt;updates&gt;
    &lt;engineering_helloworld&gt;
     &lt;file&gt;helloworld.xml&lt;/file&gt;
    &lt;/engineering_helloworld&gt;
  &lt;/updates&gt;
  &lt;/layout&gt;
 &lt;/frontend&gt;
&lt;/config&gt;</pre>
<p>This tells magento to regard the file named helloworld.xml as another layout file. Now create the helloworld.xml at:<br />
app/design/frontend/default/default/layout/helloworld.xml<br />
Type in the following:</p>
<pre class="brush:xml;">&lt;?xml version="1.0"?&gt;
&lt;layout version="0.1.0"&gt;
 &lt;engineering_helloworld_index_index&gt;
  &lt;reference name="content"&gt;
   &lt;block type="core/template" name="helloworld.text" template="engineering/helloworld/sayhello.phtml"/&gt;
  &lt;/reference&gt;
 &lt;/engineering_helloworld_index_index&gt;
&lt;/layout&gt;</pre>
<p>Because the URL is www.mysite.com/<span style="color: #ff0000;">helloworld/index/index</span> magento will load the content of &lt;helloworld_index_index&gt; tag to the layout object.  Afterwards, the</p>
<pre class="brush:php;">$this-&gt;renderLayout();</pre>
<p>will put the block named &#8220;helloworld.text&#8221; to the block named &#8220;content&#8221;,  load the block class &#8220;core/template&#8221; (Mage_Core_Block_Template) and template &#8220;engineering/helloworld/sayhello.phtml&#8221; (app/design/frontend/myinterface/mytheme/engineering/helloworld/sayhello.phtml)  for this block.</p>
<p>Now, create &#8220;sayhello.phtml&#8221; at<br />
app/design/frontend/default/default/template/engineering/helloworld/sayhello.phtml<br />
type there just</p>
<p>Hello World</p>
<p>Now, go to www.mysite.com/admin/helloworld &#8211; you should see the text &#8220;Hello world&#8221; inside magento design.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.engineer-ing.com/writing-magento-extension-part2/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Writing a Magento Extension &#8211; part1</title>
		<link>http://www.engineer-ing.com/writing-magento-extention/</link>
		<comments>http://www.engineer-ing.com/writing-magento-extention/#comments</comments>
		<pubDate>Fri, 05 Aug 2011 19:22:31 +0000</pubDate>
		<dc:creator>Jermy</dc:creator>
				<category><![CDATA[Writing a Magento Extension]]></category>
		<category><![CDATA[hello world]]></category>
		<category><![CDATA[magento extension]]></category>
		<category><![CDATA[magento module]]></category>

		<guid isPermaLink="false">http://www.engineer-ing.com/?p=143</guid>
		<description><![CDATA[In this tutorial we will create a Magento extension step by step. our extension will print &#8220;Hello World&#8221; to the screen. Go to &#8220;app/code/local&#8221; and create a new folder. name it &#8220;Packagename&#8221; &#8211; the &#8220;Packagename&#8221; is likely to be your company name &#8211; this folder will serve all the extensions that will be made by&#160;<a href="http://www.engineer-ing.com/writing-magento-extention/" class="read-more">Continue Reading</a>]]></description>
			<content:encoded><![CDATA[<p>In this tutorial we will create a Magento extension step by step. our extension will print &#8220;Hello World&#8221; to the screen.</p>
<p>Go to &#8220;app/code/local&#8221; and create a new folder. name it &#8220;Packagename&#8221; &#8211; the &#8220;Packagename&#8221; is likely to be your company name &#8211; this folder will serve all the extensions that will be made by your company. I&#8217;ll call it &#8220;Engineering&#8221;.</p>
<p>Inside the &#8220;Packagename&#8221; folder, create another folder named &#8220;Modulename&#8221; &#8211; the &#8220;Modulename&#8221; is the name of your module &#8211; I&#8217;ll name it &#8220;Helloworld&#8221;. now we should have the following path:</p>
<p>app/code/local/Engineering/Helloworld</p>
<p>Now you have to tell Magento about your extension, so create a file named &#8220;Engineering_Helloworld.xml&#8221; in the following path:</p>
<p>app/etc/modules/Engineering_Helloworld.xml</p>
<p>type in the following:</p>
<pre class="brush:xml;">&lt;?xml version="1.0"?&gt;
&lt;config&gt;
  &lt;modules&gt;
   &lt;Engineering_Helloworld&gt;
    &lt;active&gt;true&lt;/active&gt;
    &lt;codePool&gt;local&lt;/codePool&gt;
   &lt;/Engineering_Helloworld&gt;
  &lt;/modules&gt;
&lt;/config&gt;
</pre>
<p>Magento is a configuration-set MVC system. that means, if you want the URL</p>
<p>www.mysite.com/helloworld/index/index</p>
<p>will display &#8220;Hello World&#8221;, you need to tell Magento about this. Create a file named &#8220;config.xml&#8221; in the following path (create the etc folder, also):</p>
<p>app/code/local/Engineering/Helloworld/etc/config.xml</p>
<p>type in the following:</p>
<pre class="brush:xml;">&lt;?xml version="1.0"?&gt;
&lt;config&gt;
 &lt;modules&gt;
  &lt;Engineering_Helloworld&gt;
   &lt;version&gt;0.1.0&lt;/version&gt;
  &lt;/Engineering_Helloworld&gt;
 &lt;/modules&gt;
 &lt;frontend&gt;
  &lt;routers&gt;
   &lt;engineering_helloworld&gt;
    &lt;use&gt;standard&lt;/use&gt;
    &lt;args&gt;
     &lt;module&gt;Engineering_Helloworld&lt;/module&gt;
     &lt;frontName&gt;helloworld&lt;/frontName&gt;
    &lt;/args&gt;
   &lt;/engineering_helloworld&gt;
  &lt;/routers&gt;
 &lt;/frontend&gt;
&lt;/config&gt;
</pre>
<p>A short explanation about the config.xml tags:<br />
The &lt;use&gt; tag in the &lt;router&gt; hierarcy, tells Magento whether the &lt;router&gt; tag refers to admin url or the frontend url. we want the URL www.mysite.com/helloworld/index/index, and not  www.mysite.com/admin/helloworld/index/index, so that means we need the frontend. the &lt;use&gt; is &#8220;standard&#8221; (other options are &#8220;admin&#8221; and &#8220;default&#8221;).<br />
The tag &lt;engineering_helloworld&gt; under &lt;routers&gt; seems to be arbitrary, but sure, there are  conventions,  so you need to write your full module name in lower case.<br />
The tag &lt;frontName&gt; tells Magento about the first string of your extension&#8217;s URL, so the URL is:<br />
www.mysite.com/<span style="color: #993300;">helloworld</span>/index/index<br />
and not, for example<br />
www.mysite.com/<span style="color: #993300;">byeworld</span>/index/index<br />
[Note: you have to make sure that the term "helloworld" isn't already occupied by other extension or core module, otherwise the Magento's behavior will be unpredicted.]</p>
<p>Now it&#8217;s time to write the code for the output &#8220;Hello World&#8221;:<br />
For us, to make the page</p>
<p>www.mysite.com/helloworld/index/index</p>
<p>display &#8220;Hello World&#8221;, we need to create a file named &#8220;indexController.php&#8221; at:</p>
<p>app/code/local/Engineering/Helloworld/controllers/IndexController.php</p>
<p>and type in the following code:</p>
<pre class="brush:php">&lt;?php
class Engineering_Helloworld_IndexController extends Mage_Core_Controller_Front_Action
{
    public function indexAction()
    {
    echo "Hello World";
    }
}</pre>
<p>Now, go to www.mysite.com/<span style="color: #ff0000;">helloworld</span>/<span style="color: #0000ff;">index</span>/<span style="color: #339966;">index</span>, and you should see the desired &#8220;Hello World&#8221;.<br />
So, actually, when you go to www.mysite.com/helloworld/index/index, Magento is looking for a front name &#8220;<span style="color: #ff0000;">helloworld</span>&#8221; through all the active module configurations. if found, it searches for <span style="color: #0000ff;">index</span>Controller. if found, it&#8217;s looking for<br />
<span style="color: #339966;">index</span>Action inside that controller.<br />
Now try to go to www.mysite.com/helloworld &#8211; you should see the same result, this is only because when nothing mentioned after the module name, Magento looking for index/index by default.</p>
<p>On the next post, we will add some design to our extension page &#8211; so don&#8217;t go anywhere <img src='http://www.engineer-ing.com/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> </p>
<p>&nbsp;</p>
<p><a href="http://www.engineer-ing.com/writing-magento-extension-part2/">Writing Magento Extension – part2</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.engineer-ing.com/writing-magento-extention/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Find Out The SQL Query That Was Used To Retrieve A Collection</title>
		<link>http://www.engineer-ing.com/find-out-the-sql-query-that-used-to-retrieve-the-collection/</link>
		<comments>http://www.engineer-ing.com/find-out-the-sql-query-that-used-to-retrieve-the-collection/#comments</comments>
		<pubDate>Thu, 04 Aug 2011 21:43:57 +0000</pubDate>
		<dc:creator>Ron</dc:creator>
				<category><![CDATA[Working With Magento Collections]]></category>
		<category><![CDATA[debugging]]></category>
		<category><![CDATA[Magento collections]]></category>

		<guid isPermaLink="false">http://www.engineer-ing.com/?p=138</guid>
		<description><![CDATA[To find out the SQL query Magento uses to retrieve a specific collection, just do the following: Let&#8217;s say you would like to know what query is used to get a product collection &#8211; go to your debugging area (or maybe some phtml file), and paste following code: &#160; $_productCollection = Mage::getResourceModel("catalog/product_collection"); $_productCollection-&#62;load(true); &#160; Passing&#160;<a href="http://www.engineer-ing.com/find-out-the-sql-query-that-used-to-retrieve-the-collection/" class="read-more">Continue Reading</a>]]></description>
			<content:encoded><![CDATA[<p>To find out the SQL query Magento uses to retrieve a specific collection, just do the following:</p>
<p>Let&#8217;s say you would like to know what query is used to get a product collection &#8211; go to your debugging area (or maybe some phtml file), and paste following code:</p>
<p>&nbsp;</p>
<pre class="brush:php">$_productCollection = Mage::getResourceModel("catalog/product_collection");
$_productCollection-&gt;load(true);</pre>
<p>&nbsp;</p>
<p>Passing &#8220;true&#8221; as a parameter to the load function, will print out the query that Magento uses to retrieve the items for the collection.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.engineer-ing.com/find-out-the-sql-query-that-used-to-retrieve-the-collection/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Changing The Select After The Collection Has Been Loaded</title>
		<link>http://www.engineer-ing.com/changing-the-select-after-the-collection-has-been-loaded/</link>
		<comments>http://www.engineer-ing.com/changing-the-select-after-the-collection-has-been-loaded/#comments</comments>
		<pubDate>Thu, 04 Aug 2011 21:29:48 +0000</pubDate>
		<dc:creator>Ron</dc:creator>
				<category><![CDATA[Working With Magento Collections]]></category>
		<category><![CDATA[Magento collections]]></category>

		<guid isPermaLink="false">http://www.engineer-ing.com/?p=130</guid>
		<description><![CDATA[Lets observe at the following example: For some reason you want to show the products whose price is lower than 100$. If you go to list.phtml at app/design/frontend/base/default/template/catalog/product, you will see the following line: $_productCollection=$this-&#62;getLoadedProductCollection(); $_productCollection is instance of Mage_Catalog_Model_Resource_Eav_Mysql4_Product_Collection, and of course this is already loaded collection (collection that has items). resource collections in&#160;<a href="http://www.engineer-ing.com/changing-the-select-after-the-collection-has-been-loaded/" class="read-more">Continue Reading</a>]]></description>
			<content:encoded><![CDATA[<p>Lets observe at the following example:</p>
<p>For some reason you want to show the products whose price is lower than 100$.<br />
If you go to list.phtml at app/design/frontend/base/default/template/catalog/product, you will see the following line:</p>
<pre class="brush:php">$_productCollection=$this-&gt;getLoadedProductCollection();</pre>
<p>$_productCollection is instance of Mage_Catalog_Model_Resource_Eav_Mysql4_Product_Collection, and of course this is already loaded collection (collection that has items). resource collections in Magento &#8211; once the collection is loaded, you cannot add anything to the &#8220;select&#8221; and then call &#8220;load&#8221; again &#8211; this will not change the items of a collection. The solution is:</p>
<pre class="brush:php">$_productCollection-&gt;clear();
$_productCollection-&gt;getSelect()-&gt;where('price_index.price &lt; 100'); $_productCollection-&gt;load();</pre>
<p>In line 1 we called to &#8220;clear&#8221; function that deleted all items in the collection, but preserved the current select. So in the line 2 we added stuff to the select, and called &#8220;load&#8221;. This gave us the desired result.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.engineer-ing.com/changing-the-select-after-the-collection-has-been-loaded/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>The Architecture of Magento Layered Navigation</title>
		<link>http://www.engineer-ing.com/the-architecture-of-magento-layered-navigation/</link>
		<comments>http://www.engineer-ing.com/the-architecture-of-magento-layered-navigation/#comments</comments>
		<pubDate>Tue, 02 Aug 2011 17:44:45 +0000</pubDate>
		<dc:creator>Alona</dc:creator>
				<category><![CDATA[Magento Layered Navigation]]></category>
		<category><![CDATA[filters]]></category>
		<category><![CDATA[layered navigation]]></category>
		<category><![CDATA[sidebar]]></category>

		<guid isPermaLink="false">http://www.engineer-ing.com/?p=66</guid>
		<description><![CDATA[So how actually does Magento Layered Navigation work? It may sound surprising, but a chunk of code that triggers all the functionality of the layered navigation, is placed in &#8220;Mage_Catalog_Block_Layer_View&#8221;, inside the function &#8220;_prepareLayout()&#8221;. When is the function _prepareLayout being called? The function &#8220;_prepareLayout()&#8221; exists in every block, and it&#8217;s being called each time the&#160;<a href="http://www.engineer-ing.com/the-architecture-of-magento-layered-navigation/" class="read-more">Continue Reading</a>]]></description>
			<content:encoded><![CDATA[<p><span style="color: #800000;"><strong>So how actually does Magento Layered Navigation work?</strong></span></p>
<p>It may sound surprising, but a chunk of code that triggers all the functionality of the layered navigation, is placed in &#8220;Mage_Catalog_Block_Layer_View&#8221;, inside the function &#8220;_prepareLayout()&#8221;.</p>
<p><strong><span style="color: #800000;">When is the function _prepareLayout being called?</span></strong></p>
<p>The function &#8220;_prepareLayout()&#8221; exists in every block, and it&#8217;s being called each time the block is being created.<br />
Therefore, each time the block &#8220;Mage_Catalog_Block_Layer_View&#8221; is created, it&#8217;s function &#8220;_prepareLayout()&#8221; is being called.</p>
<p>Here we loop over all the filterable attributes and filter the current product collection by each of them:<br />
We create an appropriate block for each attribute (for example, for  dropdown attribute, we create block from class  &#8220;Mage_Catalog_Block_Layer_Filter_Attribute&#8221;) and call its &#8220;init&#8221;  function.</p>
<pre class="brush:php">/* FILE: code/core/Mage/Catalog/Block/Layer/View.php Function:_prepareLayout */
/**
     * Prepare child blocks
     *
     * @return Mage_Catalog_Block_Layer_View
     */
    protected function _prepareLayout()
    {
        $stateBlock = $this-&gt;getLayout()-&gt;createBlock($this-&gt;_stateBlockName)
            -&gt;setLayer($this-&gt;getLayer());

        $categoryBlock = $this-&gt;getLayout()-&gt;createBlock($this-&gt;_categoryBlockName)
            -&gt;setLayer($this-&gt;getLayer())
            -&gt;init();

        $this-&gt;setChild('layer_state', $stateBlock);
        $this-&gt;setChild('category_filter', $categoryBlock);

        $filterableAttributes = $this-&gt;_getFilterableAttributes();
        foreach ($filterableAttributes as $attribute) {
            if ($attribute-&gt;getAttributeCode() == 'price') {
                $filterBlockName = $this-&gt;_priceFilterBlockName;
            }
            elseif ($attribute-&gt;getBackendType() == 'decimal') {
                $filterBlockName = $this-&gt;_decimalFilterBlockName;
            }
            else {
                $filterBlockName = $this-&gt;_attributeFilterBlockName;
            }

            $this-&gt;setChild($attribute-&gt;getAttributeCode() . '_filter',
                $this-&gt;getLayout()-&gt;createBlock($filterBlockName)
                    -&gt;setLayer($this-&gt;getLayer())
                    -&gt;setAttributeModel($attribute)
                    -&gt;init());
        }

        $this-&gt;getLayer()-&gt;apply();

        return parent::_prepareLayout();
    }</pre>
<p>Inside the &#8220;init&#8221; function we have a call to &#8220;_initFilter&#8221;:</p>
<p>Here (line 15) we call the apply function on the model that regards the  filter block. (e.g:  for the block  &#8220;Mage_Catalog_Block_Layer_Filter_Attribute&#8221;, the model will be  &#8220;Mage_Catalog_Model_Layer_Filter_Attribute&#8221;)</p>
<pre class="brush:php">/* FILE: code/core/Mage/Catalog/Block/Layer/Filter/Abstract.php Function:_initFilter */
/**
     * Init filter model object
     *
     * @return Mage_Catalog_Block_Layer_Filter_Abstract
     */
    protected function _initFilter()
    {
        if (!$this-&gt;_filterModelName) {
            Mage::throwException(Mage::helper('catalog')-&gt;__('Filter model name must be declared.'));
        }
        $this-&gt;_filter = Mage::getModel($this-&gt;_filterModelName)
            -&gt;setLayer($this-&gt;getLayer());
        $this-&gt;_prepareFilter();

        $this-&gt;_filter-&gt;apply($this-&gt;getRequest(), $this);
        return $this;
    }</pre>
<pre class="brush:php"> /* FILE: code/core/Mage/Catalog/Model/Layer/Filter/Attribute.php Function:apply */

So finally, the filter is applied to product collection if it exists and has non-empty value in the request URI.
 The apply is performed by
<pre>$this-&gt;_getResource()-&gt;applyFilterToCollection($this, $filter);</pre>
<p>(in the following code chunk).</p>
<p>/**<br />
* Apply attribute option filter to product collection<br />
*<br />
* @param   Zend_Controller_Request_Abstract $request<br />
* @param   Varien_Object $filterBlock<br />
* @return  Mage_Catalog_Model_Layer_Filter_Attribute<br />
*/<br />
public function apply(Zend_Controller_Request_Abstract $request, $filterBlock)<br />
{<br />
$filter = $request-&gt;getParam($this-&gt;_requestVar);<br />
if (is_array($filter)) {<br />
return $this;<br />
}<br />
$text = $this-&gt;_getOptionText($filter);<br />
if ($filter &amp;&amp; $text) {<br />
$this-&gt;_getResource()-&gt;applyFilterToCollection($this, $filter);<br />
$this-&gt;getLayer()-&gt;getState()-&gt;addFilter($this-&gt;_createItem($text, $filter));<br />
$this-&gt;_items = array();<br />
}<br />
return $this;<br />
}</pre>
<p>While &#8220;_getResource&#8221; returns a resource model of this class (in our example for the class &#8220;Mage_Catalog_Model_Layer_Filter_Attribute&#8221; &#8220;_getResource&#8221; will return &#8220;Mage_Catalog_Model_Resource_Eav_Mysql4_Layer_Filter_Attribute&#8221; object), and there it calls &#8220;applyFilterToCollection&#8221; that builds appropriate SQL query according to the attribute and its value in URI.</p>
<p>And thats all,when the loop ends running we have a filtered product collection. And if we go now to &#8220;Mage_Catalog_Block_Product_List&#8221; (the block that shows the product collection),we will see that the collection is retrieved from layer (&#8220;Mage_Catalog_Model_Layer&#8221;) &#8211; this is the object which we have loaded the filtered product collection to it after looping over all filterable attributes.</p>
<p><span style="color: #800000;"><strong>Summary</strong></span></p>
<p><span style="color: #800000;"><span style="color: #000000;">As we have seen, the architecture of Magento Layered Navigation is simple &#8211; the <strong>creation</strong> of &#8220;</span></span>Mage_Catalog_Block_Layer_View<span style="color: #800000;"><span style="color: #000000;">&#8221; block triggers looping on models that regards the filterable attributes, and save the filtered product collection back to the layer.</span></span></p>
<p>After understanding the architecture of Magento Layered Navigation we have the power to customize Magento Layered Navigation to our own needs.<br />
Read the next posts of this series, to see the examples of our new capabilities.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.engineer-ing.com/the-architecture-of-magento-layered-navigation/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>What is Magento Layered Navigation</title>
		<link>http://www.engineer-ing.com/what-is-magento-layered-navigation/</link>
		<comments>http://www.engineer-ing.com/what-is-magento-layered-navigation/#comments</comments>
		<pubDate>Tue, 02 Aug 2011 13:32:00 +0000</pubDate>
		<dc:creator>Alona</dc:creator>
				<category><![CDATA[Magento Layered Navigation]]></category>
		<category><![CDATA[filters]]></category>
		<category><![CDATA[layered navigation]]></category>
		<category><![CDATA[side bar]]></category>

		<guid isPermaLink="false">http://www.engineer-ing.com/?p=46</guid>
		<description><![CDATA[This article is the first article within the sequences of articles/tutorials about Magento Layered Navigation. What is Magento Layered Navigation? Magento Layered Navigation is a piece of functionality that allows customers to filter categories in the following way: If you have to example a category named &#8220;Apparel&#8221; and the products inside this category have attributes&#160;<a href="http://www.engineer-ing.com/what-is-magento-layered-navigation/" class="read-more">Continue Reading</a>]]></description>
			<content:encoded><![CDATA[<p>This article is the first article within the sequences of articles/tutorials about Magento Layered Navigation.</p>
<p><strong><span style="color: #800000;">What is Magento Layered Navigation?</span></strong></p>
<p>Magento Layered Navigation is a piece of functionality that allows customers to filter categories in the following way:<br />
If you have to example a category named &#8220;Apparel&#8221; and the products inside this category have<br />
attributes such as color, manufacturer, etc., you can tell Magento to display a sidebar that will allow the customers to filter the category named &#8220;Apparel&#8221; by those attributes (and some others &#8211; will be explained later in this article). The next image shows an example of such sidebar:</p>
<p><img class="alignleft size-full wp-image-50" style="margin-right: 10px;" title="sidebar-example" src="http://www.engineer-ing.com/wp-content/uploads/2011/08/sidebar.jpg" alt="Example of Sidebar" width="201" height="725" /></p>
<p><span style="color: #800000;"><strong>How to make such a sidebar appear on my desired category?</strong></span></p>
<p>To make such a sidebar appear on a desired category and contain a desired attribute, you must follow next 3 simple steps:</p>
<p>1) <span style="text-decoration: underline;"><span style="color: #000000;">Make the desired category &#8220;anchor&#8221;</span></span>: Go to the admin panel -&gt; Catalog -&gt; Manage Categories. On the left, click on the category that you want to make filterable. On the right, click on the &#8220;Display Settings&#8221; tab, and choose &#8220;Yes&#8221; on &#8220;In Anchor&#8221; field.</p>
<p>2) <span style="text-decoration: underline;">Add filterable attributes:</span> Go  to the admin panel -&gt;Catalog -&gt; Attributes -&gt; Manage Attributes.  Add attribute which you wish to filter by (Detailed explanation about adding/managing  attributes -<a href="http://www.magentocommerce.com/knowledge-base/entry/tutorial-creating-attributes-custom-fields/">here</a>). Make sure that you choose &#8220;Filterable (without results)&#8221; or&#8221; Filterabe (with results)&#8221; in&#8221;Use In Layered Navigation&#8221; field (To do so, you must choose &#8220;Dropdown&#8221; or &#8220;Multiple Select&#8221; or &#8220;Price&#8221;  in &#8220;Catalog Input Type for Store Owner&#8221; field).  Also don&#8217;t forget to add some options (on Manage Label/Options tab). Finaly, make sure that you added those attributes to some attribute set (Detailed explanation about adding/managing  attribute sets &#8211; in next articles), remember the name of this set for next section.</p>
<p>3)<span style="text-decoration: underline;">Apply attributes on some products:</span> if in the previous section, you set &#8220;Filterable (without results)&#8221; for the attribute, you will not see this attribute on the sidebar, until you will have some products that has a value for this attribute. So, create new product (choose tha attribute set that you chose in a previous section), or update existing product (that has this attribute on it&#8217;s attribute set), so that the field of the attribute(s) you added, will contain some value. Don&#8217;t forget to set a desired category as a category of this product.</p>
<p>Now, on your desired category page, you should see a sidebar, that contains the attribute you added.</p>
<p>(Note: those 3 steps are 100% effective for clean Magento installation. If some modifications where done to the code/design files, those steps may not suffice.)</p>
<p>In the next article we will learn about the architecture of a Magento Layered Navigation.</p>
<p>&nbsp;</p>
]]></content:encoded>
			<wfw:commentRss>http://www.engineer-ing.com/what-is-magento-layered-navigation/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

