<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss 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/" version="2.0">

<channel>
	<title>Magebase</title>
	
	<link>http://magebase.com</link>
	<description>Magento Tutorials, Tips and Extensions - For Developers by Developers</description>
	<lastBuildDate>Mon, 13 Feb 2012 06:25:32 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.feedburner.com/magebase" /><feedburner:info xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" uri="magebase" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><item>
		<title>Quick Tip: Disable all Local Modules at Once</title>
		<link>http://magebase.com/magento-tutorials/quick-tip-disable-all-local-modules-at-once/</link>
		<comments>http://magebase.com/magento-tutorials/quick-tip-disable-all-local-modules-at-once/#comments</comments>
		<pubDate>Mon, 13 Feb 2012 05:00:14 +0000</pubDate>
		<dc:creator>Robert Popovic</dc:creator>
				<category><![CDATA[Tutorials]]></category>
		<category><![CDATA[config]]></category>
		<category><![CDATA[modules]]></category>

		<guid isPermaLink="false">http://magebase.com/?p=1551</guid>
		<description><![CDATA[Sometimes it's useful to disable all your local module code in one fell swoop. Magento has provided a neat configuration option to do just that.<p>Originally published on <a href="http://magebase.com">magebase.com</a>. Copyright &copy; 2012 Magebase - All Rights Reserved.</p>]]></description>
			<content:encoded><![CDATA[<p>While going through the study guide for the Magento Developer Exam, I&#8217;ve been learning a few interesting details that are squirreled away in the Magento code, but can be useful in day to day Magento development.</p>
<p>For example, while going through the section on Module loading, it is revealed that we can easily disable all modules living in the local (<code>app/code/local</code>) namespace by editing <code>app/etc/local.xml</code> and setting the <code>disable_local_modules</code> node to true:</p>
<pre class="brush: xml; title: ; notranslate">
&lt;config&gt;
    &lt;global&gt;
        ...
        &lt;disable_local_modules&gt;true&lt;/disable_local_modules&gt;
        ...
    &lt;/global&gt;
    ...
&lt;/config&gt;
</pre>
<p>Of course, if you have cache enable, clear or disable it to see the effects.</p>
<p>This will immediately prevent Magento from loading any code from your local code pool. You could use this to troubleshoot issues with custom modules or local Mage overrides. Of course, to find the exact culprit would require disabling individual modules one by one but at least you can narrow down your area of search quickly this way.</p>
<p>Note that this will not affect the community modules.</p>
<p>Originally published on <a href="http://magebase.com">magebase.com</a>. Copyright &copy; 2012 Magebase - All Rights Reserved.</p>]]></content:encoded>
			<wfw:commentRss>http://magebase.com/magento-tutorials/quick-tip-disable-all-local-modules-at-once/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Quick Tip: Easy pop-ups with window.js in the front end with Magento</title>
		<link>http://magebase.com/magento-tutorials/quick-tip-easy-pop-ups-with-window-js-in-the-front-end-with-magento/</link>
		<comments>http://magebase.com/magento-tutorials/quick-tip-easy-pop-ups-with-window-js-in-the-front-end-with-magento/#comments</comments>
		<pubDate>Sat, 05 Nov 2011 05:33:51 +0000</pubDate>
		<dc:creator>Robert Popovic</dc:creator>
				<category><![CDATA[Tutorials]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[window.js]]></category>

		<guid isPermaLink="false">http://magebase.com/?p=1530</guid>
		<description><![CDATA[Did you know that your Magento install comes with a Prototype based library called window.js? If you want to make use of popup windows, this is the library to include. Let's see what we can do with it.<p>Originally published on <a href="http://magebase.com">magebase.com</a>. Copyright &copy; 2011 Magebase - All Rights Reserved.</p>]]></description>
			<content:encoded><![CDATA[<p><img class="alignleft size-thumbnail wp-image-1538" title="window.js" src="http://magebase.com/wp-content/uploads/2011/11/windowjs-150x150.png" alt="window.js" width="150" height="150" />Magento comes with a lot of files, utilities and libraries, one of which is <a title="window.js" href="http://prototype-window.xilinus.com/">window.js</a>. It is a Prototype based library implementing some classes that allow you to add windows to a web page. This can be simple pop-ups and modal windows and dialogs. They can be dragged, minimized, resized and closed. You can open multiple windows if you wanted to. You can load content from a link, an HTML container on the page or via Ajax. This library is seriously versatile. The Magento admin already uses <code>window.js</code> for various pop-up functions such as the widget options and image management. Well if the back end can do it, then the front end can too.</p>
<h2 class="clear">How to use it</h2>
<p>The library is located under <code>[magento_root]/js/prototype/window.js</code>. Additionally, <code>window.js</code> comes with a bunch of CSS themes found under: <code>/js/prototype/windows/themes/*</code>. To load the library in the front end we will make or add an entry to our design theme&#8217;s <code>local.xml</code>:</p>
<pre class="brush: xml; title: ; notranslate">
&lt;default&gt;
    &lt;reference name=&quot;head&quot;&gt;
        &lt;action method=&quot;addJs&quot;&gt;&lt;script&gt;prototype/window.js&lt;/script&gt;&lt;/action&gt;
        &lt;action method=&quot;addItem&quot;&gt;&lt;type&gt;js_css&lt;/type&gt;&lt;name&gt;prototype/windows/themes/default.css&lt;/name&gt;&lt;/action&gt;
        &lt;action method=&quot;addItem&quot;&gt;&lt;type&gt;js_css&lt;/type&gt;&lt;name&gt;prototype/windows/themes/magento.css&lt;/name&gt;&lt;/action&gt;
    &lt;/reference&gt;
&lt;/default&gt;
</pre>
<p>The bare minimum necessary to make the windows look right is <code>default.css</code>. In our example above, we are also loading a supplied <code>window.js</code> theme: <code>magento.css</code>. This is the theme that the back-end loads. Now, that we have the library and styles loaded, what can we do with this? For example, we can load the compare items page in a nice pop-up instead of opening a new window. Make an override of the <code>template/catalog/product/compare/sidebar.phtml</code> in your local design theme and add the following to the end:</p>
<pre class="brush: php; title: ; notranslate">&lt;script type=&quot;text/javascript&quot;&gt;// &lt;![CDATA[
function showCompare(url) {
    winCompare = new Window({className:'magento',title:'Compare Products',url:url,width:820,height:600,minimizable:false,maximizable:false,showEffectOptions:{duration:0.4},hideEffectOptions:{duration:0.4}});
    winCompare.setZIndex(100);
    winCompare.showCenter(true);
}
// ]]&gt;&lt;/script&gt;
</pre>
<p>Also modify the line that says:</p>
<pre class="brush: php; title: ; notranslate">
&lt;button class=&quot;button&quot; title=&quot;&lt;?php echo $this-&gt;__('Compare') ?&gt;&quot; onclick=&quot;popWin('&lt;?php echo $_helper-&gt;getListUrl() ?&gt;','compare','top:0,left:0,width=820,height=600,resizable=yes,scrollbars=yes')&quot; type=&quot;button&quot;&gt;&lt;/button&gt;
</pre>
<p>to:</p>
<pre class="brush: php; title: ; notranslate">
&lt;button class=&quot;button&quot; title=&quot;&lt;?php echo $this-&gt;__('Compare') ?&gt;&quot; onclick=&quot;showCompare('&lt;?php echo $this-&gt;helper('catalog/product_compare')-&gt;getListUrl() ?&gt;')&quot; type=&quot;button&quot;&gt;&lt;/button&gt;
</pre>
<p>Add some items to compare and click on the &#8220;Compare&#8221; button and, voila, your compare page loads in a nice pop-up. I know, the Magento window theme isn&#8217;t exactly the most exciting one, but you can copy a theme CSS file to your local skin CSS folder and customize to your heart&#8217;s content.</p>
<p>Now, we might notice that the button actions in the compare window don&#8217;t quite work as expected. This is due to some of the links like Add to Cart and Add to Wishlist use <code>setPLocation</code> to set the target page URL. This won&#8217;t work in our pop-up since <code>window.js</code> loads the page into an iframe. So the remedy is to override the <code>product/compare/list.phtml</code> and add:</p>
<pre class="brush: php; title: ; notranslate">
&lt;script type=&quot;text/javascript&quot;&gt;
// &lt;![CDATA[
function setILocation(url){
    window.parent.location.href = url;
}
// ]]&gt;
&lt;/script&gt;
</pre>
<p>Then replace all <code>setPLocation</code> calls with <code>setILocation</code>.</p>
<p>The close button won&#8217;t work either but you don&#8217;t really need that as the window provides its own close button so you can simply remove it from the template.</p>
<h2>Conclusion</h2>
<p>In our example we saw how to open the compare page in a window.js pop-up. You can use this approach to create size guide pop-ups for example. However this is a powerful library and can do much more that just pop-up windows. To get a good overview of its power, visit the window.js homepage at <a title="window.js" href="http://prototype-window.xilinus.com/">prototype-window.xilinus.com</a>. You will find the documentation and a few examples there.</p>
<p>Originally published on <a href="http://magebase.com">magebase.com</a>. Copyright &copy; 2011 Magebase - All Rights Reserved.</p>]]></content:encoded>
			<wfw:commentRss>http://magebase.com/magento-tutorials/quick-tip-easy-pop-ups-with-window-js-in-the-front-end-with-magento/feed/</wfw:commentRss>
		<slash:comments>14</slash:comments>
		</item>
		<item>
		<title>Magento Sort By Newest Products Made Easy</title>
		<link>http://magebase.com/magento-tutorials/magento-sort-by-newest-products-made-easy/</link>
		<comments>http://magebase.com/magento-tutorials/magento-sort-by-newest-products-made-easy/#comments</comments>
		<pubDate>Thu, 27 Oct 2011 09:13:04 +0000</pubDate>
		<dc:creator>Robert Popovic</dc:creator>
				<category><![CDATA[Extensions]]></category>
		<category><![CDATA[Tutorials]]></category>
		<category><![CDATA[catalog]]></category>
		<category><![CDATA[sort]]></category>

		<guid isPermaLink="false">http://magebase.com/?p=1520</guid>
		<description><![CDATA[To add the ability to sort your catalog by Newest Products, you don't need to purchase extensions or hack core files. We will show you how you can do it in 5 minutes.<p>Originally published on <a href="http://magebase.com">magebase.com</a>. Copyright &copy; 2011 Magebase - All Rights Reserved.</p>]]></description>
			<content:encoded><![CDATA[<h2><img class="alignleft size-thumbnail wp-image-1525" title="sort by newest" src="http://magebase.com/wp-content/uploads/2011/10/sort-by-newest-150x150.png" alt="sort by newest" width="150" height="150" />The Situation</h2>
<p>Recently, I had the pleasure of working on an existing site we took over. The site had been upgraded from Magento CE to EE before it came to me. One of the tasks was to make a new enterprise theme and clean up any unused or incompatible extensions.</p>
<p>I will just focus on one extension here that was added to allow the catalog to be sorted by newest products. This is the EWTechnologies_SortByNewest. It came to my attention after debugging the toolbar for not showing the pagination links where there is more than one page of products. So I looked into it and to my horror realized that it was overriding the default <code>Mage_Catalog_Block_Product_List_Toolbar</code> class but extending from <code>Mage_Page_Block_Html_Pager</code>. If that wasn&#8217;t bad enough, it was also completely overriding the <code>Mage_Eav_Model_Config</code> class. This one has been substantially changed in later versions of Magento so the override implements very old code. I decided that this is too risky to keep even though there were no other visible adverse effects. It certainly isn&#8217;t best practice to run outdated code in any case.</p>
<p>I thought this feature shouldn&#8217;t require overriding so much core code so I investigated and, to my delight, found that the solution was very simple and quite elegant and didn&#8217;t involve overriding any core code as such.</p>
<h2>The Approach</h2>
<p>The Product Entity in Magento has a &#8216;created_at&#8217; attribute which stores the date when the product was created. Logically, it lends itself to be used for the sort by newest feature as it is set only once by the system, when the product was created.</p>
<p>A look into the <code>eav_attribute</code> table gives us the attribute_id and an inspection of the <code>catalog_eav_attribute</code> table shows that the attribute is set to not be used in the sort by drop-down. So, the obvious course of action was to set the attribute&#8217;s <code>used_in_sort_by</code> field to 1 and then the only other thing left was to update the <code>frontend_label</code> in <code>eav_attribute</code> to read &#8220;Newest&#8221;. That&#8217;s all, folks!</p>
<h2>The Extension</h2>
<p>I&#8217;ve whipped up a quick extensions that will perform those updates and makes it easy to install on any site that needs this feature.</p>
<p class="note">Note: This should work fine for Magento CE 1.4.x and up, PE, EE 1.8.0 and up. There is no guarantee and I don&#8217;t provide support for this extension. Use at your own risk and ALWAYS backup your database before installing.</p>
<p class="download"><a href="http://magebase.com/wp-content/uploads/2011/10/Magebase_SortByNewest.zip">Download it here.</a></p>
<h2>Conclusion</h2>
<p>This approach should be upgrade safe and works on any Magento CE version over 1.4 as well as PE and EE versions. The only issue would be if a future Magento upgrade was updating the created_at attribute but then it&#8217;s easy enough to reapply the database edits to restore functionality &#8211; easier than troubleshoot issues with core code overrides.</p>
<p class="note green"><strong>Update:</strong> If you want to set the default sort direction for the toolbar, you can do this via the layout XML. Best in your <a title="5 Useful Tricks For Your Magento local.xml" href="http://magebase.com/magento-tutorials/5-useful-tricks-for-your-magento-local-xml/">local.xml</a> but you can edit catalog.xml if your theme has overridden that:</p>
<pre class="brush: xml; title: ; notranslate">
&lt;catalog_category_default&gt;
    /* other layout nodes */
    &lt;reference name=&quot;product_list_toolbar&quot;&gt;
        &lt;action method=&quot;setDefaultDirection&quot;&gt;&lt;dir&gt;desc&lt;/dir&gt;&lt;/action&gt;
    &lt;/reference&gt;
&lt;/catalog_category_default&gt;

&lt;catalog_category_layered&gt;
    /* other layout nodes */
    &lt;reference name=&quot;product_list_toolbar&quot;&gt;
        &lt;action method=&quot;setDefaultDirection&quot;&gt;&lt;dir&gt;desc&lt;/dir&gt;&lt;/action&gt;
    &lt;/reference&gt;
&lt;/catalog_category_layered&gt;
</pre>
<p>Originally published on <a href="http://magebase.com">magebase.com</a>. Copyright &copy; 2011 Magebase - All Rights Reserved.</p>]]></content:encoded>
			<wfw:commentRss>http://magebase.com/magento-tutorials/magento-sort-by-newest-products-made-easy/feed/</wfw:commentRss>
		<slash:comments>10</slash:comments>
		</item>
		<item>
		<title>Quick Tip: Using a Frontend Model For Your Module Configuration Parameter</title>
		<link>http://magebase.com/magento-tutorials/quick-tip-using-a-frontend-model-for-your-module-configuration-parameter/</link>
		<comments>http://magebase.com/magento-tutorials/quick-tip-using-a-frontend-model-for-your-module-configuration-parameter/#comments</comments>
		<pubDate>Mon, 05 Sep 2011 05:00:44 +0000</pubDate>
		<dc:creator>Robert Popovic</dc:creator>
				<category><![CDATA[Tutorials]]></category>
		<category><![CDATA[admin]]></category>
		<category><![CDATA[config]]></category>
		<category><![CDATA[UX]]></category>

		<guid isPermaLink="false">http://magebase.com/?p=1503</guid>
		<description><![CDATA[You can greatly enhance your module's configuration options by using a front end model class. This example quick tip will show how to create a Yes/No toggle option that reveals or hides the dependent text option. <p>Originally published on <a href="http://magebase.com">magebase.com</a>. Copyright &copy; 2011 Magebase - All Rights Reserved.</p>]]></description>
			<content:encoded><![CDATA[<p>If you&#8217;re a fastidious Magento module developer, you will try to make sure that your module options only reveal the necessary and configured fields to the admin user and hide all the irrelevant stuff. Specifically, I&#8217;m referring to Yes/No options that allow the administrator to enable and configure a subsequent option. For example, you have an extension that can show additional field content if an option is enabled and allows for entering the field contents:</p>
<div id="attachment_1505" class="wp-caption aligncenter" style="width: 590px"><img class="size-full wp-image-1505" title="Standard options configuration" src="http://magebase.com/wp-content/uploads/2011/09/toggle-options-1.png" alt="Standard options configuration" width="580" height="350" /><p class="wp-caption-text">Standard options configuration</p></div>
<p>As we can see, the initial state is &#8216;No&#8217; for the &#8216;Enable Additional Text&#8217; option, and the textarea is blank. It would be really nice if the whole &#8216;Additional Text&#8217; row was hidden in this scenario.</p>
<p>We can achieve that by utilizing a front end model for our Yes/No option. Magento provides this mechanism for creating options that depend on certain settings or other dependencies. Some of the built in options are the &#8216;Allowed Countries&#8217;, Enable Flat Catalog Products/Categories and the Tax Destination Calculation &#8216;State&#8217; option.</p>
<p>We are going to use the front end model to add some logic to enable/disable the textarea and some JavaScript to enable the toggle functionality when the Yes/No drop-down is changed. Note that this is just one, albeit trivial, example of using this technique. Especially since Magento provides the <code>&lt;depends&gt;</code> node for this specific purpose (see the <a href="#update">update</a> below).</p>
<p>Using the same tutorial module from our <a href="http://magebase.com/magento-tutorials/quick-tip-explain-your-module-configuration-options-with-tooltips/">Explain Your Module Configuration Options With Tooltips</a> quick tip, we&#8217;ll change our <code>system.xml</code> to read:</p>
<pre class="brush: xml; title: ; notranslate">
&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
&lt;config&gt;
    &lt;tabs&gt;
        &lt;magebase translate=&quot;label&quot; module=&quot;custom&quot;&gt;
            &lt;label&gt;Magebase&lt;/label&gt;
            &lt;sort_order&gt;700&lt;/sort_order&gt;
        &lt;/magebase&gt;
    &lt;/tabs&gt;
    &lt;sections&gt;
        &lt;mbcustom translate=&quot;label&quot; module=&quot;custom&quot;&gt;
            &lt;tab&gt;magebase&lt;/tab&gt;
            &lt;label&gt;Magebase Tutorial Options&lt;/label&gt;
            &lt;frontend_type&gt;text&lt;/frontend_type&gt;
            &lt;sort_order&gt;10&lt;/sort_order&gt;
            &lt;show_in_default&gt;1&lt;/show_in_default&gt;
            &lt;show_in_website&gt;1&lt;/show_in_website&gt;
            &lt;show_in_store&gt;1&lt;/show_in_store&gt;
            &lt;groups&gt;
                &lt;default translate=&quot;label&quot;&gt;
                    &lt;label&gt;Conditional Toggle Options&lt;/label&gt;
                    &lt;frontend_type&gt;text&lt;/frontend_type&gt;
                    &lt;sort_order&gt;10&lt;/sort_order&gt;
                    &lt;show_in_default&gt;1&lt;/show_in_default&gt;
                    &lt;show_in_website&gt;1&lt;/show_in_website&gt;
                    &lt;show_in_store&gt;1&lt;/show_in_store&gt;
                    &lt;fields&gt;
                        &lt;mbcustomopt1 translate=&quot;label comment&quot;&gt;
                            &lt;label&gt;Enable Additional Text&lt;/label&gt;
                            &lt;frontend_type&gt;select&lt;/frontend_type&gt;
                            &lt;source_model&gt;adminhtml/system_config_source_yesno&lt;/source_model&gt;
                            &lt;frontend_model&gt;custom/adminhtml_system_config_form_field_customopt1toggle&lt;/frontend_model&gt;
                            &lt;sort_order&gt;10&lt;/sort_order&gt;
                            &lt;show_in_default&gt;1&lt;/show_in_default&gt;
                            &lt;show_in_website&gt;1&lt;/show_in_website&gt;
                            &lt;show_in_store&gt;0&lt;/show_in_store&gt;
                            &lt;comment&gt;Select whether to show a text block in the front end.&lt;/comment&gt;
                        &lt;/mbcustomopt1&gt;
                        &lt;mbcustomopt2 translate=&quot;label comment&quot;&gt;
                            &lt;label&gt;Additional Text&lt;/label&gt;
                            &lt;frontend_type&gt;textarea&lt;/frontend_type&gt;
                            &lt;sort_order&gt;20&lt;/sort_order&gt;
                            &lt;show_in_default&gt;1&lt;/show_in_default&gt;
                            &lt;show_in_website&gt;1&lt;/show_in_website&gt;
                            &lt;show_in_store&gt;0&lt;/show_in_store&gt;
                            &lt;comment&gt;Enter the content for the text block.&lt;/comment&gt;
                            &lt;tooltip&gt;Note that the content will be erased if you disable it above, and save.&lt;/tooltip&gt;
                        &lt;/mbcustomopt2&gt;
                    &lt;/fields&gt;
                &lt;/default&gt;
            &lt;/groups&gt;
        &lt;/mbcustom&gt;
    &lt;/sections&gt;
&lt;/config&gt;</pre>
<p>The key to our quick tip is in:</p>
<pre class="brush: xml; title: ; notranslate">&lt;frontend_model&gt;custom/adminhtml_system_config_form_field_customopt1toggle&lt;/frontend_model&gt;</pre>
<p>So, now, we&#8217;re going to create the front end model class. Incidentally, even though it&#8217;s named a &#8216;model&#8217; class we are going to create it as a Magento Block class since this is how the other built in front end model classes are implemented. Effectively, it is used for template output so it&#8217;s appropriate to create a block class for this.</p>
<p>Create <code>Customopt1toggle.php</code> under <code>.../Magebase/Custom/Block/Adminhtml/System/Config/Form/Field/</code> with the following content:</p>
<pre class="brush: php; title: ; notranslate">class Magebase_Custom_Block_Adminhtml_System_Config_Form_Field_Customopt1toggle extends Mage_Adminhtml_Block_System_Config_Form_Field
{

    /**
     * Get element ID of the dependent field to toggle
     *
     * @param object $element
     * @return String
     */
    protected function _getToggleElementId($element)
    {
        return substr($element-&gt;getId(), 0, strrpos($element-&gt;getId(), 'mbcustomopt1')) . 'mbcustomopt2';
    }
    /**
     * Get element ID of the dependent field's parent row
     *
     * @param object $element
     * @return String
     */
    protected function _getToggleRowElementId($element)
    {
        return 'row_'.$this-&gt;_getToggleElementId($element);
    }
    /**
     * Override method to output our custom HTML with JavaScript
     *
     * @param Varien_Data_Form_Element_Abstract $element
     * @return String
     */
    protected function _getElementHtml(Varien_Data_Form_Element_Abstract $element)
    {
        // If our Yes/No toggle is 'No' then disable the text value field
        if(!$element-&gt;getValue() || $element-&gt;getValue()!=1) {
            $_frm = $element-&gt;getForm();
            $_elm = $_frm-&gt;getElement($this-&gt;_getToggleElementId($element));
            $_elm-&gt;setDisabled('disabled')-&gt;setValue('');
        }
        // Get the default HTML for this option
        $html = parent::_getElementHtml($element);
        // Set up additional JavaScript for our toggle action. Note we are using the two helper methods above
        // to get the correct field ID's. They are hard-coded and depend on your option names in system.xml
        $javaScript = &quot;
            &lt;script type=\&quot;text/javascript\&quot;&gt;
                Event.observe(window, 'load', function() {
                    enabled=$('{$element-&gt;getHtmlId()}').value;
                    if (!enabled || enabled!=1) {
                        $('{$this-&gt;_getToggleRowElementId($element)}').hide();
                    } else {
                        $('{$this-&gt;_getToggleRowElementId($element)}').show();
                    }
                });
                Event.observe('{$element-&gt;getHtmlId()}', 'change', function(){
                    enabled=$('{$element-&gt;getHtmlId()}').value;
                    $('{$this-&gt;_getToggleElementId($element)}').disabled = (!enabled || enabled!=1);
                    if (!enabled || enabled!=1) {
                        $('{$this-&gt;_getToggleRowElementId($element)}').hide();
                    } else {
                        $('{$this-&gt;_getToggleRowElementId($element)}').show();
                    }
                });
            &lt;/script&gt;&quot;;

        $html .= $javaScript;
        return $html;
    }
}</pre>
<p>The <code>Varien_Data_Form_Element_Abstract</code> class implements the <code>_getElementHtml()</code> method responsible for generating the HTML for each option element. This is where we can add out override and &#8216;inject&#8217; some custom code to control the other element as well as the JavaScript to implement the dynamic toggle functionality. The code is self-explanatory.</p>
<p>Basically, we have a couple of helper methods to return our HTML field and row ID&#8217;s depending on the names we gave our options in <code>config.xml</code>. The <code>_getElementHtml()</code> method just sets the disabled state of the textarea field if the option is &#8216;No&#8217; and adds the Prototype JavaScript to add our toggle functionality. The JavaScript code will execute on page load and completely hide the text field if the option is &#8216;No&#8217; and install an event observer on the Yes/No drop-down to show/hide the text option.</p>
<p>The result of our work would look like this initially:</p>
<div id="attachment_1506" class="wp-caption aligncenter" style="width: 590px"><img class="size-full wp-image-1506" title="Toggle options - text hidden" src="http://magebase.com/wp-content/uploads/2011/09/toggle-options-2.png" alt="Toggle options - text hidden" width="580" height="145" /><p class="wp-caption-text">Toggle options - Text Hidden</p></div>
<p>Selecting &#8216;Yes&#8217;, wil toggle the next field into its visible state:</p>
<div id="attachment_1504" class="wp-caption aligncenter" style="width: 690px"><a class="zoom" href="http://magebase.com/wp-content/uploads/2011/09/toggle-options-3.png"><img class="size-large wp-image-1504 " title="Toggle options - text revealed" src="http://magebase.com/wp-content/uploads/2011/09/toggle-options-3-680x310.png" alt="Toggle options - text revealed" width="680" height="310" /></a><p class="wp-caption-text">Toggle options - text revealed</p></div>
<h2>Conclusion</h2>
<p>We&#8217;ve seen how to create a nice little usability enhancement to busy module option pages. You can take this paradigm and enhance it for your own specific purposes. You can study the other examples of the built in Magento options using a frontend_model class for more inspiration and ideas.</p>
<p>One note, the above solution will erase a text option once its saved when the toggle is set to &#8216;No&#8217;. If you&#8217;d like to preserve the option, just remove the PHP code setting the text field as disabled as well as the <code>$('{$this-&gt;_getToggleElementId($element)}').disabled = (!enabled || enabled!=1);</code> JavaScript line. That should allow the hidden option to be saved.</p>
<h3 id="update"><span style="color: #0000ff;">Update:</span></h3>
<p>The same result as above can be achieved by utilizing the &lt;depends&gt; node in the system.xml as Damián pointed out:</p>
<pre class="brush: xml; title: ; notranslate">&lt;fields&gt;
    &lt;mbcustomopt1 translate=&quot;label comment&quot;&gt;
        &lt;label&gt;Enable Additional Text&lt;/label&gt;
        &lt;frontend_type&gt;select&lt;/frontend_type&gt;
        &lt;source_model&gt;adminhtml/system_config_source_yesno&lt;/source_model&gt;
        &lt;sort_order&gt;10&lt;/sort_order&gt;
        &lt;show_in_default&gt;1&lt;/show_in_default&gt;
        &lt;show_in_website&gt;1&lt;/show_in_website&gt;
        &lt;show_in_store&gt;0&lt;/show_in_store&gt;
        &lt;comment&gt;Select whether to show a text block in the front end.&lt;/comment&gt;
    &lt;/mbcustomopt1&gt;
    &lt;mbcustomopt2 translate=&quot;label comment&quot;&gt;
        &lt;label&gt;Additional Text&lt;/label&gt;
        &lt;frontend_type&gt;textarea&lt;/frontend_type&gt;
        &lt;sort_order&gt;20&lt;/sort_order&gt;
        &lt;show_in_default&gt;1&lt;/show_in_default&gt;
        &lt;show_in_website&gt;1&lt;/show_in_website&gt;
        &lt;show_in_store&gt;0&lt;/show_in_store&gt;
        &lt;depends&gt;&lt;mbcustomopt1&gt;1&lt;/mbcustomopt1&gt;&lt;/depends&gt;
        &lt;comment&gt;Enter the content for the text block.&lt;/comment&gt;
    &lt;/mbcustomopt2&gt;
&lt;/fields&gt;
</pre>
<p>However, this article illustrates how you can potentially add custom option processing using the front end model option. This is more relevant for example if you have an option where you need to check more complex conditions or link several options together.</p>
<p>Originally published on <a href="http://magebase.com">magebase.com</a>. Copyright &copy; 2011 Magebase - All Rights Reserved.</p>]]></content:encoded>
			<wfw:commentRss>http://magebase.com/magento-tutorials/quick-tip-using-a-frontend-model-for-your-module-configuration-parameter/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>Quick Tip: Conditional Loading of JavaScript and CSS Using Your Module Configuration</title>
		<link>http://magebase.com/magento-tutorials/quick-tip-conditional-loading-of-javascript-and-css-using-your-module-configuration/</link>
		<comments>http://magebase.com/magento-tutorials/quick-tip-conditional-loading-of-javascript-and-css-using-your-module-configuration/#comments</comments>
		<pubDate>Tue, 09 Aug 2011 21:26:26 +0000</pubDate>
		<dc:creator>Robert Popovic</dc:creator>
				<category><![CDATA[Tutorials]]></category>
		<category><![CDATA[config]]></category>
		<category><![CDATA[layout]]></category>

		<guid isPermaLink="false">http://magebase.com/?p=1483</guid>
		<description><![CDATA[It's really easy to create conditional JavaScript and CSS includes for your custom modules using module configuration parameters. Read on to see how.<p>Originally published on <a href="http://magebase.com">magebase.com</a>. Copyright &copy; 2011 Magebase - All Rights Reserved.</p>]]></description>
			<content:encoded><![CDATA[<p>I don&#8217;t know about you but I often find myself removing third party module&#8217;s CSS and sometimes even JS files from loading in my custom themes because I need to change most of the styling and don&#8217;t want to add bulk to my site.</p>
<p>Traditionally, I do it using my local.xml <a href="http://magebase.com/magento-tutorials/5-useful-tricks-for-your-magento-local-xml/">as outlined in my previous article</a>. However, it would be good practice if module developers would provide the option right from their module configuration.</p>
<p>This is actually really easy to do, watch this:</p>
<p>1. Create configuration options in system.xml:</p>
<pre class="brush: xml; title: ; notranslate">
...
&lt;groups&gt;
    &lt;advanced translate=&quot;label&quot;&gt;
    &lt;label&gt;Advanced&lt;/label&gt;
    &lt;frontend_type&gt;text&lt;/frontend_type&gt;
    &lt;sort_order&gt;100&lt;/sort_order&gt;
    &lt;show_in_default&gt;1&lt;/show_in_default&gt;
    &lt;show_in_website&gt;1&lt;/show_in_website&gt;
    &lt;show_in_store&gt;0&lt;/show_in_store&gt;
    &lt;fields&gt;
        &lt;load_css translate=&quot;label comment&quot;&gt;
            &lt;label&gt;Load Stylesheet&lt;/label&gt;
            &lt;frontend_type&gt;select&lt;/frontend_type&gt;
            &lt;source_model&gt;adminhtml/system_config_source_yesno&lt;/source_model&gt;
            &lt;sort_order&gt;10&lt;/sort_order&gt;
            &lt;show_in_default&gt;1&lt;/show_in_default&gt;
            &lt;show_in_website&gt;1&lt;/show_in_website&gt;
            &lt;show_in_store&gt;0&lt;/show_in_store&gt;
            &lt;comment&gt;Set to No if the supplied stylesheet file should not be loaded.&lt;/comment&gt;
        &lt;/load_css&gt;
        &lt;load_js translate=&quot;label comment&quot;&gt;
            &lt;label&gt;Load Javascript&lt;/label&gt;
            &lt;frontend_type&gt;select&lt;/frontend_type&gt;
            &lt;source_model&gt;adminhtml/system_config_source_yesno&lt;/source_model&gt;
            &lt;sort_order&gt;20&lt;/sort_order&gt;
            &lt;show_in_default&gt;1&lt;/show_in_default&gt;
            &lt;show_in_website&gt;1&lt;/show_in_website&gt;
            &lt;show_in_store&gt;0&lt;/show_in_store&gt;
            &lt;comment&gt;Set to No if the supplied javascript file should not be loaded.&lt;/comment&gt;
        &lt;/load_js&gt;
    &lt;/fields&gt;
    &lt;/advanced&gt;
&lt;/groups&gt;
...
</pre>
<p>Here, I&#8217;m only showing the relevant part for brevity. Essentially, I have an Advanced section with two Yes/No drop downs which allow the admin to configure the desired options.</p>
<p>2. Add your conditional includes to your module&#8217;s layout XML:</p>
<pre class="brush: xml; title: ; notranslate">
        &lt;reference name=&quot;head&quot;&gt;
            &lt;action method=&quot;addCss&quot; ifconfig=&quot;my_config_section/advanced/load_css&quot;&gt;&lt;stylesheet&gt;css/my_module/my_module.css&lt;/stylesheet&gt;&lt;/action&gt;
            &lt;action method=&quot;addItem&quot; ifconfig=&quot;my_config_section/advanced/load_js&quot;&gt;&lt;type&gt;skin_js&lt;/type&gt;&lt;name&gt;js/my_module/my_module.js&lt;/name&gt;&lt;/action&gt;
        &lt;/reference&gt;
</pre>
<p>And there you have it. Your css and js will only be included if the configuration allows it.</p>
<p>Originally published on <a href="http://magebase.com">magebase.com</a>. Copyright &copy; 2011 Magebase - All Rights Reserved.</p>]]></content:encoded>
			<wfw:commentRss>http://magebase.com/magento-tutorials/quick-tip-conditional-loading-of-javascript-and-css-using-your-module-configuration/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Improving the File Cache Backend</title>
		<link>http://magebase.com/magento-tutorials/improving-the-file-cache-backend/</link>
		<comments>http://magebase.com/magento-tutorials/improving-the-file-cache-backend/#comments</comments>
		<pubDate>Mon, 01 Aug 2011 21:00:44 +0000</pubDate>
		<dc:creator>Vinai Kopp</dc:creator>
				<category><![CDATA[Extensions]]></category>
		<category><![CDATA[Tutorials]]></category>
		<category><![CDATA[cache]]></category>
		<category><![CDATA[memcached]]></category>
		<category><![CDATA[optimization]]></category>
		<category><![CDATA[performance]]></category>

		<guid isPermaLink="false">http://magebase.com/?p=1439</guid>
		<description><![CDATA[We know that we can enable the Magento cache to speed our sites up. We also know how to add APC or memcached into the mix. However, this does not always give us the expected results, so we need to understand the underlying caching mechanisms in order to improve on them.<p>Originally published on <a href="http://magebase.com">magebase.com</a>. Copyright &copy; 2011 Magebase - All Rights Reserved.</p>]]></description>
			<content:encoded><![CDATA[<p>The purpose of this post is to spread knowledge about the bolts and gears of the Magento cache system among developers, and to share one method of overcoming some limitations of the file cache storage class.</p>
<p>This article basically started with the site of a client who was having performance issues: when the cache reached about 38000 records, he was actually forced to clear the cache to keep the site responsive enough.</p>
<p>How strange is that? Shouldn’t a full cache give a better performance then an empty cache?</p>
<p>The number of records stored in the Magento cache depends on many factors, amongst others the number of store views, if a full page cache is used or not, and the size of the catalog. Many Sites don’t go above 1000 or 2000 cache records, but for large instances much higher values are common.</p>
<p><img class="alignnone size-large wp-image-1455" title="Filecount" src="http://magebase.com/wp-content/uploads/2011/08/Filecount-680x65.png" alt="" width="680" height="65" /></p>
<p>The performance issues of my client only occurred on specific pages, one of the most noticeable being the add-to cart action. Dropping a product to the cart took up to 4 seconds!<br />
Using some profiling, we could pin the issue down on part of the (full page) cache being cleared, more precisely, when the mini-cart in the page header had to be rebuilt.</p>
<p>Lets have a look at how the Magento caching (which uses the <code>Zend_Cache library</code>) works.<br />
Each cache entry consists of the following information</p>
<ul>
<li>the cached data</li>
<li>a cache key (or ID), that uniquely identifies this entry and is used to retrieve the data from the cache</li>
<li>a cache lifetime, after which the cache entry expires</li>
<li>zero or more cache tags</li>
</ul>
<p>Most of these are obvious, but what is the purpose of cache tags? Cache tags are used to segment the cache for partial deletion. For example, you could clear all entries of the configuration cache, without touching the any entries of the HTML block cache.</p>
<p>On the cache management page most of the cache tags used by Magento are listed. Depending on the modules and extensions installed there could be more or less tags, e.g. <code>CONFIG, LAYOUT_GENERAL_CACHE_TAG, BLOCK_HTML, TRANSLATIONS, FULL_PAGE_CACHE,</code> …</p>
<div id="attachment_1458" class="wp-caption alignleft" style="width: 310px"><a class="zoom" href="http://magebase.com/wp-content/uploads/2011/08/Cache-Management1.png"><img class="size-medium wp-image-1458  " title="Listed Cache Tags - more are used internaly" src="http://magebase.com/wp-content/uploads/2011/08/Cache-Management1-300x163.png" alt="Listed Cache Tags - more are used internaly" width="300" height="163" /></a><p class="wp-caption-text">Listed Cache Tags</p></div>
<p>All the information associated with the cache record is saved in the cache storage every time the method <code>Mage::app()-&gt;saveCache()</code> is called. And to read cache records the Method <code>Mage::app()-&gt;loadCache()</code> is used.<br />
Magento offers several different options what to use as a cache storage, and each of these storage systems is used by means of a PHP class called “cache backend”.</p>
<p>By default, cache data is stored in files (located in the directory <code>var/cache/</code>). Another option is the database, which is slower then the files option mostly because the database is a heavily used resource for Magento instances anyway. Then there are storage schemes that use RAM (which are much faster), e.g. <a title="APC" href="http://php.net/manual/en/apc.setup.php" target="_blank">APC</a> (shared memory) or <a title="memcached" href="http://memcached.org/" target="_blank">memcached</a> (a networked caching server).</p>
<p>So, lets use RAM as our cache storage, right?</p>
<p>Sounds good, except for one problem: APC and memcached only support storing simple key-value pairs, so the cache tags are lost! This renders the whole caching rather useless, because every time we need to clear only one part of the cache, EVERY cache entry is cleared.</p>
<p>But, do not despair! The Zend Framework contains a solution to this problem. There is a special cache backend called Twolevels. The Twolevels backend uses a fast cache backend (i.e. APC or memcached) for the cache data, and a slow backend (i.e. files or database) for the lifetime and the cache tag information. This way we can have the best of both worlds!</p>
<p>According to the excellent <a title="Magento Performance Whitepaper" href="http://www.magentocommerce.com/whitepaper" rel="external">performance whitepaper</a> (login required) Magento has released, it is recommended to use APC for the fast backend and files for the slow backend for single webserver setups. If you use a cluster of webservers, you should use memcached for the fast backend and the database for the slow backend. The latter has more overhead then the APC/files combo, but having all servers share one cache pool makes up for that.</p>
<p>Magento makes it easy to configure all this by the way &#8211; have a look at the file <code>app/etc/local.xml.additional</code> for further information. I will not go deeper into the setup here because <a href="http://magebase.com/magento-tutorials/speeding-up-magento-with-apc-or-memcached/">we have already written about this</a>.</p>
<p>Now, back to the problem at hand &#8211; why is a nice, full, cache slower then an empty one?<br />
The site in question was using APC as the fast backend and files as the slow backend.</p>
<p>So, lets have a look at what is happening.<br />
Every time a product is added to the cart, the following method is called:</p>
<pre class="brush: php; title: ; notranslate">Mage::app()-&gt;getCache()-&gt;clean(
    Zend_Cache::CLEANING_MODE_MATCHING_ANY_TAG,
    array($cacheTag)
);</pre>
<p><code>$cacheTag</code> is an MD5 hash built from several parameters identifying the active customers mini-cart block cache.<br />
So, how do the twolevel and the file cache backends handle this?</p>
<p>In the method <code>Zend_Cache_Backend_TwoLevels::clean()</code> each request with the cleaning mode <code>CLEANING_MODE_MATCHING_ANY_TAG</code> fetches all cache IDs matching the given tags from the slow backend using the method <code>getIdsMatchingAnyTags()</code>, and then removes one cache entry after the other in a loop.</p>
<pre class="brush: php; title: ; notranslate">case Zend_Cache::CLEANING_MODE_MATCHING_ANY_TAG:
    $ids = $this-&gt;_slowBackend-&gt;getIdsMatchingAnyTags($tags);
    $res = true;
    foreach ($ids as $id) {
        $bool = $this-&gt;remove($id);
        $res = $res &amp;&amp; $bool;
    }
    return $res;
    break;</pre>
<p>Lets dive in a little bit deeper and find out how the <code>Zend_Cache_Backend_File</code> backend finds those cache IDs.<br />
The interesting part happens in the method <code>_get()</code>. Here we can see a list of all cache entries is built, and then it loops over each one, reads in the corresponding meta data file (using <code>file_get_contents()</code> and <code>unserialize()</code>) and then checks if the cache entry is associated with a matching cache tag.</p>
<p>This following code is slightly simplified for educational purposes:</p>
<pre class="brush: php; title: ; notranslate">$result = array();
$glob = @glob($cacheDir . $prefix . '--*');
if ($glob !== false) {
    foreach ($glob as $file) {
        $fileName = basename($file);
        $id = $this-&gt;_fileNameToId($fileName);
        $metadatas = $this-&gt;_getMetadatas($id);
        …
       switch ($mode) {
           …
           case 'matchingAny':
               $matching = false;
               foreach ($tags as $tag) {
                   if (in_array($tag, $metadatas['tags'])) {
                       $result[] = $id;
                       break;
                   }
               }
               break;
           …
       }
    }
}</pre>
<p>This code is probably fine for a couple of hundred cache entries, but after not even a day my clients Magento instance reached 40k records. Opening and unserializing thousands of files takes some time, even on a strong machine.</p>
<p><strong>It turns out the file backend doesn’t scale well.</strong></p>
<p>The remedy to this is obviously some kind of index, mapping the tags to the matching cache IDs.<br />
Instead of writing that information into a file that would have to be parsed and updated, I decided to use the filesystem itself as the index utilizing directories and symlinks.</p>
<p>In the modified file cache backend developed for the client, every time a cache entry is written, a directory with the name of each tag is created and a symlink to the metadata file is placed into it. This gives a little more overhead during the write operation. There is no difference reading cache entries. But every operation matching some tags is a lot faster. And since Magento makes heavy use of cache tags, the effect is quite noticeable, depending on the number of records in the cache.  For example, adding a product to the cart now takes less then a second on the original instance. And I’m happy to say the reports of the friends who have been nice enough to test the extension have been positive for smaller sites also.</p>
<p><a name="benchmark"></a><strong>Benchmarks!</strong></p>
<p>Inspired by Marc Jakubowski&#8217;s comment below, I added a little benchmark script. Here are some results to give a more detailed idea.<br />
<strong>UPDATE:</strong> Thanks to Collin Mollenhour&#8217;s comment below, I also added benchmarks for Redis using his <a title="Zend_Cache_Backend_Redis on github" href="https://github.com/colinmollenhour/Zend_Cache_Backend_Redis" target="_blank">Zend Cache Backend</a> Class &#8211; it&#8217;s incredibly fast, so if you have the possibility to use <a title="Redis" href="http://redis.io/" target="_blank">Redis 2.4</a> or newer, go for it! For this test I used the default Redis configuration, with the server running on the same machine I was running the tests. Before using it in production I would like to write some unit tests for this new backend, but it seems to work okay.</p>
<table>
<tbody>
<tr>
<th>Records</th>
<th>Tags</th>
<th>Avg. Records / Tag</th>
<th>Cache Backend</th>
<th>Avg. Time for getIdsMatchingTags()</th>
</tr>
<tr>
<td>50000</td>
<td>250</td>
<td>~700</td>
<td>File</td>
<td>20.71s</td>
</tr>
<tr>
<td>50000</td>
<td>250</td>
<td>~700</td>
<td>Symlink</td>
<td>2.28s</td>
</tr>
<tr>
<td>50000</td>
<td>250</td>
<td>~1500</td>
<td>Redis</td>
<td>0.01s</td>
</tr>
<tr>
<td>6000</td>
<td>120</td>
<td>~175</td>
<td>File</td>
<td>2.41s</td>
</tr>
<tr>
<td>6000</td>
<td>120</td>
<td>~175</td>
<td>Symlink</td>
<td>0.23s</td>
</tr>
<tr>
<td>6000</td>
<td>120</td>
<td>~370</td>
<td>Redis</td>
<td>0.002s</td>
</tr>
<tr>
<td>2000</td>
<td>80</td>
<td>~88</td>
<td>File</td>
<td>0.78s</td>
</tr>
<tr>
<td>2000</td>
<td>80</td>
<td>~88</td>
<td>Symlink</td>
<td>0.08s</td>
</tr>
<tr>
<td>2000</td>
<td>80</td>
<td>~180</td>
<td>Redis</td>
<td>0.001s</td>
</tr>
</tbody>
</table>
<p>The numbers for the records and tags where chosen because they roughly correspond the average cache pool size and tags on several live Magento instances of different sizes. These benchmarks where run on my laptop, and obviously the results may be different depending on the drive, file system, system memory etc. Please go ahead and test on your system.<br />
One interesting thing about the Redis backend is that the average number of ID&#8217;s per tag is much higher then with the other backends. I&#8217;m not sure why, my guess is that it has something to do with the way Redis manages the tag hash tables. I don&#8217;t have time to check it out at the moment, but maybe Collin already knows why.</p>
<p>By the way, according to the PHP reference, the <a title="PHP symlink function" href="http://php.net/manual/en/function.symlink.php" target="_blank">symlink function</a> is no longer limited to Unix systems, but since PHP 5.3 it is also available under Windows (Vista, Server 2008 or greater).  I haven’t tested this, though.</p>
<p>This module is provided with no warranty, you use it at your own risk. I know it is being used successfully on several sites, both as a primary cache backend and as a slow backend in combination with APC or memcached.<br />
I invite you to have a look at it and try it out, but please start with a test instance and not your live store. You can download the module from <a title="Netzarbeiter Cache on Magento Connect" href="http://www.magentocommerce.com/magento-connect/vinai/extension/7416/netzarbeiter_cache" rel="external">Magento Connect</a> or from <a title="Netzarbeiter Cache on github" href="https://github.com/Vinai/Symlink-Cache" rel="external">github</a>.<br />
If you find bugs or have improvements, please send them in.</p>
<p>After installing the extension clear the config and block_html cache and visit System &gt; Tools &gt; Symlink Cache.</p>
<p><a class="zoom" href="http://magebase.com/wp-content/uploads/2011/08/Symlink-Cache-Page.png"><img class="alignright size-medium wp-image-1467" title="Symlink-Cache Utility Page" src="http://magebase.com/wp-content/uploads/2011/08/Symlink-Cache-Page-300x282.png" alt="Symlink-Cache Utility Page" width="300" height="282" /></a><br />
There you can see sample XML that you will have to add to your <code>app/code/local.xml</code> file for both variants, to use it on its own or to use it as a slow backend.<br />
Then, after you have updated the <code>local.xml</code> file, clear the config cache, go to the Symlink Cache page and hit the “Initialize Tag Symlinks” button.<br />
And that is all, your system is set up and uses the tag symlinks. Enjoy!<br />
I would be happy to hear about other methods, ideas and experiences about improving cache performance.</p>
<h2>Downloads</h2>
<p class="download"><a title="Netzarbeiter Cache on Magento Connect" href="http://www.magentocommerce.com/magento-connect/vinai/extension/7416/netzarbeiter_cache" rel="external">Magento Connect</a></p>
<p>or</p>
<p class="download"><a title="Netzarbeiter Cache on github" href="https://github.com/Vinai/Symlink-Cache" rel="external">Github</a></p>
<p>Originally published on <a href="http://magebase.com">magebase.com</a>. Copyright &copy; 2011 Magebase - All Rights Reserved.</p>]]></content:encoded>
			<wfw:commentRss>http://magebase.com/magento-tutorials/improving-the-file-cache-backend/feed/</wfw:commentRss>
		<slash:comments>123</slash:comments>
		</item>
		<item>
		<title>Google Optimizer on Magento: Where to start for maximum gain</title>
		<link>http://magebase.com/magento-tutorials/google-optimizer-on-magento-where-to-start-for-maximum-gain/</link>
		<comments>http://magebase.com/magento-tutorials/google-optimizer-on-magento-where-to-start-for-maximum-gain/#comments</comments>
		<pubDate>Mon, 01 Aug 2011 02:23:05 +0000</pubDate>
		<dc:creator>Mark Hammersley</dc:creator>
				<category><![CDATA[Tutorials]]></category>
		<category><![CDATA[analytics]]></category>
		<category><![CDATA[google optimizer]]></category>
		<category><![CDATA[Magento]]></category>
		<category><![CDATA[optimization]]></category>

		<guid isPermaLink="false">http://magebase.com/?p=1423</guid>
		<description><![CDATA[Magento has Google Optimizer tools built in and so it makes sense to use them.  Google Optimizer allows you to present different content options to your prospective customers and then tracks which version converts more.  On top of this Google Optimizer has built in probability formulae that understand when a result is a ‘confident result’ [...]<p>Originally published on <a href="http://magebase.com">magebase.com</a>. Copyright &copy; 2011 Magebase - All Rights Reserved.</p>]]></description>
			<content:encoded><![CDATA[<p>Magento has Google Optimizer tools built in and so it makes sense to use them.  Google Optimizer allows you to present different content options to your prospective customers and then tracks which version converts more.  On top of this Google Optimizer has built in probability formulae that understand when a result is a ‘confident result’ rather than a random occurrence.</p>
<p>To get a confident result you need to either have a test that is really obviously better or a decent number of transactions.  But as a rule of thumb if you are getting more than 10 transactions a day then you can benefit from using Google Optimizer.</p>
<h2>Where to start?</h2>
<p>If you have a lower number of transactions it makes sense to start optimizing on the pages that most people see.  This tends to be the home and checkout pages of the site. However we need not guess the best place to start when we have good data available to tell us exactly.</p>
<p>We can find the best place to start by looking at Google Analytics.  Google Analytics should be setup using Ecommerce mode and to be tracking conversions, which is a standard part of Magento as long as you have entered the Google ID in the Google API area of Magento’s configuration settings.</p>
<p>In Google Analytics go to ‘content’</p>
<p><img class="alignleft size-full wp-image-224" title="go1" src="http://www.browsertobuyer.com/wp-content/uploads/2011/08/go1.png" alt="" width="229" height="108" /></p>
<p class="clear">Then top content</p>
<p><img class="alignleft size-full wp-image-225" title="go2" src="http://www.browsertobuyer.com/wp-content/uploads/2011/08/go2.png" alt="" width="217" height="182" /></p>
<p>Then set the time line for Google Analytics to show a decent length of time.  I am using 6 months in my example – just use as much data as you have since the site has been stable and not changed.</p>
<p>On the top content screen find the right most column called $ index – the $ index is the average value for a page that a user visited before completing an Ecommerce transaction.  Ordering by the $ index will give you the most valuable pages on your site.  However you also need to click on ‘weighted sort’ to give you not only the most valuable pages but the most relevant valuable pages.  Without weighted sort you are only going to see the pages that randomly got high values because an odd buyer used them to make a big purchase.  By using weighted sort we can filter out these anomalies.</p>
<p><img class="size-full wp-image-226 alignnone" title="go3" src="http://www.browsertobuyer.com/wp-content/uploads/2011/08/go3.png" alt="" width="582" height="88" /></p>
<p>On the site I am looking at for this example this gives me the following pages</p>
<p><img class="alignleft size-full wp-image-227" title="go4" src="http://www.browsertobuyer.com/wp-content/uploads/2011/08/go4.png" alt="" width="375" height="216" /></p>
<p>As you can see these are all checkout pages which are NOT part of the inbuilt Google Optimizer set of tools that Magento supplies.  Whilst I have personally run split tests here, its tricky and not something I can easily show you.  However you can optimise these pages by creating a ‘goal’ funnel and looking at the profile, but I want to cover that in another blog post.</p>
<p>So what I am going to do is to scroll through the list until I find one of the following pages that is built into Magento to Google Optimizer test</p>
<ul class="clear">
<li>Product page</li>
<li>CMS page – (this could be a Google Adwords landing page and in many of my sites these are the best pages to test as they drive a significant proportion of my revenue)</li>
<li>Category page</li>
<li>Home page</li>
</ul>
<p>In my example site the first page I find is not the home page as I would have expected but instead a product page.  It just goes to show how important it is to look at the stats before deciding where to test.</p>
<p>The product I can use to test is worth $102 and thus a decent sale for the site and must have a fair number of transactions to rank this highly.  So this is where I would start.</p>
<p>I am not going to go through how to actually setup the experiment as there are plenty of good blog tutorials available – just Google “Google Optimizer for Magento” – but I wanted to show you where to test first as this will actually allow you to make the most important changes to your site first.</p>
<p>Originally published on <a href="http://magebase.com">magebase.com</a>. Copyright &copy; 2011 Magebase - All Rights Reserved.</p>]]></content:encoded>
			<wfw:commentRss>http://magebase.com/magento-tutorials/google-optimizer-on-magento-where-to-start-for-maximum-gain/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Creating Custom Layout Handles</title>
		<link>http://magebase.com/magento-tutorials/creating-custom-layout-handles/</link>
		<comments>http://magebase.com/magento-tutorials/creating-custom-layout-handles/#comments</comments>
		<pubDate>Mon, 11 Jul 2011 09:33:10 +0000</pubDate>
		<dc:creator>Paryank Kansara</dc:creator>
				<category><![CDATA[Tutorials]]></category>
		<category><![CDATA[attribute set]]></category>
		<category><![CDATA[design]]></category>
		<category><![CDATA[layout]]></category>
		<category><![CDATA[product page]]></category>
		<category><![CDATA[template]]></category>

		<guid isPermaLink="false">http://magebase.com/?p=1402</guid>
		<description><![CDATA[In this tutorial we will explore our journey through Magento's layout XML further by showing how we can easily create our own custom layout handles to target specific conditions and scenarios.<p>Originally published on <a href="http://magebase.com">magebase.com</a>. Copyright &copy; 2011 Magebase - All Rights Reserved.</p>]]></description>
			<content:encoded><![CDATA[<p>As discussed in <a href="http://magebase.com/magento-tutorials/demystifying-magentos-layout-xml-part-1/">previous articles about Magento&#8217;s Layout XML</a>, <a href="http://magebase.com/magento-tutorials/digging-deeper-into-magentos-layout-xml-part-2/">Layout Handles</a> in Magento&#8217;s layout XML are XML nodes which contain the definition of updates in page layouts. There are some built in Layout Handles which are called implicitly in Magento. For example, <code>default</code> handle is called for every page, <code>PRODUCT_TYPE_configurable</code> is called for the configurable product detail page, <code>customer_logged_in</code> is called if a customer is logged in, etc.</p>
<p>But what if we want to add a custom set of layout updates for our own condition? For example, if we wanted our product pages to be different depending on its attribute set. Magento already provides layout handles for each product type. It also provides a layout handle <code>PRODUCT_[product_id]</code> where <code>[product_id]</code> is replaced by the product’s ID in the database. Using this layout handle, we can easily define a layout update for a specific product. But in our case, we want to define a layout handle for all products with a particular attribute set. In this case, it is not practical to define <code>PRODUCT_[product_id]</code> handles for each product in that attribute set, because new products added in that attribute set will not have the same design update and we would have to keep adding additional handles.</p>
<p>So ideally, we need a way to define a layout handle for attribute sets. Something like the following:</p>
<pre class="brush: xml; title: ; notranslate">
&lt;PRODUCT_ATTRIBUTE_SET_shirts&gt;
    &lt;reference name=&quot;product.info&quot;&gt;
      &lt;action method=&quot;setTemplate&quot;&gt;&lt;template&gt;my/custom/product/view.phtml&lt;/template&gt;&lt;/action&gt;
    &lt;/reference&gt;
&lt;/PRODUCT_ATTRIBUTE_SET_shirts&gt;
</pre>
<p>Fortunately, Magento’s layout engine is flexible enough to provide a way to define our own layout handles and call them explicitly through custom extensions. In the example of the case we discussed above, we will see how to create our own layout handles.</p>
<p>As described in our previous tutorials on Layout XML, after the layout XML is loaded, Magento applies the default handle, store handle, theme handle and then action handle. At the very end, layout updates from the database are applied.</p>
<p>For the product page, two additional layout handles: <code>PRODUCT_TYPE_[type_id]</code> and <code>PRODUCT_[product_id]</code> are applied after the action handle and before the layout updates from the database. In our case, we need to create and apply one more additional handle so that we can target our attribute set, namely: <code>PRODUCT_ATTRIBUTE_SET_[attribute_set]</code>.</p>
<p>To accomplish this, we will use the event observer approach. This will keep our customization clean and not interfere with other extension.</p>
<p>Magento fires an event <code>controller_action_layout_load_before</code> before applying layout updates from the database. We can add a method observing this event in our extension which will add our attribute specific layout handle.</p>
<p>So, we have to follow the steps described below:</p>
<ol>
<li>Create an extension which observes the event: <code>controller_action_layout_load_before</code> and calls a method to add our custom layout handle.</li>
<li>In the observer method, we will check if it is a product page and if not stop the execution or go to step 3.</li>
<li>We&#8217;ll fetch the current product’s attribute set name.</li>
<li>For the attribute set name, Magento allows characters like space, comma, period, etc. which are not valid as XML tag names. Since the layout handle is also an XML tag, we need to convert it to a XML tag compatible name. In short we need to remove all invalid characters from the attribute set name and replace them with underscores (‘_’).</li>
<li>Finally, we add the new layout handle <code>PRODUCT_ATTRIBUTE_SET_[attribute_set_nicename]</code> where <code>[attribute_set_nicename]</code> is the attribute set name which is converted to a XML tag compatible format.</li>
</ol>
<p>We will give our extension the name: <code>Magebase_AttributeSetHandle</code>. First, we will create <code>app/etc/modules/Magebase_AttributeSetHandle.xml</code></p>
<pre class="brush: xml; title: ; notranslate">
&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
&lt;config&gt;
    &lt;modules&gt;
        &lt;Magebase_AttributeSetHandle&gt;
            &lt;active&gt;true&lt;/active&gt;
            &lt;codePool&gt;local&lt;/codePool&gt;
        &lt;/Magebase_AttributeSetHandle&gt;
    &lt;/modules&gt;
&lt;/config&gt;
</pre>
<p>And, <code>app/code/local/Magebase/AttributeSetHandle/etc/config.xml</code></p>
<pre class="brush: xml; title: ; notranslate">
&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
&lt;config&gt;
    &lt;modules&gt;
        &lt;Magebase_AttributeSetHandle&gt;
            &lt;version&gt;0.1.0&lt;/version&gt;
        &lt;/Magebase_AttributeSetHandle&gt;
    &lt;/modules&gt;
    &lt;global&gt;
        &lt;events&gt;
            &lt;controller_action_layout_load_before&gt;
                &lt;observers&gt;
                    &lt;attributesethandle&gt;
                        &lt;class&gt;Magebase_AttributeSetHandle_Model_Observer&lt;/class&gt;
                        &lt;method&gt;addAttributeSetHandle&lt;/method&gt;
                    &lt;/attributesethandle&gt;
                &lt;/observers&gt;
            &lt;/controller_action_layout_load_before&gt;
        &lt;/events&gt;
    &lt;/global&gt;
&lt;/config&gt;
</pre>
<p>Here, in <code>config.xml</code> we declare an observer method for the <code>controller_action_layout_load_before</code> event as <code>Magebase_AttributeSetHandle_Model_Observer::addAttributeSetHandle()</code>.</p>
<p>Now, we will create a class: <code>Magebase_AttributeSetHandle_Model_Observer</code> and a method: <code>addAttributeSetHandle()</code> in <code>app/code/local/Magebse/AttributeSetHandle/Model/Observer.php</code>.</p>
<pre class="brush: php; title: ; notranslate">
&lt;?php
class Magebase_AttributeSetHandle_Model_Observer
{
    /**
     * Converts attribute set name of current product to nice name ([a-z0-9_]+).
     * Adds layout handle PRODUCT_ATTRIBUTE_SET_&lt;attribute_set_nicename&gt; after
     * PRODUCT_TYPE_&lt;product_type_id&gt; handle
     *
     * Event: controller_action_layout_load_before
     *
     * @param Varien_Event_Observer $observer
     */
    public function addAttributeSetHandle(Varien_Event_Observer $observer)
    {
        $product = Mage::registry('current_product');

        /**
         * Return if it is not product page
         */
        if (!($product instanceof Mage_Catalog_Model_Product)) {
            return;
        }

        $attributeSet = Mage::getModel('eav/entity_attribute_set')-&gt;load($product-&gt;getAttributeSetId());
        /**
         * Convert attribute set name to alphanumeric + underscore string
         */
        $niceName = str_replace('-', '_', $product-&gt;formatUrlKey($attributeSet-&gt;getAttributeSetName()));

        /* @var $update Mage_Core_Model_Layout_Update */
        $update = $observer-&gt;getEvent()-&gt;getLayout()-&gt;getUpdate();
        $update-&gt;addHandle('PRODUCT_ATTRIBUTE_SET_' . $niceName);
    }
}
</pre>
<p>Here, to convert the attribute set name to a XML tag compatible name, we have called:</p>
<pre class="brush: php; title: ; notranslate">
$niceName = str_replace('-', '_', $product-&gt;formatUrlKey($attributeSet-&gt;getAttributeSetName()));
</pre>
<p>This is because, <code>formatUrlKey()</code> in the product class, replaces all non-alphanumeric characters to ‘-’. But ‘-’ is not valid in XML tag name, so we are replacing it with ‘_’.</p>
<p>After that we add our handle for the attribute set. However, there is one shortfall to our observer approach.</p>
<p>On the product page, after the action handle is applied, the product type and product id handles are applied immediately before the <code>controller_action_layout_load_before</code> event is fired. This means that our attribute set handle is applied <span style="text-decoration: underline;">after</span> the product id handle, which is not ideal.</p>
<p>The reason is that if we use both the product id handle and product attribute set handle in our custom layout modifications, then the attribute set handle will override the product id handle updates. This is not a practical because the product id handle should always be applied after the attribute set handle since it is specific to a product. Our handle hierarchy should be:</p>
<p><code>PRODUCT_TYPE_[type] =&gt; PRODUCT_ATTRIBUTE_SET_[attribute_set_nicename] =&gt; PRODUCT_ID_[id]</code></p>
<p>Unfortunately, there is no event fired between the handles applied for product type and product id so, we have to rearrange the layout handles in our observer method. So our method would be as below:</p>
<pre class="brush: php; title: ; notranslate">
&lt;?php
class Magebase_AttributeSetHandle_Model_Observer
{
    /**
     * Converts attribute set name of current product to nice name ([a-z0-9_]+).
     * Adds layout handle PRODUCT_ATTRIBUTE_SET_&lt;attribute_set_nicename&gt; after
     * PRODUCT_TYPE_&lt;product_type_id&gt; handle
     *
     * Event: controller_action_layout_load_before
     *
     * @param Varien_Event_Observer $observer
     */
    public function addAttributeSetHandle(Varien_Event_Observer $observer)
    {
        $product = Mage::registry('current_product');

        /**
         * Return if it is not product page
         */
        if (!($product instanceof Mage_Catalog_Model_Product)) {
            return;
        }

        $attributeSet = Mage::getModel('eav/entity_attribute_set')-&gt;load($product-&gt;getAttributeSetId());
        /**
         * Convert attribute set name to alphanumeric + underscore string
         */
        $niceName = str_replace('-', '_', $product-&gt;formatUrlKey($attributeSet-&gt;getAttributeSetName()));

        /* @var $update Mage_Core_Model_Layout_Update */
        $update = $observer-&gt;getEvent()-&gt;getLayout()-&gt;getUpdate();
        $handles = $update-&gt;getHandles(); // Store all handles in a variable
        $update-&gt;resetHandles(); // Remove all handles

        /**
         * Rearrange layout handles to ensure PRODUCT_&lt;product_id&gt;
         * handle is added last
         */
        foreach ($handles as $handle) {
            $update-&gt;addHandle($handle);
            if ($handle == 'PRODUCT_TYPE_' . $product-&gt;getTypeId()) {
                $update-&gt;addHandle('PRODUCT_ATTRIBUTE_SET_' . $niceName);
            }
        }
    }
}
</pre>
<p>Here, we have stored all added layout handles in an array variable, then reset the updates. So now layout update instance has no layout handle. Then we iterate over all the handles we have stored and add them one by one again except when we find the product type handle, we add our attribute set handle immediately after that. This way, the attribute set handle is added exactly where we want it.</p>
<h2>Conclusion</h2>
<p>In this tutorial, we saw how we can add custom layout handles if we need to by observing the <code>controller_action_layout_load_before</code> event. In our example, we added a handle that allows us to create specific layouts for product pages that show products with a specific attribute set. Similarly, we could implement a custom layout handle based on some other attribute value or condition.</p>
<p>Let us know if you discover some more interesting scenarios with your own custom layout handles.</p>
<p>Originally published on <a href="http://magebase.com">magebase.com</a>. Copyright &copy; 2011 Magebase - All Rights Reserved.</p>]]></content:encoded>
			<wfw:commentRss>http://magebase.com/magento-tutorials/creating-custom-layout-handles/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Customizing the Magento Error Report and Maintenance Page</title>
		<link>http://magebase.com/magento-tutorials/customizing-the-magento-error-report-and-maintenance-page/</link>
		<comments>http://magebase.com/magento-tutorials/customizing-the-magento-error-report-and-maintenance-page/#comments</comments>
		<pubDate>Mon, 04 Jul 2011 06:50:17 +0000</pubDate>
		<dc:creator>Robert Popovic</dc:creator>
				<category><![CDATA[Tutorials]]></category>
		<category><![CDATA[custom error report]]></category>
		<category><![CDATA[error]]></category>
		<category><![CDATA[Maintenance]]></category>

		<guid isPermaLink="false">http://magebase.com/?p=1376</guid>
		<description><![CDATA[In this Magento tutorial we will build upon one of our earlier tutorials and show you how you can easily customize the default maintenance and error pages that are shown when the site is in maintenance mode or encounters an error. All you need is an understanding of the error processing and some HTML/CSS skills.<p>Originally published on <a href="http://magebase.com">magebase.com</a>. Copyright &copy; 2011 Magebase - All Rights Reserved.</p>]]></description>
			<content:encoded><![CDATA[<p><img class="alignright size-medium wp-image-1378" title="magento-error-page" src="http://magebase.com/wp-content/uploads/2011/07/magento-error-page-300x199.png" alt="magento-error-page" width="300" height="199" />In this tutorial, we will expand on the material <a href="../magento-tutorials/customising-magentos-error-messages/">Kristof already covered a while ago</a> since there are some neat additional options available to us.</p>
<p>If you&#8217;ve worked with Magento for any length of time, you will most certainly be familiar with the dreaded &#8220;There has been an error processing your request&#8221; page. Clearly, the goal is to make sure that this page never appears to our online customers on a live site, but, on occasion it may still show up. For example if you&#8217;ve just sent out a newsletter and have an onslaught of visits, if your server runs out of MySQL connections, your visitors will still see this page.</p>
<p>Similarly, Magento provides an easy way to show a maintenance page. All you have to do is create an empty file called maintenance.flag in your Magento document root and your site will be redirected to the built in maintenance page.</p>
<p>This is all well but as part of a professional solution for your clients, we would like to be able to customize these pages so that they are more in line with the design of the site. Luckily, it is very easy to customize these templates. The principle is very similar to customizing a standard Magento skin folders, so, let&#8217;s dig into it.</p>
<p class="note">Note that the Magento version used for this tutorial is 1.5.</p>
<h2>1. Structure of the Error Pages</h2>
<p><img class="alignright size-full wp-image-1377" title="magento-error-folder" src="http://magebase.com/wp-content/uploads/2011/07/magento-error-folder.png" alt="magento-error-folder" width="230" height="432" />The error report and maintenance pages are rendered from template located under <code>[MAGENTO_ROOT]/errors</code>. As you can see from the screenshot, the folder contains some php files and a folder called default that reminds us of the way the normal Magento skin folders are structured. You will notice that the skin folder also contains files with the same name as the error root folder. The difference between them is that the files in the error root are just there to route the specific page processing. They include the <code>processor.php</code> file, instantiate the report class and call the appropriate method which in turn will render the actual page template. For example, the <code>503.php</code> file has these three lines:</p>
<pre>require_once 'processor.php';

$processor = new Error_Processor();
$processor-&gt;process503();</pre>
<p>The actual page HTML will be in the phtml files under the default skin folder.</p>
<p>So let&#8217;s examine the various files of interest here.</p>
<p>In the error folder:</p>
<h3>local.xml.sample</h3>
<p>The good guys from the Magento dev team have provided us with a sample configuration file that we can use to create our specific configuration to customize our error/maintenance pages. We will look into this file in a moment and create our <code>local.xml</code> file once we decide what we want to achieve.</p>
<h3>processor.php</h3>
<p>This file is the &#8220;engine&#8221; that contains all the rendering logic. It implements the <code>Error_Processing</code> class that reads the error template configuration from the <code>local.xml</code> file, loads the configured design and runs the configured design.</p>
<h3>404.php, 503.php, report.php</h3>
<p>These are the &#8220;routing&#8221; pages that just invoke the appropriate methods in the <code>Error_Processor</code> class.</p>
<p>The default design folder:</p>
<h3>page.phtml</h3>
<p>This is the master template file that contains the HTML for all the pages that are handled by the error sub-system. This page will include one of the phtml files listed below. Since this page contains the header and footer you&#8217;d clearly want to modify it to implement your own branded design.</p>
<h3>404.phtml</h3>
<p>This is a 404 Not Found page template. I haven&#8217;t seen that one appear on a Magento site since there is already a 404 CMS page built into Magento. However, this page may be useful if you want to change the default 404 handling and direct all 404s to this template. For our purposes, we will ignore this template.</p>
<h3>503.phtml</h3>
<p>This is the &#8220;Temporarily Unavailable&#8221; page that also dubs as the maintenance page shown when the site is in maintenance mode. For example, when you are performing upgrades from Magento Connect or manually put the <code>maintenance.flag</code> file up.</p>
<p>We&#8217;ll definitely want to customize this page.</p>
<h3>report.phtml</h3>
<p>This page contains the HTML and PHP code that renders the error report page shown above. It&#8217;s certainly another candidate for our customization.</p>
<h3>images and css folders</h3>
<p>These folders contain the skin CSS and images used by the error/maintenance templates.</p>
<h2>2. The local.xml File</h2>
<p>Before we dive into customizing the phtml, we should realize that, like with the standard Magento design templates, a similar paradigm is also in effect here. In other words, we don&#8217;t want to &#8220;hack&#8221; the files in the default design, but create our own error design and customize the files there. For this, we will need to create a <code>local.xml</code> file with the appropriate configuration. Opening the supplied sample XML file, we see:</p>
<pre class="brush: xml; title: ; notranslate">
&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
&lt;config&gt;
    &lt;skin&gt;default&lt;/skin&gt;
    &lt;report&gt;
        &lt;!--
            &quot;action&quot; can be set to &quot;print&quot; to show exception on screen and &quot;email&quot;
            to send exception on specified email
        --&gt;
        &lt;action&gt;print&lt;/action&gt;
        &lt;!--
            in &quot;subject&quot; you can set subject of email
        --&gt;
        &lt;subject&gt;Store Debug Information&lt;/subject&gt;
        &lt;!--
            &quot;email_address&quot; admin email address
        --&gt;
        &lt;email_address&gt;&lt;/email_address&gt;
        &lt;!--
            &quot;trash&quot; is handle about trace info
            value &quot;leave&quot; is for store on disk
            value &quot;delete&quot; is for cleaning
        --&gt;
        &lt;trash&gt;leave&lt;/trash&gt;
    &lt;/report&gt;
&lt;/config&gt;
</pre>
<p>The comments in the file are pretty clear but we&#8217;ll quickly explain the various elements.</p>
<p><code>&lt;skin&gt;</code> &#8211; this is the element describing which skin folder the error processor should use. So, to create our own skin, we will change &#8220;default&#8221; to our own custom skin folder, for example:</p>
<pre class="brush: xml; title: ; notranslate">&lt;skin&gt;magebase&lt;/skin&gt;</pre>
<p><code>&lt;action&gt;</code> &#8211; is an element that governs what will happen when an error is reported. The values are:</p>
<p>- <code>blank</code>: This is the default value and means that the error report will not be shown on the page but saved in the report file under var/report/</p>
<p>- <code>print</code>: If you want to show the full exception report on the error page, this is the value to use.</p>
<p>- <code>email</code>: You may want the error report page to display an error report form that your customers can fill out when they encounter an error on your site (perhaps to explain the steps they took before the error). This setting will do just that. Note that error report emails will be sent regardless whether the customer fills out the form or not.</p>
<p>The following two elements allow you to set a default email recipient and subject and are relevant only if you set the action to &#8220;email&#8221; and are self-explanatory. Note that Magento will append the error report number to the subject line automatically.</p>
<p><code>&lt;trash&gt;</code> is the final element and allows you to specify what you want to happen with the error report files dumped in <code>var/report/</code>. Again, the comments are self-explanatory.</p>
<p>So, we will settle for the following <code>local.xml</code> content:</p>
<pre class="brush: xml; title: ; notranslate">
&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
&lt;config&gt;
    &lt;skin&gt;magebase&lt;/skin&gt;
    &lt;report&gt;
        &lt;action&gt;email&lt;/action&gt;
        &lt;subject&gt;XYZ Store Debug Information&lt;/subject&gt;
        &lt;email_address&gt;someone@example.com&lt;/email_address&gt;
        &lt;trash&gt;leave&lt;/trash&gt;
    &lt;/report&gt;
&lt;/config&gt;
</pre>
<p>In other words, we&#8217;ll create a &#8220;magebase&#8221; skin, we want our customers to be able to submit error reports to us and also leave the report files on the server. If the customer sends a report, our email will have the subject line: &#8220;XYZ Store Debug Information [error-number]&#8221; and it will be sent to the specified email address (do change that on your own site).</p>
<h2>3. Creating a Custom Skin</h2>
<p>That&#8217;s easy, just create a new sub-folder under <code>errors/</code> and copy the files and folders from the <code>errors/default/</code> skin there. Done!</p>
<p>Of course, if you this won&#8217;t show any changes in the design but, the error page would now look like this:</p>
<p><img class="alignnone size-large wp-image-1382" title="magento-error-with-report-form" src="http://magebase.com/wp-content/uploads/2011/07/magento-error-with-report-form-680x472.png" alt="magento-error-with-report-form" width="680" height="472" /></p>
<p>Now, the task is to customize our design.</p>
<h2>4. Customizing the Skin</h2>
<p>We mentioned above that the main HTML for these pages comes from <code>page.phtml</code> containing the following code:</p>
<pre class="brush: xml; title: ; notranslate">
&lt;!DOCTYPE html PUBLIC &quot;-//W3C//DTD XHTML 1.0 Strict//EN&quot; &quot;http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd&quot;&gt;
&lt;html xmlns=&quot;http://www.w3.org/1999/xhtml&quot; xml:lang=&quot;en&quot; lang=&quot;en&quot;&gt;
&lt;head&gt;
&lt;title&gt;&lt;?php echo $this-&gt;pageTitle?&gt;&lt;/title&gt;
&lt;base href=&quot;&lt;?php echo $this-&gt;getSkinUrl()?&gt;&quot; /&gt;
&lt;meta http-equiv=&quot;Content-Type&quot; content=&quot;text/html; charset=utf-8&quot; /&gt;
&lt;meta name=&quot;description&quot; content=&quot;&quot; /&gt;
&lt;meta name=&quot;keywords&quot; content=&quot;&quot; /&gt;
&lt;meta name=&quot;robots&quot; content=&quot;*&quot; /&gt;
&lt;link rel=&quot;stylesheet&quot; href=&quot;css/styles.css&quot; type=&quot;text/css&quot; /&gt;
&lt;link rel=&quot;icon&quot; href=&quot;images/favicon.ico&quot; type=&quot;image/x-icon&quot; /&gt;
&lt;link rel=&quot;shortcut icon&quot; href=&quot;images/favicon.ico&quot; type=&quot;image/x-icon&quot; /&gt;
&lt;/head&gt;
&lt;body&gt;
    &lt;div class=&quot;wrapper&quot;&gt;
        &lt;div class=&quot;page&quot;&gt;
            &lt;div class=&quot;header-container&quot;&gt;
                &lt;div class=&quot;header&quot;&gt;
                    &lt;a href=&quot;&lt;?php echo $this-&gt;getBaseUrl()?&gt;&quot; title=&quot;Magento Commerce&quot; class=&quot;logo&quot;&gt;&lt;img src=&quot;images/logo.gif&quot; alt=&quot;Magento Commerce&quot; /&gt;&lt;/a&gt;
                &lt;/div&gt;
            &lt;/div&gt;
            &lt;div class=&quot;main-container&quot;&gt;
                &lt;div class=&quot;main col1-layout&quot;&gt;
                    &lt;?php require_once $contentTemplate; ?&gt;
                &lt;/div&gt;
            &lt;/div&gt;
            &lt;div class=&quot;footer-container&quot;&gt;
                &lt;div class=&quot;footer&quot;&gt;
                    &lt;address class=&quot;copyright&quot;&gt;Magento is a trademark of Magento Inc. Copyright &amp;copy; 2010 Magento Inc.&lt;/address&gt;
                &lt;/div&gt;
            &lt;/div&gt;
        &lt;/div&gt;
    &lt;/div&gt;
&lt;/body&gt;
&lt;/html&gt;
</pre>
<p>So, clearly, the first thing we&#8217;d want to do is replace the logo image, link title attribute and image alt attribute, as well as the footer text. Then we can move onto the included phtml templates. And work on our CSS. We can also add or replace the images in the images folder if we need some fancy background or other imagery.</p>
<p>We won&#8217;t go into details about how to structure your HTML/CSS, we will leave that up to you since it&#8217;s standard web development work.</p>
<p>So, after our Magebase error page makeover, our new pages look like this:</p>
<div id="attachment_1384" class="wp-caption alignnone" style="width: 690px"><img class="size-large wp-image-1384" title="custom-magento-maintenance" src="http://magebase.com/wp-content/uploads/2011/07/custom-magento-maintenance-680x351.png" alt="custom-magento-maintenance" width="680" height="351" /><p class="wp-caption-text">Our custom site maintenance page. Note we added contact info so customers can ring.</p></div>
<div id="attachment_1383" class="wp-caption alignnone" style="width: 690px"><img class="size-large wp-image-1383" title="custom-magento-error" src="http://magebase.com/wp-content/uploads/2011/07/custom-magento-error-680x604.png" alt="custom-magento-error" width="680" height="604" /><p class="wp-caption-text">Our custom error report page allowing customers to send us additional information</p></div>
<h2>Conclusion</h2>
<p>We saw how we can easily customize the default Magento maintenance and error pages by configuring the <code>local.xml</code> file, creating a custom skin folder and adjusting the HTML and CSS supplied in the default skin. You can play around with the settings in <code>local.xml</code> to get the configuration you want and add more meaningful content to the pages themselves.</p>
<p>If you want to change the actual default processing that happens in <code>processor.php</code>, then you&#8217;d have to extend the Error_Processor class in your own file and include it in the other <code>*.php</code> files. Bear in mind that those changes may be overwritten during an upgrade. Your custom skin, however, would not be affected.</p>
<p>Finally, there doesn&#8217;t seem to be an easy way to create language/locale specific error pages but you can create your custom skin templates in your store&#8217;s main language.</p>
<p>Originally published on <a href="http://magebase.com">magebase.com</a>. Copyright &copy; 2011 Magebase - All Rights Reserved.</p>]]></content:encoded>
			<wfw:commentRss>http://magebase.com/magento-tutorials/customizing-the-magento-error-report-and-maintenance-page/feed/</wfw:commentRss>
		<slash:comments>18</slash:comments>
		</item>
		<item>
		<title>Quick Tip: Explain Your Module Configuration Options With Tooltips</title>
		<link>http://magebase.com/magento-tutorials/quick-tip-explain-your-module-configuration-options-with-tooltips/</link>
		<comments>http://magebase.com/magento-tutorials/quick-tip-explain-your-module-configuration-options-with-tooltips/#comments</comments>
		<pubDate>Thu, 23 Jun 2011 11:45:11 +0000</pubDate>
		<dc:creator>Robert Popovic</dc:creator>
				<category><![CDATA[Tutorials]]></category>
		<category><![CDATA[admin]]></category>
		<category><![CDATA[config]]></category>
		<category><![CDATA[tooltip]]></category>

		<guid isPermaLink="false">http://magebase.com/?p=1353</guid>
		<description><![CDATA[Did you know that Magento provides built in tooltips for your configuration options? If you're a module developer and want to explain some of your module options in more detail, you can. Check out how. <p>Originally published on <a href="http://magebase.com">magebase.com</a>. Copyright &copy; 2011 Magebase - All Rights Reserved.</p>]]></description>
			<content:encoded><![CDATA[<p>If you are developing end user extensions you would have used the system.xml file to define your extension&#8217;s configuration options. You also probably aware that you can add captions that explain the purpose and effect of your options by using the <code>&lt;comment&gt;&lt;/comment&gt;</code> element.</p>
<p>But did you know that you could take this a step further?</p>
<p>Magento provides a built in options tooltip you can use to explain some of your options in more detail. If used, these tooltips appear at the top right of the list of your options section when you hover over an option label or field.</p>
<div id="attachment_1355" class="wp-caption aligncenter" style="width: 464px"><img class="size-full wp-image-1355" title="simple-option-tooltip" src="http://magebase.com/wp-content/uploads/2011/06/simple-option-tooltip.png" alt="simple-option-tooltip" width="454" height="59" /><p class="wp-caption-text">A simple tooltip appears at the top right of your options</p></div>
<p>To achieve this, let&#8217;s start with an example system.xml:</p>
<pre class="brush: xml; title: ; notranslate">
&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
&lt;config&gt;
    &lt;tabs&gt;
        &lt;magebase&gt;
            &lt;label&gt;Magebase&lt;/label&gt;
            &lt;sort_order&gt;700&lt;/sort_order&gt;
        &lt;/magebase&gt;
    &lt;/tabs&gt;
    &lt;sections&gt;
        &lt;mbcustom&gt;
            &lt;tab&gt;magebase&lt;/tab&gt;
            &lt;label&gt;Demo Options&lt;/label&gt;
            &lt;frontend_type&gt;text&lt;/frontend_type&gt;
            &lt;sort_order&gt;10&lt;/sort_order&gt;
            &lt;show_in_default&gt;1&lt;/show_in_default&gt;
            &lt;show_in_website&gt;1&lt;/show_in_website&gt;
            &lt;show_in_store&gt;1&lt;/show_in_store&gt;
            &lt;groups&gt;
                &lt;default&gt;
                    &lt;label&gt;Demo Defaults&lt;/label&gt;
                    &lt;frontend_type&gt;text&lt;/frontend_type&gt;
                    &lt;sort_order&gt;10&lt;/sort_order&gt;
                    &lt;show_in_default&gt;1&lt;/show_in_default&gt;
                    &lt;show_in_website&gt;1&lt;/show_in_website&gt;
                    &lt;show_in_store&gt;1&lt;/show_in_store&gt;
                    &lt;fields&gt;
                        &lt;mbcustomopt1&gt;
                            &lt;label&gt;Option 1&lt;/label&gt;
                            &lt;frontend_type&gt;select&lt;/frontend_type&gt;
                            &lt;source_model&gt;adminhtml/system_config_source_yesno&lt;/source_model&gt;
                            &lt;sort_order&gt;10&lt;/sort_order&gt;
                            &lt;show_in_default&gt;1&lt;/show_in_default&gt;
                            &lt;show_in_website&gt;1&lt;/show_in_website&gt;
                            &lt;show_in_store&gt;0&lt;/show_in_store&gt;
                            &lt;comment&gt;Option 1 comment&lt;/comment&gt;
                        &lt;/mbcustomopt1&gt;
                    &lt;/fields&gt;
                &lt;/default&gt;
            &lt;/groups&gt;
        &lt;/mbcustom&gt;
    &lt;/sections&gt;
&lt;/config&gt;</pre>
<p>This will just give us the simple option caption since we only used the <code>&lt;comment&gt;</code> element. To add the tooltip, we will use the <code>&lt;tooltip&gt;&lt;/tooltip&gt;</code> element:</p>
<pre class="brush: xml; title: ; notranslate">
...
                        &lt;mbcustomopt1&gt;
                            &lt;label&gt;Option 1&lt;/label&gt;
                            &lt;frontend_type&gt;select&lt;/frontend_type&gt;
                            &lt;source_model&gt;adminhtml/system_config_source_yesno&lt;/source_model&gt;
                            &lt;sort_order&gt;10&lt;/sort_order&gt;
                            &lt;show_in_default&gt;1&lt;/show_in_default&gt;
                            &lt;show_in_website&gt;1&lt;/show_in_website&gt;
                            &lt;show_in_store&gt;0&lt;/show_in_store&gt;
                            &lt;comment&gt;Option 1 comment&lt;/comment&gt;
                            &lt;tooltip&gt;Option 1 tooltip&lt;/tooltip&gt;
                        &lt;/mbcustomopt1&gt;
...
</pre>
<p>This will give us the result in the above screenshot.</p>
<p>However, if we want to spruce things up a bit, we can add some HTML to both the caption and the tooltip. For example, to achieve the following:</p>
<div id="attachment_1356" class="wp-caption aligncenter" style="width: 690px"><a class="zoom" href="http://magebase.com/wp-content/uploads/2011/06/complex-option-tooltip.png"><img class="size-large wp-image-1356 " title="complex-option-tooltip" src="http://magebase.com/wp-content/uploads/2011/06/complex-option-tooltip-680x197.png" alt="complex-option-tooltip" width="680" height="197" /></a><p class="wp-caption-text">A more complex HTML formatted caption and tooltip</p></div>
<p>We need to enclose our element content with <code>&lt;[CDATA[ ... ]&gt;</code> so the new option would look like:</p>
<pre class="brush: xml; title: ; notranslate">
                        &lt;mbcustomopt2&gt;
                            &lt;label&gt;Option 2&lt;/label&gt;
                            &lt;frontend_type&gt;text&lt;/frontend_type&gt;
                            &lt;sort_order&gt;20&lt;/sort_order&gt;
                            &lt;show_in_default&gt;1&lt;/show_in_default&gt;
                            &lt;show_in_website&gt;1&lt;/show_in_website&gt;
                            &lt;show_in_store&gt;0&lt;/show_in_store&gt;
                            &lt;comment&gt;&lt;![CDATA[Using CDATA to give us more formatting options:&lt;br/&gt;&lt;strong&gt;Bold text&lt;/strong&gt;&lt;br/&gt;&lt;em&gt;Emphasis&lt;/em&gt;&lt;br/&gt;&lt;a href=&quot;http://google.com&quot;&gt;Hyperlinks&lt;/a&gt;]]&gt;&lt;/comment&gt;
                            &lt;tooltip&gt;&lt;![CDATA[&lt;div style=&quot;border-radius:6px;background-color:#fcc;padding:10px;margin-left:10px;width:230px;&quot;&gt;Also using CDATA
 to create richly formatted tooltips like an image:&lt;br /&gt;
&lt;img src=&quot;http://magento15.dev.lero9.com/skin/frontend/default/modern/images/logo.gif&quot; alt=&quot;Logo&quot; style=&quot;margin:15px 15px 15px 0;&quot;/&gt;
&lt;p&gt;Some paragraph text.&lt;/p&gt;&lt;/div&gt;]]&gt;&lt;/tooltip&gt;
                        &lt;/mbcustomopt2&gt;
</pre>
<p>Keep in mind that Magento&#8217;s admin stylesheet specifies the tooltip container with at 180px (class: <code>.system-tooltip-box</code> in <code>boxes.css</code>) but the overflow is not hidden. Also, there is no point in putting any hyperlinks in the tooltip since it disappears when you move your mouse away from the option.</p>
<p class="note">Note that this feature is tested and will work from magento 1.4 onwards.</p>
<h2>Conclusion</h2>
<p>It&#8217;s really easy to add some more verbose explanations to your Magento extension configuration options by using the <code>&lt;tooltip&gt;</code> element in your options definitions. We encourage this especially for more obscure and less intuitive options as well as to have less clutter in the options list since we can avoid lengthy options comments.</p>
<p>Originally published on <a href="http://magebase.com">magebase.com</a>. Copyright &copy; 2011 Magebase - All Rights Reserved.</p>]]></content:encoded>
			<wfw:commentRss>http://magebase.com/magento-tutorials/quick-tip-explain-your-module-configuration-options-with-tooltips/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
	</channel>
</rss><!-- Performance optimized by W3 Total Cache. Learn more: http://www.w3-edge.com/wordpress-plugins/

Minified using disk: basic
Page Caching using disk: enhanced
Database Caching using disk: basic
Object Caching 649/716 objects using disk: basic

Served from: magebase.com @ 2012-02-23 22:07:34 -->

