5 Tips to Use local.xml to Customize Your E-Store

When you plan out a new theme for your Magento store, you begin designing it by using the default theme as your base. Very rarely would you create a new theme from the scratch. The reason being the default theme brings with it most of the elements like standard features, that are required by the phtml and layout files.

While this is a simple way of designing your new theme, there will be certain elements in the phtml that you would not want to use. You may want to customize the layout files to suit your design and theme requirements. What if, the theme is updated, after you have made the layout changes? You will need to fit the customizations to these new updates as well. That's why it is considered better to make the necessary changes in the local.xml file. Here the original files remain unchanged, and the modifications are stored within a single file, which is an added advantage. Creating and storing the necessary modifications in the local.xml file is similar to modifying the layout directly

Here is the root element layout for local.xml file

<?xml version="1.0" encoding="UTF-8"?>
<!--
/**
 * local.xml
 *
 * Local layout modifications for our local theme
 *
 * @category    design
 * @package     my_theme_default
 * @copyright   Copyright (c) 2011 Magebase.
 */
-->
<layout version="0.1.0">
...
</layout>

Here are five tips that might help you work with local.xml file in a better way

Adding/Removing JS and CSS Files

There will be certain scripting or styling files, added with the 3rd party extensions, that you won't need in your website. You may want to add your own scripting files. In order to add the functionalities that suit your design needs, you may add the scripting and styling files needed by the module, instead of the default ones. The module specific layout XML file will take care of the customizations you have created, but it is the layout specific XML that will account for a theme specific scripting. When you are adding an arbitrary file, you need to know whether to include it along all pages of the website, or just add it to a few elements on the website.

For example you want to add the scripting file myjs.js and styling file mystyles.css to every page with the handles. Targeting the "head" block with the addItem action, you can add the necessary files to the theme specific layout

<default>
    <reference name="head">
        <action method="addItem">
            <type>skin_js</type>
            <name>js/my_js.js</name>
            <params/>
        </action>
    <action method="addItem">
            <type>skin_css</type>
            <name>css/my_styles.css</name>
        </action>
    </reference>
</default>

You can use removeItem method to remove the scripting and styling files

<default>
    <reference name="head">
        <action method="removeItem">
            <type>skin_css</type>
            <name>css/brandext/slider.css</name>
        </action>
        <action method="removeItem">
            <type>js</type>
            <name>some_ext/jquery-1.4.2.js</name>
        </action>
    </reference>
</default>

In the above mentioned code, the second removeItem usage concerns with removing scripting file that was added by an extension to the JS folder and not the theme specific folder.

Google CDN instead of Local jQuery

You can even replace the locally added jQuery file with the same file added from Google CDN. The main aim of doing this is to improve the performance of your website. Here is how you can programmatically achieve this

<default>
    <reference name="head">
        <block type="core/text" name="google.cdn.jquery">
            <action method="setText">
            <text><![CDATA[<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"></script><script type="text/javascript">jQuery.noConflict();</script>]]>
                </text>
            </action>
        </block>
    </reference>
</default>

Let's understand what is happening here. The jQuery.noconflict() was called at the end of the code so that there is no conflict between the jQuery files and Magento prototype library. Also, JS is excluded in this code, so addItem() function cannot be used within the code.

In order to avoid including these functions, and ensuring no conflict occurs, a block core/text has been added where the script is included as text node. CDATA is the default output of this block.

Modifying the Block Parameters

If you want to modify some of the block parameters like number of upsell/crosssell products, or the number of columns within the category grid, then here is how you can do it.

First you will need to change the category grid using the following code

<catalog_category_default>
    <reference name="product_list">
        <action method="setColumnCount">
            <count>3</count>
        </action>
    </reference>
</catalog_category_default>
<catalog_category_layered>
    <reference name="product_list">
        <action method="setColumnCount">
            <count>3</count>
        </action>
    </reference>
</catalog_category_layered>
<catalogsearch_result_index>
    <reference name="search_result_list">
        <action method="setColumnCount">
            <count>3</count>
        </action>
    </reference>
</catalogsearch_result_index>

Here's how you can modify upsell in the product view

<catalog_product_view>
    <reference name="upsell_products">
        <action method="setItemLimit">
            <type>upsell</type>
            <limit>3</limit>
        </action>
        <action method="setColumnCount">
            <columns>3</columns>
        </action>
    </reference>
</catalog_product_view>

In the root element code, we have already seen that the local.xml file is called towards the end. This simply means that whatever values are set in the other XML file layout will be overridden by the local.xml towards the end.

Logged vs. Not Logged Customers

Let's change the theme layout for the logged vs. the not logged customers. You can play the appearance and include/exclude elements, thus making the theme appear differently for both the handles. With this you can use the layout block to create different content for the different handles.

If you consider the stock alert functionality of Magento, you will see that while it offers notifications to the logged in customer about availability of a product, or when a product is back in stock, it redirects the ones who are not logged in to the Log in page. With a little change in content, this functionality and discomfort can be eased out for both handles.

This new phtml block will be shown in place of the default. This block will be displayed in place of the "add to cart" button

<catalog_product_view>
    <!-- remove the original alert URL block; we will put it back into the add to cart block below -->
    <reference name="alert.urls">
        <action method="unsetChild">
            <name>productalert.stock</name>
        </action>
    </reference>
    <!-- create our new block as a child block of the addtocart block -->
    <reference name="product.info.addtocart">
        <!-- Block comes from the original stock alert block in productalert.xml -->
        <block type="productalert/product_view" name="productalert.stock" as="productalert_stock" template="magebase/productalert.phtml">
            <action method="prepareStockAlertData"/>
            <action method="setHtmlClass">
            <value>alert-stock link-stock-alert</value>
            </action>
        </block>
    </reference>
</catalog_product_view>

Let's introduce a custom phtml template to the following path template/magebase/productalert.phtml. Paste the following code to this path

<p class="<?php echo $this->getHtmlClass() ?>">
<?php if ($this->getSignupDesc()) : ?>
    <span class="alert-description"><?php echo $this->getSignupDesc() ?></span>
<?php endif; ?>
    <button type="button" title="<?php echo $this->escapeHtml($this->__($this->getSignupLabel())); ?>" class="button btn-alert" onclick="setLocation('<?php echo $this->escapeHtml($this->getSignupUrl()) ?>')"><span><span><?php echo $this->escapeHtml($this->__($this->getSignupText())); ?></span></span></button>
</p>

Let's add some descriptive items to the link to make the call to action clear, despite removing the button. This way you will make it clear to the customer as to what will happen when they click on this link. Add the following code to the XML, you will be able to differentiate actions for logged in vs logged out customers.

<customer_logged_out>
    <reference name="product.info.addtocart">
        <reference name="productalert.stock">
            <action method="setSignupLabel" translate="value">
                <value>Sign up to get notified when this product is back in stock</value>
            </action>
            <action method="setSignupText" translate="value">
                <value>Sign Up For Alerts</value>
            </action>
            <action method="setSignupDesc" translate="value">
                <value>Log in or create an account to be notified when this product is back in stock.</value>
            </action>
        </reference>
    </reference>
</customer_logged_out>

<customer_logged_in>
    <reference name="product.info.addtocart">
        <reference name="productalert.stock">
            <action method="setSignupLabel" translate="value">
                <value>Click to get notified when this product is back in stock</value>
            </action>
            <action method="setSignupText" translate="value">
                <value>Alert Me When In Stock</value>
            </action>
            <action method="setSignupDesc" translate="value">
                <value>You can sign up to be notified when this product is back in stock.</value>
            </action>
        </reference>
    </reference>
</customer_logged_in>

Removing/Modifying Template Blocks

Chances are you want to replace the existing template blocks with your own custom blocks. You may wish to rearrange the template blocks, and remove certain blocks that don't belong to your store. Here are techniques to perform these actions in the local.xml file.

If you want to remove blocks, you can do so using these two methods, both are contextual

  • Use : works in a global context, and is processed only after all the remaining blocks are processed. This function removes the template block without taking the layout handle into consideration. Of course, you won't be able to remove the template block from one place and associate it to another place using this method

  • Use : works in a global context, and is processed only after all the remaining blocks are processed. This function removes the template block without taking the layout handle into consideration. Of course, you won't be able to remove the template block from one place and associate it to another place using this method

Now let's see how you can rearrange the template blocks

It is a two-step method , where the first step is to remove the unwanted blocks at a global level using remove function. The second step is to rearrange blocks using "unset child" function

Remove unwanted blocks

<default>
    <!-- remove the language and store switcher and footer links blocks, we won't use them -->
    <remove name="store_language" />
    <remove name="store_switcher"/>
    <remove name="footer_links" />
</default>

Rearrange with Unset

<default>

        <!-- move the breadcrumb block from the top.bar child block back to the template root

(this overrides the modern theme breadcrumb positioning) -->

        <reference name="top.bar">
            <action method="unsetChild">
                <name>breadcrumbs</name>
            </action>
        </reference>

        <reference name="root">
            <block type="page/html_breadcrumbs" name="breadcrumbs" as="breadcrumbs"/>
        </reference>
    </default>

Replace with custom blocks

<catalog_product_view>
    <reference name="product.info">
        <action method="unsetChild">
            <name>info_tabs</name>
        </action>
        <block type="catalog/product_view_tabs" name="product.info.tabs" as="info_tabs" template="catalog/product/view/tabs.phtml" >
            <action method="addTab" translate="title" module="catalog">
                <alias>upsell_products</alias>
                <title>You may also like</title>
                <block>catalog/product_list_upsell</block>
                <template>catalog/product/list/upsell.phtml</template>
            </action>
            <action method="addTab" translate="title" module="catalog">
                <alias>description</alias>
                <title>Details</title>
                <block>catalog/product_view_description</block>
                <template>catalog/product/view/description.phtml</template>
            </action>
            <!-- neat trick to include a CMS Static block directly in the tab -->
            <action method="addTab" translate="title" module="catalog">
                <alias>shipping</alias>
                <title>Shipping Costs</title>
                <block>cms/block</block>
                <template>null</template>
            </action>
            <!-- define the CMS block ID for the shipping info tab -->
            <block type="cms/block" name="product.info.tabs.shipping" as="shipping">
                <action method="setBlockId"><block_id>tab-product-shipping</block_id></action>
            </block>
        </block>
    </reference>
</catalog_product_view>

Conclusion

With these five tips, you can easily bring modifications at a very local level. In case your theme is updated, you don't need to customize or include the changes once again. As you have included it at a local level, it will be automatically taken in by the theme, thus making it convenient for you.

Deepa, a technical writer with Semaphore Software, who now devotes her time in advising its clients to hire certified magento developers. She offers information as well as tips and latest trends in this domain. Her love for reading helps her constantly provide latest information on different technical and design aspects of Magento

Deepa Ranganathan
  • magento
  • magento tips
  • e-store
By Deepa Ranganathan On 04 May, 15  Viewed: 142

Other blogs you may like

How to Manage the Backend Functionality of Your Magento Store?

Helper contains the necessary functions for you; you can call in a helper from anywhere. An example of helper is as below $helper = Mage::helper('monhelper'); The call can be related to $helper = Mage::helper('monhelper/data'); **Let's create a helper file** You will need to... By Deepa Ranganathan   On 17 Jul 2015  Viewed: 142

How to Programmatically Create a Dropdown Login for your Magento Store?

If you want to improve the interface of your Magento store, then you must include the dropdown login form. This would help create an interactive base for your consumers, and offer convenience too! Let’s see how you can include the form programmatically. Go to... By Deepa Ranganathan   On 07 Jul 2015  Viewed: 1,151

3 Ways to Track Shoppers Checking-in From Different Devices

Smart devices are just increasing and improving with time. The digital era has definitely introduced many devices that will offer convenience and ease out your problems. With multiple platforms available for logging into your favourite store, it becomes difficult for you as a store owner or a... By Deepa Ranganathan   On 18 Jun 2015  Viewed: 185

Display Best Selling Products on your Magento Store

<center>![Magento][1]</center> It's a good idea to tell your audience which products are "best sellers" on your e-store. Most often, people do want to know what others have viewed on your store. When you display these products, you are actually making your audience stay on your store for a... By Deepa Ranganathan   On 29 Apr 2015  Viewed: 238

5 ways SMBs can benefit from an e-store?

If you own a small or medium business, it is time you moved online! Embrace e-commerce solutions to get more engagement, conversions, and marked-up sales. The reason is pretty simple- your consumers are online. It only makes sense to be visible on the medium chosen by your consumers. So, in this... By SilvertouchtechUK   On 05 May 2015  Viewed: 92