Magento layouts are very important for theme development. Layout are xml files located in your theme/layout folder. Layout are very power magento tools, initially tricky to understand but once you get familiar, it becomes very powerful tool. As the name suggests, layout files are responsible for setting positions of various elements on the page and determining which phtml is loaded on which page and placed where.
Layout files are located in your theme inside the layout folder. catalog.xml, page.xml , checkout.xml ,etc are layout files.
Magento uses 3 things to display its pages
- Block Classes
- PHTML files
- Layout XML
Magento is based on MVC architecture. PHTML file contain all html(view) codes and Block classes contain all view related logic. Layout XML are the ones that relate block classes and phtml files, and define which phtml file will be used on which page and at which location.
When a page is loaded in magento, it read all the magento layout xml files in your theme, combines it and then processes it to create the view of a page.
Now we will look into the details of layout xml files
Layouts are basically xml files, which are divided into blocks and xml tags. Lets start of by taking an example, open the layout file catalog.xml
A basic layout block looks like
<block type="catalog/navigation" name="catalog.topnav" template="catalog/navigation/top.phtml"/><br />
- type = magento php file where all functions used in top.phtml are location. This the block class. For eg. In the current case it is Mage_Catalog_Block_Navigation
- name = any unique name given for the block
- template = path of the phtml file used
In the template file, we using various php function $this object. The $this object is basically the object of the block type we defined. To see the significance of block type , open the file catalog/navigation/top.phtml
There you will find a code
<?php $_menu = $this->renderCategoriesMenuHtml(0,'level-top') ?>
So the function $this->renderCategoriesMenuHtml is a class function, which is defined in class Mage_Catalog_Block_Navigation located at app/core/Mage/Catalog/Block/Navigation.php. So if block type is wrong, then a block doesn’t work.
Put one block tag inside another to make a child block for e.g
<block type='core/template' name='parent' template='parent.phtml'/> <block type='core/template' name='child' template='child.phtml'/> </block>
In the phtml file parent.phtml you can access the child block by
$this->getChildHtml function is used in various phtml in magento. It is basically used to the get the content of the its child block. Making child blocks, divides your view logic into separate files, and make reading of code simpler.
Another important aspect of layouts is how does magento to know which block to read for a particular page. For example, when opening home page, how does magneto know which blocks to display.
If you see layout files, all block declarations are placed in parent tags like
<default> </default> <checkout_cart_index> </checkout_cart_index>
The default tag means, all blocks inside this tag are to be shown in all the pages. So blocks like header, footer, menu etc are placed inside tag, so that they are shown in all pages.
Other tags like , are used to display block specific to pages. Like if we want to place a block on the cart page or product page then we use such tags. These tags are based on the URLs on the page.
Each url inside magento is broken down into 3 parts
- Customer login page url is: www.youtmagento.com/index.php/customer/account/login
- Checkout page url is: www.youtmagento.com/index.php/checkout/onepage/index
So the layout tag for login page would be <customer_account_login> and that for checkout page is <checkout_onepage_index>. Inside the layout files you will xml tags like <customer_account_login> and <checkout_onepage_index>,this is to specific, that block inside such tags are read on those pages and not other pages.
Magento default theme has 5 different type of page structures. These are 1column layout, 2 column left , 2 column right ,3 column layout and empty layout. If you open the files of your theme ‘page/1column.phtml’ , ‘page/2columns-left.php’, ‘page/2columns-right.php’, etc you will see HTML skeleton structure which has divided the page into header, footer, left column, right column, main body etc, these files make the basic skeleton of the pages in magento. You will find many $this->getChildHtml function in these templates.
The block xml tags for these pages are defined in page.xml with names
page.xml layout file, also contains an important block i.e the root block. This block is defined inside the
<block type="page/html" name="root" output="toHtml" template="page/3columns.phtml">
The root block is like the top most parent block, this block defines the structure of a page and all other block comes as children of the root block.
So, suppose if you want to set the structure of a page as 3columns, the do the below inside the page’s url tag.
<reference name="root"> <action method="setTemplate"><template>page/3columns.phtml</template></action> </reference>
Basically, this calls a function setTemplate in the root block. For example if you want the magento login page to have 3column layout. Then you need to do this
<customer_account_login> <reference name="root"> <action method="setTemplate"> <template>page/3columns.phtml</template> </action> </reference> </customer_account_login>
There are few blocks which are important in magento and widely used. For example, the content block, left, right, head (these are block name), all these blocks are defined in page.xml.
The important thing to know about these blocks is that, which ever child you add to these block, they automatically get displayed in them. You don’t need to call getChildHtml(‘childname’); ?> for these blocks.
As we know magento layout is divided in many xml files. But there are many blocks that we want to use, lets say in catalog.xml but it is are defined in a different file like page.xml. For example the head, content, root block are all defined in page.xml but we want to use them in other layout files as well.
To do this, magento has setup the reference tag. Using this tag, we can take a reference of another block and add child elements to it or do other operations on it. For example, if I want to add a block in the left column, from the catalog.xml file. I will take reference of block left, and add a child block to it.
<reference name='left'> <block type='core/template' template='catalog/test.phtml' /> </reference>
So, taken reference can be correlated, to make a copy of that block in your own xml file and doing operations on it.
<customer_account_login> <reference name='head'> <action method="addCss"><stylesheet>css/styles.css</stylesheet></action> <action method="addJs"><script>varien/js.js</script></action> </reference> </customer_account_login>
You can many other ways to add js and css files in page.xml layout file.
- By default in magento theme, the customer login page has, 1column layout. Change this to 3column layout.
- Create a new phtml file called test.phtml. With the text “Hello World” in it. This text, should come in all pages in magento. On the left column.
- Add a new css file in the skin folder called new.css, this css should be included on the checkout page and should come in no other page.