3.2 Directory Climbing in Magento Layout
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
1
2
3
4
5
6
7
8
9
|
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
1
2
|
# 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.
1
2
3
4
5
6
7
8
9
10
|
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!