Intro to Layouts

Layout, by appearance of its components, can easily deceive you into believing that in order to work with it you must first be armed with an extensive knowledge of programming logics. Nothing can be further from the truth. Layout is built with a small set of XML tags that are easy and fun to learn. By learning some key concepts and commands of layout, you will soon be armed with the confidence and knowledge to easily modify your store design to your desired spec.


Back to TopHow Layout Works

Layout is a virtual component of the Magento application. By modifying the components of layout, you can build your store page in an upgrade-compatible way.

Diagram 1

Layout is comprised of default layout and layout updates that are made up of easy-to-learn XML tags. With these layout commands, you can modify/assign content block-structural block relationships and also control store-front functionalities such as loading and unloading of block-specific Javascripts to a page.

Layout files are separated on a per-module basis, every module bringing with it its own layout file (for instance 'catalog.xml' is a layout file for the catalog module, 'customer.xml' is for the customer module...etc). These layout files are located in app/design/frontend/your_interface/your_theme/layout/ and each file is further separated by handles (see diagram 1), each handle (with the exception of <default>) assigning its nested updates to the according specific page in the store.

Some layout files may contain the <default> handle. When parsing the layout files, Magento first grabs the layout updates assigned in the <default> handle of almost all layout files, reading them in the order as assigned in app/etc/modules/Mage_All.xml. It then parses the page-specific layout update, finalizing the building of a store page.

The system is built this way in order to allow seamless addition and removal of modules without effecting other modules in the system.

Back to TopAnatomy of Layout

Layout contain a small set of XML tags that act as detailed instructions to the application on how to build a page, what to build it with and the behavior of each building block. The best way to approach layout is to just dive right in and attack it from all angles. In order for you to do that, here’re some behavioral properties of each layout XML tag.

Handle

Handle (diagram 1) is an identifier by which the application determines what to do with the updates nested by it.

If the name of the handle is <default>, then the application knows that its nested updates must be loaded on almost all the pages of the store prior to loading page-specific layout (We say 'almost all', because some exceptional pages like the product image popup does not load the layout in the <default> handle).

If Magento finds handles other than <default>, it will assign the updates nested inside the handle to the according page specified by the handle. For instance, <catalog_product_view> contain the layout updates for the Product View page, while <catalog_product_compare_index> contain those for the Compare Product page. Handles are set-in-stone identifiers that as a designer with no extensive understanding of Magento programming, should never need to modify.

<block>

Magento determines the behavior and visual representation of each building block of a page via the <block> tag. We've already mentioned the two types of blocks Magento employs - structural blocks and content blocks. The best way to distinguish between the two is by examining the behavior assigned to it via the tag attributes. A structural block usually contains the attribute 'as', through which the application is able to communicate with the designated area (by the getChildHtml method) in a template. You will notice many occurances of this 'as' attribute in the default layout, because by nature the default layout is one that builds the ground work upon which the page-specific layouts can begin adding onto. For instance, in the default layout, there're structural blocks such as 'left', 'right', 'content' and 'footer' being introduced. Not to say these blocks cannot exist in normal layout updates, but why not first set up the reoccurring structural blocks in the default layout first, then start adding content on a per-page basis? Let’s dig further into available attributes for <block>.

  • type – This is the identifier of the module class that defines the functionality of the block. This attribute must not be modified.
  • name – This is the name by which other blocks can make reference to the block in which this attribute is assigned (see diagram 3).
  • before (and) after – These are two ways to position a content block within a structural block. before="-" and after="-" are commands used to position the block accordingly at the very top or very bottom of a structural block.
  • template - This attribute determines the template that will represent the functionality of the block in which this attribute is assigned. For instance, if this attributes is assigned ‘catalog/category/view.phtml’, the application will load the ‘app/design/frontend/template/catalog/category/view.phtml template file.In order to learn about how layout works with templates to bring markup to your store, read Step by Step Guide to Building a Theme
  • action – <action> is used to control store-front functionalities such as loading or unloading of a Javascript. A full list of action methods will soon become available, but in the mean time the best way to learn about the different action methods is by playing around with them in the currently available layout updates.
  • as – This is the name by which a template calls the block in which this attribute is assigned. When you see the getChildHtml('block_name') PHP method called from a template, you can be sure it is referring to the block whose attribute 'as' is assigned the name 'block_name'. (ie. The method <?=$this->getChildHtml('header')?> in the a skeleton template correlates to <block as=“header”> )

<reference>

Diagram 3

<reference> is used to make reference to another block. By making a reference to another block, the updates inside <reference> will apply to the <block> it correlates to (see diagram 3).

In order to make the reference, you must target the reference to a block by using the 'name' attribute. This attribute targets the <block> tag's 'name' attribute. So if you were to make a reference by <reference name="right">, you're targeting the block called <block name=" right ">.

Back to TopRules of XML

Diagram 4

If you're not familiar with it, upon encountering Magento's XML-based layout updates, you may have a question or two about the rules you must follow when modifying an XML file.
The only set rule you need to remember with regards to XML, is that when a tag opens, it must either be followed by a closing tag(<xml_tag></xml_tag>) or self-close(<xml_tag/>) exactly as (X)HTML file tags would.

Back to TopQuick Exercises to Get You Started

Just like any new concepts, we know that without actually diving in and getting your hand dirty, you can never truly grasp what you've been explained in words. So here are a couple of exercises for you to get a feel for working with layouts. In order to work with this exercise, you must have the default Magento theme ready and accessible.

Exercise #1: In the category page, move the "My Cart" box from the right column to the left
  1. Turn on the Template Path Hint by going to the admin then navigating to System -> Configuration. When you're in the configuration page, select the store you're working in by using the top left website/store selector. Wait for the page to reload, then select the Developer tab. Select 'Yes' in the select box for Template Path Hints. Click on Save. Go back to the store front, and reload.
  2. When the page reloads, look at the template path of the 'My Cart' block- it'll most likely say 'frontend/default/default/template/checkout/cart/sidebar.phtml'. By looking at the path, you know this template is being introduced via the 'checkout' module. How do you know this? - frontend/default/default/template/checkout/cart/sidebar.phtml. It says so in the template path. The immediate directory name following 'template' is the name of the module through which a template is introduced.
  3. Open up layout/checkout.xml - because now we know we're dealing with the checkout module
  4. Search for 'checkout/cart/sidebar.phtml' (the template name of the My Cart block) in the layout updates. You will find an area that looks like this:
    <reference name="right">
    <block type="checkout/cart_sidebar" name="cart_sidebar" before="-" template="checkout/cart/sidebar.phtml"/">
    </reference">
    Change it to say the following instead (Note that all you're doing is changing the <reference name="right"> to <reference name="left">).
    <reference name="left">
    <block type="checkout/cart_sidebar" name="cart_sidebar" before="-" template="checkout/cart/sidebar.phtml"/">
    </reference">
  5. Reload the store front and you will now see the change reflected.

Exercise #2: Separate the SEO links at the footer area - Instead of having the link items to be one list, isolate 'Advanced Search' to be in the header instead.
  1. You can make a calculated assumption that the SEO links must be assigned somewhere in the layout under the footer block because it's being pulled through '<?=$this->getChildHtml()?>' of template/page/html/footer.phtml. (You will need the Template Path Hints turned on to see why this is obvious).
  2. Open up layout/page.xml and look through the list of children under the footer block in order to locate a block that calls the footer links - You will find <block name="footer_links">, which is what calls the SEO links. Now that you know that layout updates reference the SEO links via the name="footer_links", now you will do a search in all the xml files for <reference name="footer_links">. You will find references for the footer_links block in catalog.xml (which calls 'Site Map'), catalogsearch.xml(which calls 'Search Terms' and 'Advanced Search') and contacts.xml (which calls 'Contact Us').
  3. Now that you've located the area of the individual SEO link items, you will now begin the steps to isolate 'Advanced Search' from the bunch and make it it's own thing in the header. First go back to page.xml and create a new block <block type="page/template_links" name="header_links" as="header_links" template="page/template/links.phtml"/> and nest it inside <block name="header">. You've made the layout updates to expect this link in header.phtml. Open template/page/html/header.phtml, and type in <?=$this->getChildHtml('header_links')?> where you want the link to reside.
  4. Now I go to catalogsearch.xml, and cut this:
    <action method="addLink" translate="label title" module="catalogsearch"><label>Advanced Search</label><url helper="catalogsearch/getAdvancedSearchUrl" /><title>Advanced Search</title></action>
    out from <reference name="footer_links">.
    I create new lines to reference the new header_links block I created, and nest the cut out code inside it like so:
    <reference name="header_links">
    <action method="addLink" translate="label title" module="catalogsearch"><label>Advanced Search</label><url helper="catalogsearch/getAdvancedSearchUrl" /><title>Advanced Search</title></action>
    </reference>
  5. Now I have Advanced search in the header instead of the footer.

This marks the end of Designer's Guide to Magento. Hopefully by now you're armed with confidence and knowledge about how to approach designing with Magento. We hope to see some of your results up on the forum. Share with us your designs, discuss this documentation and ask lots of questions at the community forum's 'HTML, XHTML, CSS, Design Questions' thread.