Magento: Standard OOP Still Applies
Like this article? 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.
One trap a lot of people (myself included) fall into with Magento is forgetting that sometimes the best solution is just basic, standard PHP OOP. There was a Stack Overflow question where this came up in the comments, and I figured I’d wrangle a blog post out of it.
So, is sounds like the original poster wants to conditionally change the appearance of the customer_account_login page. If we take a look at the layout XML, we can see this is a pretty simple page.
<reference name="content">
<block type="customer/form_login" name="customer_form_login" template="customer/form/login.phtml"/>
</reference>
The Layout Update XML gets a reference to the content block, and then adds a customer/form_login block to the page. The poster’s solution to this was to setup an observer that would look for a particular handle, and then manipulate the layout directly.
A simpler approach would be to remove the block that’s been added, re-add another customer block, and then include code in that custom block to conditionally change the appearance of the page.
Note: This is slightly tipsy pseudo code, so problems and corrections are appreciated
First step, add this to a module’s XML Layout file (or local.xml, if you’re just working locally)
<customer_account_login>
<reference name="content">
<action method="removeChild"><name>customer_form_login</name></action>
<block type="yourmodule/form_login" name="customer_form_login" template="customer/form/login.phtml"/>
</reference>
</customer_account_login>
This removed the customer login block, and then immediately re-adds it using a different block alias. You’ll want to make sure this is added after the customer XML is (using the module’s before/after attributes to control loading order). Then, in your Module, add a custom block
class Youtpackage_Yourmodule_Block_Form_Login extends Mage_Customer_Block_Form_Login
{
}
The key here is our “new” block extends the old block. Mage_Customer_Block_Form_Login is the Block class for the alias customer/form_login. As our imaginary module stands right now, our login page should function exactly the same as the existing module, since our new block inherits all the old Block’s behavior.
There’s numerous ways to complete our task at this point. A good old fashioned override of _toHtml should do the trick
class Youtpackage_Yourmodule_Block_Form_Login extends Mage_Customer_Block_Form_Login
{
protected function _toHtml()
{
$config = Mage::getStoreConfig('path/to/config');
switch($config)
{
case 'foo':
$this->setTemplate('foo/baz/bar.phtml');
break;
case 'baz':
$this->setTemplate('foo/baz/bar.phtml');
break;
default:
//do nothing, maintain existing behavior, which will
//we old module's behavior.
}
return parent::_toHtml();
}
}
We use the config value to determine which custom template to set (changing the appearance), or if a specific value isn’t found, we do nothing and the old behavior is maintained.
Wrapup
A trip through Magento’s deeper abstractions is always worthwhile, but don’t forget that the systems exist for a reason. Often the complicated solution you’re looking for can be solved with some good old fashioned PHP coding, sans the abstract design patterns.
