Why changing the root template doesn't work
Both
Mage_Cms_IndexController::indexAction()
and
Mage_Cms_IndexController::viewAction()
which are responsible for displaying the default homepage and a CMS page respectively call a helper:
Mage::helper('cms/page')->renderPage($this, $pageId)
If you jump into the helper (located at app/code/core/Mage/Cms/Helper/Page.php) and follow renderPage()
to the protected method _renderPage()
you'll see that Magento is checking two times for a root template (Magento CE 1.7.0.2):
if ($page->getRootTemplate()) {
$handle = ($page->getCustomRootTemplate()
&& $page->getCustomRootTemplate() != 'empty'
&& $inRange) ? $page->getCustomRootTemplate() : $page->getRootTemplate();
$action->getLayout()->helper('page/layout')->applyHandle($handle);
}
and
if ($page->getRootTemplate()) {
$action->getLayout()->helper('page/layout')
->applyTemplate($page->getRootTemplate());
}
Both calls happen after layout handles like "cms_page" and the like are processed, so you are out of luck here.
What you can do to change the root template
There is an event cms_page_render
which you can use for adding your own XML layout handle on CMS pages. Create your own extension (I'll spare some details here) and configure the event observer in your config.xml
:
<?xml version="1.0"?>
<config>
<modules>
<Emzee_Cms>
<version>0.0.1</version>
</Emzee_Cms>
</modules>
<global>
<events>
<cms_page_render>
<observers>
<emzee_cms_page_render>
<class>emzee_cms/observer</class>
<method>cms_page_render</method>
</emzee_cms_page_render>
</observers>
</cms_page_render>
</events>
<models>
<emzee_cms>
<class>Emzee_Cms_Model</class>
</emzee_cms>
</models>
</global>
</config>
Add your event observer:
<?php
class Emzee_Cms_Model_Observer
{
public function cms_page_render(Varien_Event_Observer $observer)
{
$action = $observer->getEvent()->getControllerAction();
$actionName = strtolower($action->getFullActionName());
$action->getLayout()->getUpdate()
->addHandle($actionName . '_after');
return $this;
}
}
Finally, add your new layout XML handle (e.g. in your local.xml
):
<?xml version="1.0"?>
<layout version="0.1.0">
<cms_index_index_after>
<reference name="root">
<action method="setTemplate"><template>page/1column.phtml</template></action>
</reference>
</cms_index_index_after>
</layout>
You can use this method as well to add a cms_page_view_after
handle or create page specific handles as cms_page_render
passes the $page
object to your observer.
Why you can't add a block to the 'reference left'
Are you sure that the template you're using has a left column? This question may sound silly but the default "2 columns with right bar" layout for example only offers a 'content' and a 'right' area. I can add blocks to the right column using cms_page
without problems so this could be the problem.
In general, you can only easily add blocks to references and echo them if
- the chosen root template uses the block you're referencing (see
app/design/frontend/base/default/template/page/*.phtml
) and
- the block you're referencing either is of type
core/text_list
, calls $this->getChildhtml()
without arguments or does something else to echo all child blocks.
Without further details, I can't tell you why your blocks are not echo'd in the left or right column.
Yes of course, bu not page title, you can move content heading. In that case local.xml cannot affect to cms page, because of it is loaded before cms.xml. You should edit cms.xml as following:
<cms_page translate="label">
<label>CMS Pages (All)</label>
<reference name="left">
<block type="core/template" name="page_content_heading" template="cms/content_heading.phtml" before="tags_popular"/>
<remove name="catalog.compare.sidebar"/>
</reference>
<reference name="content">
<block type="page/html_wrapper" name="cms.wrapper" translate="label">
<label>CMS Content Wrapper</label>
<action method="setElementClass">
<value>std</value>
</action>
<block type="cms/page" name="cms_page"/>
</block>
</reference>
</cms_page>
You should change layout of cms page via admin.
Best Answer
You can't do this with a simple layout update xml. The easiest way to achieve this is create a new root template specific to your cms page. Steps for this is given below.
1. Layout Update XML File
Go to
CMS > Pages > [Select your CMS Page] > Design > Layout Update XML
section. Put this layout update code there.This code basically performs 3 actions.
It removes the default CMS Page heading block from layouts; So it will eventually removes the default title section that you are viewing in your cms page.
It defines a new root template,
custom/page/cms_1column.phtml
for your CMS Page; I will explain why we need this.We are again redefining CMS Page heading block, but this time it comes inside
root
block and not insidecontent
block.2. Define Custom Root Template
Now create a new file
app\design\frontend\[package]\[theme]\template\custom/page/cms_1column.phtml
and copy paste all content ofapp\design\frontend\[package]\[theme]\template\page/1column.phtml
to that file. Then call our heading block inside that file as like this.As you can see
<?php echo $this->getChildHtml('cms_page_heading') ?>
this part renders the CMS Page heading block and it comes above layout-div block. You can adjust the position of your CMS page heading block according to your need as per your need.We are using a new root template only for adding this custom CMS Page heading block. This will avoid touching of core files and hence would be the best solution in this case.