Categories


Archives


Recent Posts


Categories


Directory Climbing in Magento Layout

astorm

Frustrated by Magento? Then you’ll love Commerce Bug, the must have debugging extension for anyone using Magento. Whether you’re just starting out or you’re a seasoned pro, Commerce Bug will save you and your team hours everyday. Grab a copy and start working with Magento instead of against it.

No Frills Magento Layout is the only Magento front end book you'll ever need. Get your copy today!

Just a quick note on some updates I’ve made to the Layouts, Blocks and Templates article.

Previously, the example code given had demoed a technique for storing your phtml template files along with your module files by climbing the directory tree up to app/, and then back down to your module

template="../../../../../code/local/[etc...]"

One of the early Magento Books I’d read included the technique, and demoing it in the article re-enforced where Magento stored its templates in relation to module files.

I’ve since rewritten the article to remove all references to it, as the technique no longer works in more recent versions of Magento. If you take a look at the core Template block class

File: app/code/core/Mage/Core/Block/Template.php
...
$includeFilePath = realpath($this->_viewDir . DS . $fileName);
if (strpos($includeFilePath, realpath($this->_viewDir)) === 0) {
    include $includeFilePath;
} else {
    Mage::log('Not valid template file:'.$fileName, Zend_Log::CRIT, null, null, true);
}
...

you can see there’s a conditional check before the include. Prior to including the phtml template, Magento is checking to make sure that the constructed include path matches the base view directory. Because realpath is being used, all the ../..s are stripped off, resulting in a conditional statement something like

#if (strpos($includeFilePath, realpath($this->_viewDir)) === 0) {
if (strpos('app/code/local[etc...]', realpath('app/design/frontend[etc...]')) === 0) {

This is, all things considered, for the best. Although convenient, climbing relative directory paths with .. in PHP usually leads to trouble down the line.

Additionally, if you really want Blocks that read from folders in your Module, extending the base template Block and redefining fetchView is probably the better approach.

class My_Module_Block_Template extends Mage_Core_Block_Template
{
    public function fetchView($fileName)    
    {    
        //ignores file name, just uses a simple include with template name
        $this->setScriptPath(Mage::getModuleDir('', 'My_Module') . DS . 'templates');    
        return parent::fetchView($this->getTemplate());
    } 

}

So that’s that. If you’re still having trouble getting through the Layout tutorial please let me know and we’ll get to the bottom of things. See you all in LA for Imagine!

Originally published February 5, 2011

Copyright © Alan Storm 1975 – 2017 All Rights Reserved

Originally Posted: 5th February 2011