The Better Way to Modify Magento Layouts

In this article, I’m going to be covering what I believe to be a very effective way of modifying the layout of any Magento theme.

For several of the first Magento themes I built, I copied the layout files from the default or blank theme into the custom theme layout folder. I would then modify the layout files directly, editing or commenting out content in files like: catalog.xml, page.xml, checkout.xml, etc… I never liked editing these files directly, as I knew that when it came time to upgrade to a newer version of Magento that had upgraded the layout files, I’d have to merge the changes into the new layout files.

One day, I was digging through the Magento code relating to layout files and discovered a bit of code that made me realize that it was possible to just place a local.xml file in my custom theme’s layout folder and have it loaded automatically by Magento. (this code is on line 283 in /app/code/core/Mage/Core/Model/Layout/Update.php in the fetchFileLayoutUpdates() method).

Due to Magento’s brilliant tags, it’s possible to do just about anything you want without having to edit any of the default layout files.

Before delving into the code, let’s look at the advantages/disadvantages of this method:


  • Allows you to upgrade themes without having to merge in changes
  • All custom layout changes are centralized, allowing developers to more easily make changes to custom theme elements


  • At first, it’s slower to use this method than hacking up the standard layout files directly
  • You will have one more place to look where the site might be pulling code (template phtmls, standard layout files, admin layout updates, AND local.xml)

Here is the slimmed down, commented local.xml from one of our recent projects:

<?xml version="1.0"?>
<layout version="0.1.0">
	<reference name="head">
		<!-- Magento looks in /skin/frontend/<INTERFACE>/<THEME>/js/buyprinting.js
		for this file -->
		<action method="addItem"><type>skin_js</type><name>js/buyprinting.js</name></action>
		<!-- This removes the item that was set in the page.xml file -->
		<action method="removeItem"><type>skin_js</type><name>js/iehover-fix.js</name></action>
		<!-- Magento looks in /js/prototype/ for this file -->
		<action method="addJs"><name>prototype/</name></action>
		<action method="addCss">
	<reference name="header">
        <!-- This adds a CMS block that can be called from the template file
        associated with the header block. -->
		<block type="cms/block" name="cms_quick_help">
			<action method="setBlockId"><block_id>quick_help</block_id></action>
        <!-- The remove tag removes the blocks with the specified name from the layout -->
		<remove name=""/>
		<remove name="store_language"/>
		<remove name="breadcrumbs"/>
	<reference name="top.nav">
		<remove name="catalog.topnav"/>
	<reference name="left">
		<remove name="left.newsletter"/>
		<remove name="left.permanent.callout"/>
		<remove name="catalogsearch.leftnav"/>
        <!-- When you use the remove tag, it removes any blocks with the specified name from
            the entire layout, regardless of the context. So, if I remove right.newsletter in
            the <default> context and that name is used in say the <catalog_product_view> context,
            then both blocks will be removed.  Because remove operates on the global context,
            you can only remove an element once.  Since <remove name="right.newsletter" /> is
            being called in catalogsearch.xml, we have to unset it, or else we'll get an error.
            The line below only unsets the block from the parent's context, not the global
            layout context -->
		<action method="unsetChild"><name>right.newsletter</name></action>
	<reference name="right">
        <!-- Some blocks have to be removed using remove, others via unsetChild.
            I've not spent the time digging into the code to figure out why -->
		<remove name="right.permanent.callout"/>
		<remove name=""/>
		<remove name="left.reports.product.viewed"/>
		<action method="unsetChild"><name>sale.reorder.sidebar</name></action>
		<action method="unsetChild"><name>wishlist_sidebar</name></action>
		<action method="unsetChild"><name>right.reports.product.viewed</name></action>
		<remove name="cart_sidebar"/>
	<catalog_product_view><!-- 2columns-right -->
		<reference name="root">
			<action method="setTemplate"><template>page/2columns-left.phtml</template></action>
		<reference name="content">
			<reference name="">
				<block type="cms/block" name="cms_product_info_tabs">
					<action method="setBlockId"><block_id>product_info_tabs</block_id></action>
				<block type="catalog/product_view" name="product.clone_prices" as="prices" template="catalog/product/view/price_clone.phtml"/>
				<action method="unsetChild"><name>tierprices</name></action>
				<action method="unsetChild"><name>addto</name></action>
				<remove name="addto"/>
				<reference name="">
					<action method="unsetChild"><name>product.tierprices</name></action>

I hope with article has given you some direction as to how you can improve you Magento theming skills. If you have any additional tips/comments on coding layouts, please suggest them in the comments section.

Posted on February 23, 2010

Posted by Erik Hansen



  2. How do you have control over number of products in the category ? Also, how to handle the out of stock notification indicator when you create custom layout ?

  3. Great tutorial for understanding the possiblities of the theme-topic ;-)

  4. Thank you for your post!

    Anybody knows how to restore left block which is removed on checkout-page via checkout.xml

    I am using local.xml file, and need to show this left block which is not showing. Any help will be great!

  5. Great help & better tutorial, nice. can u provide some similar help for Joomla also ? Thanks in advance !!!

  6. Love this! Building my first site in Magento and this article is a life saver…thank you! :)

  7. Great post, used it to remove all the unnecessary javascript from the checkout pages.



  8. If your local.xml is being ignored, then your problem is probably the caching. Magento really loves to cache its layouts. If it had to compile everything for every request it would quickly grind to a halt.
    Go to your admin page. System | Cache Management. Make sure “Configuration” cache is disabled. IMO it’s best to turn off *all* caching while a site is in development.

  9. Some of the code was removed.

  10. I’ve tried, but I am not getting my local.xml file to override anything. Its like It is being completely ignored. I created a new theme (genesis), and in there created 3 new folders (template, layout and genesis) and in the layout folder i have my local.xml file. The contents of the file is:

    < ?xml version="1.0" encoding="UTF-8"?>



    I simply want to update the default layout of the pages and this is not happening at all, neither is anything (for instance, breadcrumbs) being removed. Can anyone advise me as to what the solution is?

  11. I am extremely impressed thanks for sharing all information. It is a great post for the people to get the proper information.

  12. Extremely awesome and helpful post for me… even about a year after you wrote it!! These layouts are tough to get the hang of, but your code example really helped me out.

    You should write a book on templating Magento. Stuff like local.xml best practices and “stuff you need to know”. I’d for sure buy it. ;)

  13. @hartog actually in 1.5 the code has just been moved to a different method. Have a look in public function getFileLayoutUpdatesXml in the same file, line 418

  14. Hello
    Great articles.
    How to unsetChil one block

    Its possible ? or only emove is ok for this block ?

  15. hmm just a note here but maybe it would be a good idea to dig into the source for this site and add “htmlspecialchars()”
    to the php for the comment post. would make it a WHOLE lot easier on your commenters.

  16. So I got past my initial issues and I am successfully designing a theme based on your method.

  17. from:


  18. from:


    reference name=”content”>
    reference name=””>
    action method=”unsetChild”>addto
    remove name=”addto”/>


  19. Why are you doing both unsetChild-addto AND remove addto ? Was the unsetChild not enough ?



  20. Is there a tag type similar to that specifies if the shopping cart has anything in it? For example if I only wanted to display the My Cart toplink if the cart had something in it. I’ve seen a few ways it can be done by editing the php core directly, but I don’t want to to that.

  21. I love the way you explain it. Thank you!

  22. third try with xhtml tags:

    I love your article and I kept everything clean with this. I know you worte this ages ago, but maybe someone can give me a hand with one problem. I cannot add a new reference between content and footer without changing page.xml. Do you know a way to do this?
    It works when I change page.xml and add into the default layout and:
    <block type=”core/text_list” name=”middlespace” as=”middlespace” translate=”label”>
    Then I can use:
    <reference name=”middlespace”>
    <block type=”core/template” name=”three-teasers-home” template=”page/html/three-teasers-home.phtml” after=”-” />
    But I don’t want to change page.xml, can you help me out? Or maybe someone else?

  23. Hi,
    I love your article and I kept everything clean with this. I know you worte this ages ago, but maybe someone can give me a hand with one problem. I cannot add a new reference between content and footer without changing page.xml. Do you know a way to do this?
    It works when I change page.xml and add into the default layout and:


    Then I can use:

    But I don’t want to change page.xml, can you help me out? Or maybe someone else?

  24. Hi,
    I love your article and I kept everything clean with this. I know you worte this ages ago, but maybe someone can give me a hand with one problem. I cannot add a new reference between content and footer without changing page.xml. Do you know a way to do this?
    It works when I change page.xml and add into the default layout and:


    Then I can use:

    But I don’t want to change page.xml, can you help me out? Or maybe someone else?

  25. if you want to create your own magento blocks and insert it in a layout look at :

  26. I guess the code tag didn’t really work:


  27. Thanks for pointing out this helpful technique. With the following code in local.xml, I was able to simply incorporate an alternate body style.


  28. How do you control number of products in the category view in Magento?

  29. Hi ehansen,

    Thanks for great article lots of things are cleared to me by this article.

  30. Thanks for your helpful tip. I have a question. Are there any way to determine the block position from layout.xml file based on module configuration? EX: i have config from backend to show one block at: left, right or not. So the layout file of this module will reference to left, right or not. How do i approach this?

    Sorry for my poor English. Hope you understand.

    Thanks and hope to hear from you soon.

  31. Great article, one issue that I’ve come across is when you need to reorder the JavaScript includes in .

    How do you normally approach this?

  32. @Thomas- Sorry for being dump here. Are you referring to create a custom module for “another block”. Please explain what do you mean by “new reference” and “another block”.

  33. Magento version
    Dear hansen,
    we have gone through all the posts, excellent discussion but couldn’t solve our simple problem i guess.

    we are simply trying to display a news ticker on the right column of our home page.We are successful in creating a static block on the right column from the admin interface but data of news updates is required to be fetched from database.we have no clue how to fetch and display data on our static block. Design guide doesn’t say any thing on the topic.
    A quick help is appreciated.

  34. @ Zahid – you should not be using a “static” block to fetch database content. You should create a new reference or create another block to pull it in.

  35. @seif That is indeed possible, if you copy the page refrence code to the xml you can change everything.

    For example the category page is ‘catalog_category_default’. You can find it if you look in your page source, it’s attaced to you body class (don’t forget to change the – with _ in the xml).

  36. Hi .
    Thanks for this article , well done .
    Can i use local local.xml to force the template in every page to 3columns.phtml ?
    Thanks !

  37. Thanks for this article it is very helpfull, i was looking for this kind of tutorial.

    Question tough: For example if i want to remove the ”My Cart” link out of the, what is the best way to do this? Because in the checkout.xml this is inserted using a so i can’t remove this using of because it isn’t a block (am i right or am i totally thinking wrong)?

    Also how can i change the quantity of the upsell blocks on the product detail page using the local.xml


  38. Hi, this post has been quite useful to me. Thank you.

    I do have a question following from it, though. It seems like if you use a local.xml file that you would be updating the layout of every page with that theme.

    If this is true, then every unique page would require a new theme. It seems like that would be bulky, time-consuming and difficult to update.

    Is there a way to get the local.xml file to make different changes to the layout based upon the template which has been chosen for the particular page? Or have I misunderstood what Magento is doing?


  39. Custom Layout Update,it can work, thanks for your share.


  40. I am trying to move the breadcrumbs on the Product View Page, so that it appears just below the product name. Is there any way to achieve this. Thank you for your great tips.

  41. @Jonathan_Hodges: Thanks, that worked like a charm. Didn’t think of doing it that way. I found an article that in navigation.phtml loops through all cms pages and adds the cms-pages to the navigation. I think that fogged my “clear thinking”. Happily, I posted my problem here and now I’ve got it working. Thanks again.

  42. @Percy: You could add your static block in the default layout handle and echo it in the top of the footer template. Then unset child in the footer block in the layout handles for My Account and Checkout pages.

  43. I am wondering if the following is possible:

    I want to add a static block to the bottom of the content (between content and footer) for all pages, except for the checkout pages and the “My Account” pages. All other pages, being all CMS, Catalog, Products.

    It seems to me that there should be a possibility to set this in the local.xml layout file. Can you help me with that?

  44. Hi I’m completely new to magento. I just want to know where do i go to edit code. Is it through the Magento dashboard? Thanks i appreciate any help for this newbie.

  45. I am so confused. Sorry! I cannot figure this out. Why is it so difficult to edit the top menu bar with cart, login, etc? What file do I go to so I can just edit it, or put a stupid breadcrumbs add-in to manage the links myself? Sorry, I have searched at least 30 blogs and not gotten an answer and everything I try crashed the site, been working at it for at least 6 hours now, and it is late and the pub under my office is having karaoke night to top it off. hahahahah! Thanks for any help.

  46. I think managing all custom updates via local.xml is a bad idea.

    If your upgrading Magento you should still merge any changes to layout or template files. This method does not solve that issue, it only makes it more difficult to track down which files need to be merged. For instance, if an update include some new blocks in you really wouldn’t be able to find out unless you went through all the diffs between magento and then your custom theme.

    Your custom layout changes should be all in your custom_package/default (assuming version 1.4+ which falls back to base/default).

    If you’re running on a version of magento that falls back on base/default then it’s possible to only update the necessary files in your custom package and theme directories. When you upgrade, you compare the changes between the old and new magento versions, check if any of those files exist in your custom theme and only merge those files.

    I’ve stared a script to help speed up this process,
    As a bonus it can also scan app/code/local for php classes which extend core magento classes and inform you if they should be reviewed. Currently only runs on *nix systems due to the use of the diff command.

  47. @hartog actually in 1.5 the code has just been moved to a different method. Have a look in public function getFileLayoutUpdatesXml in the same file, line 418

  48. Thank you for this tutorial, it´s really good. I was wondering if it´s possible to add simple text via local.xml, like a phone number, or an adress into the top.links section, I just can´t figure it out. Cheers!

  49. I’m trying to add a new / custom reference to my store. I’ve set it up so that I’ve got custom_content reference in my xml under the <catalog_product_view> and it set to getChildHtml(‘custom_content’) in the view.phtml file. I’ve also added the custom page in my page.xml file, so it registers.

    However, a LOT of basic stuff is yanked out immediately (like the Add to Cart button). When I add it back in local.xml I get a javascript error Cannot call method ‘submit’ of undefined.

    If I copy the ENTIRE content reference from catalog.xml I still get the same error. What am I missing?!


  50. 1 2 3 4

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>