Magento structural blocks, content blocks and phtml templates

11,693

There are mainly two types of blocks in Magento

  1. Structural blocks :- These blocks actually defines the structure of a page block. This is where content blocks resides

    Example : Header, Left, Right, Footer and Main blocks (defines in page.xml)

  2. Content blocks :- These blocks are actually holding the content. Depends upon the type of block, the content hold by these block varies

    Example :- Any custom blocks, core/template block, cms/page block etc.

Normally every content block should come under any of the strucural block that described above. These content block holds different contents depend upon its type. For example, a cms/page block is intend to hold cms page content that we set through admin section. catalog/product_view block is used to hold a product view contents. As you already noted these two content blocks use to hold contents but the content differes from block to block, depending on its type specified. With that said let us look on your problem

1) Structural blocks holds structures of a page. Content block comes under each structual block. So in the above layout code, the block with type page/html_header is a structural block. While all other blocks that come inside this block are content blocks of above structural block. In other words they are children of the header structural block. Now let us look on this header block at backside.

#File : app/code/core/Mage/Page/Block/Html/Header.php
<?php
class Mage_Page_Block_Html_Header extends Mage_Core_Block_Template
{
    public function _construct()
    {
        $this->setTemplate('page/html/header.phtml');
    }

    ......
}

There it is. Our structural block is actually assigned with a template through backend. This means the template that correspond to our header block resides in app/design/frontend/<your_package>/<your_theme>/template/page/html/header.phtml. If you open that file, you can see that the template is actually defining the header portion of our page using html, css and js and invoking its child blocks using a method getChildHtml(). Some portion of above file is shown below.

.....
<div class="quick-access">
            <?php echo $this->getChildHtml('topSearch') ?>
            <p class="welcome-msg"><?php echo $this->getChildHtml('welcome') ?> <?php echo $this->getAdditionalHtml() ?></p>
            <?php echo $this->getChildHtml('topLinks') ?>
            <?php echo $this->getChildHtml('store_language') ?>

            .....
</div>

.....

As you can see above, it invokes child blocks(in other words content blocks) that are defined in page.xml layout file, using getChildHtml() method.

This means, if you add a custom child block inside the header structural block and didn't invoke it in header.phtml using getChildHtml() method, your content block is not going to show in frontend.

You can also set header.phtml to the block header through page.xml like this

<block type="page/html_header" name="header" as="header" template="page/html/header.phtml" />

There is no issue with this. So in short, we cannot generally say that a block that defines a phtml file is either a content block or a strutural block. How both of these block defferes purely depends on what those block holds.

Short Note : A cotent block can contain other content blocks. What we are doing is most of the time is this. Means adding our custom content block to another content block that already existing in magento.

2) If you look on different blocks in magento, you can see that, irrespective of structural block/content block, a block can set with a template through layout or through backend. We can set template to a block using an observer also. I already stated how header structural block set with the template header.phtml . In this case it is through backend side.

Hopes that helps you to understand the concept.

EDIT

No you are absoulutely wrong. In magento layout holds the entire structure of a page. It holds all the blocks that need to render for a particular page.

Suppose you have a url www.mydomain.com/index.php/customer/account. What magento does now is it will split the url and find which module generates such url. So here above url split like this

base url => www.mydomain.com/index.php/
frontend name => customer/
action controller name => account/
method => index/

Now magento will query for which module that is responsible for frontend name customer. It is defined by Mage_Customer core module. Now magento look for which controller that handles this url. In our url, the part that mention this is account. So it will look for AccountController.php file in Mage_Customer module. Now again magento look for whcih method that handles the url. But in our url there is no method specified. So it will assume the method index hence. Now look on that method.

#File:app/code/core/Mage/Customer/controllers/AccountController.php
/**
 * Default customer account page
 */
public function indexAction()
{
    $this->loadLayout();

    // some other codes

    $this->renderLayout();
}

This is the important section. First the method calls a function loadLayout(). This simple code does a lot of work behind the curton. It will generate a big layout tree that is correspond to the page that is going to show in frontend. Where is this layouts are defined ? Of course.. It is in layout XML files. Layout xml file defines what are the blocks that should render for this above url and what are not. For an example in this context, follwing handles will be processed by magento.

default
STORE_default
THEME_frontend_default_default
customer_account_index
customer_logged_in
customer_account

Magento will generate a huge layout tree that will consist of all blocks that is specified under these layout handles. Layout handles may come in any layout XML file that comes under the directory app/design/frontend/<your_package>/<your_theme>/layout. After creating this layout tree, magento will render these layout tree using the code renderLayout(). Basically what it will do is convert these layout into html and render it (For this it uses template files and skin).

Now what would you think ? Layout XMLs are that simple? :)

Share:
11,693
aDvo
Author by

aDvo

SAP HCM Mobile Development Drupal Cakephp Fitness freak

Updated on June 04, 2022

Comments

  • aDvo
    aDvo almost 2 years

    I've just started reading up on Magentos (1.9 CE) layout and how it works with the XML and PHTML files. I've come across the structural blocks and content blocks.

    I'm looking at the page.xml file of Magento 1.9 installed RWD package DEFAULT theme. I've pasted below what i believe is the header, content, and footer from the page.xml file.

    My questions 1) Is a block considered to be a content block the moment it is assigned a "template="XXXX.phtml" attribute? EAnd if not, it is known as a structural block?

    2) For structural blocks that don't have the template="XXX", how does it ultimately link with the phtml files? My question comes from the context of looking at the header block as seen below, some of its sub blocks have "template" attribute, but none of them seem to point to the header.phtml from "\template\page\html" directory, which i have been editing to customize the look of the Magento site Welcome message.

    <block type="page/html_header" name="header" as="header">
        <block type="page/template_links" name="top.links" as="topLinks"/>
        <block type="page/switch" name="store_language" as="store_language" template="page/switch/languages.phtml"/>
        <block type="core/text_list" name="top.menu" as="topMenu" translate="label">
            <label>Navigation Bar</label>
            <block type="page/html_topmenu" name="catalog.topnav" template="page/html/topmenu.phtml">
                <block type="page/html_topmenu_renderer" name="catalog.topnav.renderer" template="page/html/topmenu/renderer.phtml"/>
            </block>
        </block>
        <block type="page/html_wrapper" name="top.container" as="topContainer" translate="label">
            <label>Page Header</label>
            <action method="setElementClass"><value>top-container</value></action>
        </block>
        <block type="page/html_welcome" name="welcome" as="welcome"/>
    </block>
    
    
    
    <block type="core/text_list" name="content" as="content" translate="label">
        <label>Main Content Area</label>
    </block>
    
    
    <block type="page/html_footer" name="footer" as="footer" template="page/html/footer.phtml">
        <block type="page/html_wrapper" name="bottom.container" as="bottomContainer" translate="label">
            <label>Page Footer</label>
            <action method="setElementClass"><value>bottom-container</value></action>
        </block>
        <block type="page/switch" name="store_switcher" as="store_switcher" after="*" template="page/switch/stores.phtml"/>
        <block type="page/template_links" name="footer_links" as="footer_links" template="page/template/links.phtml">
            <action method="setTitle"><title>Quick Links</title></action>
        </block>
        <block type="page/template_links" name="footer_links2" as="footer_links2" template="page/template/links.phtml">
            <action method="setTitle"><title>Account</title></action>
        </block>
        <!-- This static block can be created and populated in admin. The footer_links cms block can be used as a starting point. -->
        <!--<block type="cms/block" name="footer_social_links">
            <action method="setBlockId"><block_id>footer_social_links</block_id></action>
        </block>-->
    </block>
    
  • aDvo
    aDvo over 9 years
    Hi @programmer_rkt. Thanks for the thorough explanationputs things into context greatly for me. Please tell me if my understanding is correct: I'm used to MVC, and i now understand that the XML layout files have almost nothing to do with actual visible layout on the site, but has more to do with determining what is "available" to be used. And what is available and ultimately used, depends on what the PHP code actually called within phtml file. And the relationship to "which phtml" file can be done either via the backend or via the XML files in the template attribute. Do i make sense?
  • Rajeev K Tomy
    Rajeev K Tomy over 9 years
    No. In magento, the entire layout hold by a layout file. Without layout file you cannot see anything frontend and backend. Actually depend upon each request through url, magento generates a corresponding layout tree and then convert it to html and then renders. See my Update.
  • aDvo
    aDvo over 9 years
    That does make things much clearer. Thanks for the wonderful insight @programmer_rkt !
  • sunny
    sunny over 9 years
    Awesome explaination dude!thats cleared a lot of concepts for me!
  • Rajeev K Tomy
    Rajeev K Tomy over 9 years
    @sunny : Happy to hear :)