Magento Version: 1.6.rc1+
I just downloaded the release candidate for Magento 1.6, and I noticed a change that seemed like a regression, but a little digging made me realize it was something else.
A lot of Magento developers (meaning me) like keeping their custom phtml
files somewhere other than the the standard add/design/frontend
file hierarchy. They accomplish this though symlinks, or by creating custom block objects that look elsewhere for the files.
However, in the 1.4 branch of community edition, this changed. Before rendering a block template, Magento started checking if the phtml
file was located in the view directory, and they used PHP’s realpath
function to normalize the directory string.
File: app/code/core/Mage/Core/Block/Template.php
...
$includeFilePath = realpath($this->_viewDir . DS . $fileName);
if (strpos($includeFilePath, realpath($this->_viewDir)) === 0) {
...
No more symlinks. You could still redefine fetchView
in your own blocks to take this into account and store your files elsewhere, which I did.
In the 1.5 branch, this code was altered slightly.
if (strpos($includeFilePath, realpath($this->_viewDir)) === 0 || $this->_getAllowSymlinks()) {
The _getAllowSymlinks
method
const XML_PATH_TEMPLATE_ALLOW_SYMLINK = 'dev/template/allow_symlink';
protected function _getAllowSymlinks()
{
if (is_null($this->_allowSymlinks)) {
$this->_allowSymlinks = Mage::getStoreConfigFlag(self::XML_PATH_TEMPLATE_ALLOW_SYMLINK);
}
return $this->_allowSymlinks;
}
checks for a config flag, and if it’s true allows the template file to render from a symlinked path. Yay for symlinks.
Turns out Magento 1.6 takes this a step further, and add the same check to setScriptPath
public function setScriptPath($dir)
{
$scriptPath = realpath($dir);
if (strpos($scriptPath, realpath(Mage::getBaseDir('design'))) === 0 || $this->_getAllowSymlinks()) {
$this->_viewDir = $dir;
} else {
Mage::log('Not valid script path:' . $dir, Zend_Log::CRIT, null, null, true);
}
return $this;
}
This is what was tripping me up, even with an overridden fetchView
, this check would stop my templates from rendering in app/code/pool/Package/Module
.
Flipping this config bit at
System -> Configuration -> Developer -> Template Settings
or redefining _getAllowSymlinks
in your own blocks
protected function _getAllowSymlinks()
{
return true;
}
should take care of this. That said, there’s probably a reason the core team wants to discourage template use outside of the approved directory, and it’s making me re-consider my placement of templates.
Here’s looking forward to Magento 2, where frontend files will be packaged up along with code modules!