Add a new Magento CMS Template

Apr 14, 2011

MagentoI usually try and stick to the standard Magento templates where possible. The 3 column, 2 column left and right and single column layouts are nicely put together and it gives enough flexibility for most sites. I have recently been dealing with sites with landing pages that follow a single design layout but that are a bit too complicated to build from scratch each time using the single column template. So, I wondered how simple would it be to create my own template file that I can use for CMS pages, with dedicated blocks for different areas of the page. Turns out it is very simple indeed, although you do need to understand a broad set of Magento conventions – or follow a tutorial that is!

The first thing you need to do is tell Magento that there is a new template that it can use. You can do this by adding to your local.xml file. You can find the file here /app/etc/local.xml. You simply need to add a page element inside the global element that you will already find. The code below shows you how to reference your new phtml template file.

<?xml version="1.0"?>
<config>
  <global>
    ...
    <page>
      <layouts>
        <template_name>
          <label>Human Readable Template Name</label>
          <template>page/template_name.phtml</template>
        </template_name>
      </layouts>
    </page>
  </global>
  ...
</config>

Next you simply create the phtml file, probably best to copy one of the existing templates unless you are building something radically different. This file is basically just HTML plus calls to getChildHtml that add named blocks to your template that can be filled-in later using the XML layout files.

In my example I am going to create a page with two columns at the top of the page, one of which will contain the ‘content’. You probably want to keep the ‘content’ block since this will be used by the CMS. The additional blocks can be called anything you like. You can see in my code below that I mark these up with some divs so that I can style it all in my CSS.

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="<?php echo $this->getLang() ?>" lang="<?php echo $this->getLang() ?>">
<head>
<?php echo $this->getChildHtml('head') ?>
</head>
<body<?php echo $this->getBodyClass()?' class="'.$this->getBodyClass().'"':'' ?>>
<?php echo $this->getChildHtml('after_body_start') ?>
<div class="wrapper">
  <?php echo $this->getChildHtml('global_notices') ?>
  <div class="page">
    <?php echo $this->getChildHtml('header') ?>
    <div class="main-container col1-layout">
    <div class="main">
      <?php echo $this->getChildHtml('breadcrumbs') ?>
      <div class="col-main">
        <?php echo $this->getChildHtml('global_messages') ?>
        <div class="homepage_leftcol">
          <?php echo $this->getChildHtml('homepage_leftcol') ?>
        </div>
        <div class="homepage_rightcol">
          <?php echo $this->getChildHtml('content') ?>
        </div>
        <div class="homepage_fullcol">
          <?php echo $this->getChildHtml('homepage_fullcol1') ?>
        </div>
        <div class="homepage_fullcol">
          <?php echo $this->getChildHtml('homepage_fullcol2') ?>
        </div>
      </div>
    </div>
    </div>
    <?php echo $this->getChildHtml('footer') ?>
    <?php echo $this->getChildHtml('before_body_end') ?>
  </div>
</div>
<?php echo $this->getAbsoluteFooter() ?>
</body>
</html>

So, as you can see above I now have the following blocks that I can fill in using layout XML – either in my layout XML files or in the design tab of the CMS page.

  • homepage_leftcol
  • content
  • homepage_fullcol1
  • homepage_fullcol2

It is most practical for my purposes to add the layout XML to the CMS page, since these are pages designed to show of some specific products. See the screenshot below to see where I am putting these references to the block names above.

You can see in the above screenshot I have added product list blocks to the new blocks – only the blocks are referenced, using a reference. For this to work there is a final stage. The page XML layout file needs to express these blocks as core/text_list blocks so that the custom XML in the CMS page can add its bit in and the template file itself knows what to go and get when you call getChildHtml. Confusing but the following XML just needs to be added to the appropriate handle in the page.xml layout file. You could create a handle for just the places you will be using the new template but it will work just as well to add to the default handle (where you should be able to see references to your header and footer.

<block type="core/text_list" name="homepage_leftcol" as="homepage_leftcol" translate="label">
  <label>Left Col Area on Homepage Template</label>
</block>
<block type="core/text_list" name="homepage_fullcol1" as="homepage_fullcol1" translate="label">
  <label>Full Col 1 Area on Homepage Template</label>
</block>
<block type="core/text_list" name="homepage_fullcol2" as="homepage_fullcol2" translate="label">
  <label>Full Col 2 Area on Homepage Template</label>
</block>

Anyway, that’s all there is to it – I hope this proves useful to people out there working with Magento.