We use Magento to develop from small to larger e commerce web application. Magento was build based on Zend Framework. Zend Framework is an MVC framework. Magento's MVC pattern implementation is divided in three parts : Layout, Template and Block. With the combination of these three weapons you can build anything with Magento in the e commerce world. You have to grasp solid understanding of Layout, Template and Block to catch the workflow of Magento and its mechanism. If you are that you are the rock! and can be able to handle with a Magento project smoothly and I am here with you by giving a clear guide on the journey of Magento world. So, Guys, lets start to the path.
As a simplicity just keep in mind that the following four things are responsible to render a Magento page that means the work flow of Magento to frontend view.
1. The url of a Magento page that should be rendered. For example : ... /customer/account/
2. The layout xml files where the positions and locations of XML (content and structural) blocks are defined and page contents will be rendered according these content blocks which reside inside the mainframe blocks that means structural blocks. The positions and locations of these blocks are arranged within a handler. According page url, Magento internal mechanism will match which handler's content should be displayed to frontview. Layout are the breeze between blocks and templates. For example : customer.xml is a customer module's design layout update xml file which resides on app/design/frontend/base/default/layout/customer.xml. In this file customer_account_index is a handler and this will be processed to render within all of the design layout update inside it when user browse to .../customer/account/.
<layout version="0.1.0">
--- --- ---
--- --- ---
<customer_account_index translate="label">
<label>Customer My Account Dashboard</label>
<update handle="customer_account"/>
<!-- Mage_Customer -->
<reference name="root">
<action method="setTemplate"><template>page/2columns-left.phtml</template></action>
</reference>
--- --- ---
--- --- ---
</customer_account_index>
--- --- ---
--- --- ---
</layout>
3. The block classes are responsible for back end functionalities . Block classes are set in the block element of layout xml file as a block type attribute. For example : In the customer_account_index handler of customer.xml file there declared a block inside the handler like as <block type="customer/account_dashboard" name="customer_account_dashboard" template="customer/account/dashboard.phtml">. In here type="customer/account_dashboard" means it's a class resides in app/code/core/Mage/Customer/Block/Account/Dashboard.php file and the class name will be Mage_Customer_Block_Account_Dashboard. All of the outputted result processing by this class will be render in the dashboard.phtml file.
<layout version="0.1.0">
--- --- ---
--- --- ---
<customer_account_index translate="label">
<label>Customer My Account Dashboard</label>
<update handle="customer_account"/>
<!-- Mage_Customer -->
<reference name="root">
<action method="setTemplate"><template>page/2columns-left.phtml</template></action>
</reference>
<reference name="my.account.wrapper">
<block type="customer/account_dashboard" name="customer_account_dashboard" template="customer/account/dashboard.phtml">
--- --- ---
--- --- ---
</block>
</reference>
--- --- ---
--- --- ---
</customer_account_index>
--- --- ---
--- --- ---
</layout>
4. Templates are used for the output of the block classes functionalities. Inside the Layout xml file template is set in a block for which a block class type will also be assigned in that block and template will render the contents processing by that class declared as a block type . For example: In the above mentioned customer.xml layout file, the processing outputted result by Mage_Customer_Account_Dashboard class which was declared as a block type="customer/account_dashboard" will be viewed in the dashboard.phtml file which resides in the app/design/forntend/base/default/template/customer/account/dashboard.phtml. Here both attributes the type and the template are assigned in the same bock.
As a simplicity just keep in mind that the following four things are responsible to render a Magento page that means the work flow of Magento to frontend view.
1. The url of a Magento page that should be rendered. For example : ... /customer/account/
2. The layout xml files where the positions and locations of XML (content and structural) blocks are defined and page contents will be rendered according these content blocks which reside inside the mainframe blocks that means structural blocks. The positions and locations of these blocks are arranged within a handler. According page url, Magento internal mechanism will match which handler's content should be displayed to frontview. Layout are the breeze between blocks and templates. For example : customer.xml is a customer module's design layout update xml file which resides on app/design/frontend/base/default/layout/customer.xml. In this file customer_account_index is a handler and this will be processed to render within all of the design layout update inside it when user browse to .../customer/account/.
<layout version="0.1.0">
--- --- ---
--- --- ---
<customer_account_index translate="label">
<label>Customer My Account Dashboard</label>
<update handle="customer_account"/>
<!-- Mage_Customer -->
<reference name="root">
<action method="setTemplate"><template>page/2columns-left.phtml</template></action>
</reference>
--- --- ---
--- --- ---
</customer_account_index>
--- --- ---
--- --- ---
</layout>
3. The block classes are responsible for back end functionalities . Block classes are set in the block element of layout xml file as a block type attribute. For example : In the customer_account_index handler of customer.xml file there declared a block inside the handler like as <block type="customer/account_dashboard" name="customer_account_dashboard" template="customer/account/dashboard.phtml">. In here type="customer/account_dashboard" means it's a class resides in app/code/core/Mage/Customer/Block/Account/Dashboard.php file and the class name will be Mage_Customer_Block_Account_Dashboard. All of the outputted result processing by this class will be render in the dashboard.phtml file.
<layout version="0.1.0">
--- --- ---
--- --- ---
<customer_account_index translate="label">
<label>Customer My Account Dashboard</label>
<update handle="customer_account"/>
<!-- Mage_Customer -->
<reference name="root">
<action method="setTemplate"><template>page/2columns-left.phtml</template></action>
</reference>
<reference name="my.account.wrapper">
<block type="customer/account_dashboard" name="customer_account_dashboard" template="customer/account/dashboard.phtml">
--- --- ---
--- --- ---
</block>
</reference>
--- --- ---
--- --- ---
</customer_account_index>
--- --- ---
--- --- ---
</layout>
4. Templates are used for the output of the block classes functionalities. Inside the Layout xml file template is set in a block for which a block class type will also be assigned in that block and template will render the contents processing by that class declared as a block type . For example: In the above mentioned customer.xml layout file, the processing outputted result by Mage_Customer_Account_Dashboard class which was declared as a block type="customer/account_dashboard" will be viewed in the dashboard.phtml file which resides in the app/design/forntend/base/default/template/customer/account/dashboard.phtml. Here both attributes the type and the template are assigned in the same bock.
Figure: Magento templates, blocks and layouts work flow.
Let's digging a deeper how this trilogy work together :
First and foremost, we need to understand that the complexity of the layout, block, phtml (template) relationship is necessary, powerful, and flexible. These three pieces allow to develop 'theme' in Magento and so we can easily override pieces of the store's ( e commerce application by Magento ) look n feel without messing default Magento's layouts, blocks and templates. Before we dive deep inside Magento, it will be helpful if we understand where to look for what of some important folder structures of Magento.
The top root folder app is the heart of Magento and it contains all application development related files. Below mentioned some important folders structure of Magento.
( i ) app/etc/modules contains all module loading configuration files to show on/off in the admin panel (admin/System/Configuration/Advanced/Modules Output ). If we want to create custom module we also need to create our custom loading configuration xml file inside the app/etc/modules. All default modules loading configuration xml files come with the Magento are mostly prefixed with "Mage_".
Example : Mage_All.xml
We can know from the Mage_All.xml file that the default customer module is declared in the system and it resides in the core codepool (app/code/core/Mage/Customer) with the following code and Magento have been identified this module declared in the app/etc/module/Mage_All.xml file.
<config>
<modules>
--- --- ---
<Mage_Customer>
<active>true</active>
<codePool>core</codePool>
<depends>
<Mage_Eav/>
<Mage_Dataflow/>
<Mage_Directory/>
</depends>
</Mage_Customer>
--- --- ---
</modules>
</config>
( ii ) app / code / core / Mage / (Module) / etc contains configuration of modules. All of the Magento's default modules configuration xml files will reside here. We need to put our custom module configuration xml files inside app/code/local/CustomModulePackage/ CustomModule/etc.
Example : app / code / core / Mage / Customer / etc / config.xml
Though Magento have been identified the customer module declared in the Mage_All.xml now it will load the cutomer's config.xml file that means after knowing the declaration of customer module in app/etc/modules/Mage_All.xml file Magento is going to look for the customer module itself defined in the app/code/core/Mage/Customer/etc/config.xml file which contains the actual configuration information for a module. Look at the config.xml below of customer module. It has defined its own layout xml file for template as customer.xml inside the <frontend> </frontend> element and this customer.xml design layout update will be reside in the app/design/frontend/themepackage/themename/layout/customer.xml. For Magento default installed it will be app/design/frontend/base/default/layout/customer.xml.
<config>
<modules>
<Mage_Customer>
<version>1.6.2.0.3</version>
</Mage_Customer>
</modules>
<admin>
--- --- ---
--- --- ---
</admin>
<global>
--- --- ---
--- --- ---
<blocks> </blocks>
<models> </models>
<template></template>
--- --- ---
--- --- ---
</global>
--- --- ---
--- --- ---
<frontend>
--- --- ---
--- --- ---
<layout>
<updates>
<customer module="Mage_Customer">
<file>customer.xml</file>
</customer>
</updates>
</layout>
</frontend>
<default>
--- --- ---
--- --- ---
</default>
</config>
( iii ) app / code / core / Mage / (Module) / controllers contains Controllers action provided by module. Before rendering, Magento loads all configured layout update files ( for example : config.xml ) and its design layout update files ( for example : customer.xml) to determine which block is to be rendered at which location and which layout handle needs to be processed. So, in here the layout handle selection process is based on the controller action being executed. In most cases, Magento loads the layout handle with name : [module_front_name]_[controller_name]_[action_name]. The action methods define in the controller class are mapped with the requested URL and perform the backend processing for the current requested page like retrieving and storing data from/to the database. Before rendering Magento creates Layout Instance and Layout Update Instance. Layout Instance is responsible to page render and Layout Update Instance contains the data of all layout handles added to the current page. Two method of action controller $this->loadLayout() and $this->renderLayout() work with these Layout Instance and Layout Update Instance for initializing the layout.
Example: app/code/core/Mage/Customer/AccountController.php
When the customer account index page is requested, then indexAction of AccountController controller (app/code/core/Mage/Customer/AccountController.php) of Mage_Customer module is executed. Module front name of Mage_Customer is customer. So the layout handle to be processed for the customer account index page will be customer_account_index. indexAction( ) function has been defined inside the Mage_Customer_AccountController class which extends the core controller class of Magento Mage_Core_Controller_Front_Action in the AccountController.php file.
public function indexAction()
{
$this->loadLayout();
$this->_initLayoutMessages('customer/session');
$this->_initLayoutMessages('catalog/session');
$this->getLayout()->getBlock('content')->append(
$this->getLayout()->createBlock('customer/account_dashboard')
);
$this->getLayout()->getBlock('head')->setTitle($this->__('My Account'));
$this->renderLayout();
}
ow programmatically custom layout block type can be created ( customer/account_dashboard ) and this block type has been used inside the customer_account_index handler in the customer.xml design layout update file as the name "customer_account_dashboard" block : NOTE : Look at the above code snippet, h
<layout version="0.1.0">
--- --- ---
--- --- ---
<customer_account_index translate="label">
--- --- ---
--- --- ---
<block type="customer/account_dashboard" name="customer_account_dashboard" template="customer/account/dashboard.phtml">
--- --- ---
--- --- ---
</block>
--- --- ---
--- --- ---
</customer_account_index>
--- --- ---
--- --- ---
</layout>
( iv ) app / code / core / Mage / (Module) / Block contains classes of logic block. Magento use these block classes when block type defined in the block element of design layout update xml file and this type attribute defines the block class name. Each block may have its specific features that should be shown on the related page. Block classes do the backend functionalities job and template attribute defines the actual phtml template file to be used for rendering the block.
Example : app/code/core/Mage/ Customer/ Block/Account/Dashboard.php
In the above code snippet of customer_account_index handler, a new block was created and the block type defined as "customer/account_dashboard". So, Magento will look for the class of this newly created block regarding type attribute inside the Magento default module block classes folder. For "customer/account_dashboard" block type it will look for the appropriate block class "Mage_Customer_Block_Account_Dashboard" in the app/code/core/Mage/Customer/Block/Account/Dashboard.php file.
Let's see the another block type declared inside the customer_account_index handler in the customer.xml file as follow :
<block type="customer/account_dashboard_newsletter" name="customer_account_dashboard_newsletter" as="newsletter" template="customer/account/dashboard/newsletter.phtml"/>. Class file path for this block type would be app/code/core/Mage/Customer/Block/Account/Dashboard/Newsletter.php and the appropriate block class "Mage_Customer_Block_Account_Dashboard_Newsletter".
Usually block classes are inherited from magento core block class "Mage_Core_Block_Template" which resides on app/code/core/Mage/Core/Block/Template.php file. Block classes are named in Magento like "Mage_ModuleName_Block_Classname". Each block type is mapped to the appropriate block class with appropriate file path.
For better understanding below are given some example of Magento Customer module block types declared in the customer.xml file which are mapped with appropriate block classes and folders structure. For All other Magento module the convention of class naming and file path structure regarding block types will be the same way.
First and foremost, we need to understand that the complexity of the layout, block, phtml (template) relationship is necessary, powerful, and flexible. These three pieces allow to develop 'theme' in Magento and so we can easily override pieces of the store's ( e commerce application by Magento ) look n feel without messing default Magento's layouts, blocks and templates. Before we dive deep inside Magento, it will be helpful if we understand where to look for what of some important folder structures of Magento.
The top root folder app is the heart of Magento and it contains all application development related files. Below mentioned some important folders structure of Magento.
( i ) app/etc/modules contains all module loading configuration files to show on/off in the admin panel (admin/System/Configuration/Advanced/Modules Output ). If we want to create custom module we also need to create our custom loading configuration xml file inside the app/etc/modules. All default modules loading configuration xml files come with the Magento are mostly prefixed with "Mage_".
Example : Mage_All.xml
We can know from the Mage_All.xml file that the default customer module is declared in the system and it resides in the core codepool (app/code/core/Mage/Customer) with the following code and Magento have been identified this module declared in the app/etc/module/Mage_All.xml file.
<config>
<modules>
--- --- ---
<Mage_Customer>
<active>true</active>
<codePool>core</codePool>
<depends>
<Mage_Eav/>
<Mage_Dataflow/>
<Mage_Directory/>
</depends>
</Mage_Customer>
--- --- ---
</modules>
</config>
( ii ) app / code / core / Mage / (Module) / etc contains configuration of modules. All of the Magento's default modules configuration xml files will reside here. We need to put our custom module configuration xml files inside app/code/local/CustomModulePackage/ CustomModule/etc.
Example : app / code / core / Mage / Customer / etc / config.xml
Though Magento have been identified the customer module declared in the Mage_All.xml now it will load the cutomer's config.xml file that means after knowing the declaration of customer module in app/etc/modules/Mage_All.xml file Magento is going to look for the customer module itself defined in the app/code/core/Mage/Customer/etc/config.xml file which contains the actual configuration information for a module. Look at the config.xml below of customer module. It has defined its own layout xml file for template as customer.xml inside the <frontend> </frontend> element and this customer.xml design layout update will be reside in the app/design/frontend/themepackage/themename/layout/customer.xml. For Magento default installed it will be app/design/frontend/base/default/layout/customer.xml.
<config>
<modules>
<Mage_Customer>
<version>1.6.2.0.3</version>
</Mage_Customer>
</modules>
<admin>
--- --- ---
--- --- ---
</admin>
<global>
--- --- ---
--- --- ---
<blocks> </blocks>
<models> </models>
<template></template>
--- --- ---
--- --- ---
</global>
--- --- ---
--- --- ---
<frontend>
--- --- ---
--- --- ---
<layout>
<updates>
<customer module="Mage_Customer">
<file>customer.xml</file>
</customer>
</updates>
</layout>
</frontend>
<default>
--- --- ---
--- --- ---
</default>
</config>
( iii ) app / code / core / Mage / (Module) / controllers contains Controllers action provided by module. Before rendering, Magento loads all configured layout update files ( for example : config.xml ) and its design layout update files ( for example : customer.xml) to determine which block is to be rendered at which location and which layout handle needs to be processed. So, in here the layout handle selection process is based on the controller action being executed. In most cases, Magento loads the layout handle with name : [module_front_name]_[controller_name]_[action_name]. The action methods define in the controller class are mapped with the requested URL and perform the backend processing for the current requested page like retrieving and storing data from/to the database. Before rendering Magento creates Layout Instance and Layout Update Instance. Layout Instance is responsible to page render and Layout Update Instance contains the data of all layout handles added to the current page. Two method of action controller $this->loadLayout() and $this->renderLayout() work with these Layout Instance and Layout Update Instance for initializing the layout.
Example: app/code/core/Mage/Customer/AccountController.php
When the customer account index page is requested, then indexAction of AccountController controller (app/code/core/Mage/Customer/AccountController.php) of Mage_Customer module is executed. Module front name of Mage_Customer is customer. So the layout handle to be processed for the customer account index page will be customer_account_index. indexAction( ) function has been defined inside the Mage_Customer_AccountController class which extends the core controller class of Magento Mage_Core_Controller_Front_Action in the AccountController.php file.
public function indexAction()
{
$this->loadLayout();
$this->_initLayoutMessages('customer/session');
$this->_initLayoutMessages('catalog/session');
$this->getLayout()->getBlock('content')->append(
$this->getLayout()->createBlock('customer/account_dashboard')
);
$this->getLayout()->getBlock('head')->setTitle($this->__('My Account'));
$this->renderLayout();
}
ow programmatically custom layout block type can be created ( customer/account_dashboard ) and this block type has been used inside the customer_account_index handler in the customer.xml design layout update file as the name "customer_account_dashboard" block : NOTE : Look at the above code snippet, h
<layout version="0.1.0">
--- --- ---
--- --- ---
<customer_account_index translate="label">
--- --- ---
--- --- ---
<block type="customer/account_dashboard" name="customer_account_dashboard" template="customer/account/dashboard.phtml">
--- --- ---
--- --- ---
</block>
--- --- ---
--- --- ---
</customer_account_index>
--- --- ---
--- --- ---
</layout>
( iv ) app / code / core / Mage / (Module) / Block contains classes of logic block. Magento use these block classes when block type defined in the block element of design layout update xml file and this type attribute defines the block class name. Each block may have its specific features that should be shown on the related page. Block classes do the backend functionalities job and template attribute defines the actual phtml template file to be used for rendering the block.
Example : app/code/core/Mage/ Customer/ Block/Account/Dashboard.php
In the above code snippet of customer_account_index handler, a new block was created and the block type defined as "customer/account_dashboard". So, Magento will look for the class of this newly created block regarding type attribute inside the Magento default module block classes folder. For "customer/account_dashboard" block type it will look for the appropriate block class "Mage_Customer_Block_Account_Dashboard" in the app/code/core/Mage/Customer/Block/Account/Dashboard.php file.
Let's see the another block type declared inside the customer_account_index handler in the customer.xml file as follow :
<block type="customer/account_dashboard_newsletter" name="customer_account_dashboard_newsletter" as="newsletter" template="customer/account/dashboard/newsletter.phtml"/>. Class file path for this block type would be app/code/core/Mage/Customer/Block/Account/Dashboard/Newsletter.php and the appropriate block class "Mage_Customer_Block_Account_Dashboard_Newsletter".
Usually block classes are inherited from magento core block class "Mage_Core_Block_Template" which resides on app/code/core/Mage/Core/Block/Template.php file. Block classes are named in Magento like "Mage_ModuleName_Block_Classname". Each block type is mapped to the appropriate block class with appropriate file path.
For better understanding below are given some example of Magento Customer module block types declared in the customer.xml file which are mapped with appropriate block classes and folders structure. For All other Magento module the convention of class naming and file path structure regarding block types will be the same way.
Block type <block type ="customer/form_login" template="customer/form/login.phtml" /> <block type ="customer/form_register" template="customer/form/login.phtml" /> <block type ="customer/account_forgotpassword" template="customer/form/forgotpassword.phtml" /> <block type="customer/account_dashboard_address" as="address" template="customer/account/dashboard/address.phtml"/> <block type="customer/address_book" template="customer/address/book.phtml"/> | Block class Mage_Customer_Block_Form_Login Mage_Customer_Block_Form_Register Mage_Customer_Block_Account_Forgotpassword Mage_Customer_Block_Account_Dashboard_Address Mage_Customer_Block_Address_Book | Block class path app/code/core/Mage/Customer/Block/Form/Login.php app/code/core/Mage/Customer/Block/Form/Register.php app/code/core/Mage/Customer/Block/Account/Forgotpassword.php app/code/core/Mage/Customer/Block/Account/Dashboard/Address.php app/code/core/Mage/Customer/Block/Address/Book.php |
Besides the module based block types Magento defines some built-in block types which are widely used in layout.
In this series of article part 1, I have just explored to introduce how the layout, template, blocks are internally designed to achieve the maximum flexibility of theme development. The file and folder structure of these trilogy mapping with each other according Magento convention and the interconnection of these pieces first time seems complex but the far you dig the far you realize how easy are they to make the theme design modular. In the next part of this series we will cover more advance usage of layout, template and block. Hope you will read through them all. Thanks.
saifulmasud
june 16, 2014
Coming up next : Magento Layout, Template, Block Details - Understanding and Creating Custom Block, Part 2
- core/template: This block renders a template defined by its template attribute. The majority of blocks defined in the layout are of type or subtype of core/template.
- page/html: This is a subtype of core/template and defines the root block. All other blocks are child blocks of this block.
- page/html_head: Defines the HTML head section of the page which contains elements for including JavaScript, CSS etc.
- page/html_header: Defines the header part of the page which contains the site logo, top links, etc.
- page/template_links: This block is used to create a list of links. Links visible in the footer and header area use this block type.
- core/text_list: Some blocks like content, left, right etc. are of type core/text_list. When these blocks are rendered, all their child blocks are rendered automatically without the need to call the getChildHtml() method.
- page/html_wrapper: This block is used to create a wrapper block which renders its child blocks inside an HTML tag set by the action setHtmlTagName. The default tag is <div> if no element is set.
- page/html_breadcrumbs: This block defines breadcrumbs on the page.
- page/html_footer: Defines footer area of page which contains footer links, copyright message etc.
- core/messages: This block renders error/success/notice messages.
- page/switch: This block can be used for the language or store switcher.
In this series of article part 1, I have just explored to introduce how the layout, template, blocks are internally designed to achieve the maximum flexibility of theme development. The file and folder structure of these trilogy mapping with each other according Magento convention and the interconnection of these pieces first time seems complex but the far you dig the far you realize how easy are they to make the theme design modular. In the next part of this series we will cover more advance usage of layout, template and block. Hope you will read through them all. Thanks.
saifulmasud
june 16, 2014
Coming up next : Magento Layout, Template, Block Details - Understanding and Creating Custom Block, Part 2