Overwrite Magento Core using a Module
The layout of Magento’s information, warning and error messages cannot be easily changed using layout and template files. The HTML generation is done from a Block PHP class (Mage_Core_Block_Messages). It is a very bad idea to overwrite any core element of Magento. Instead we are going to extend this core-block by creating a separate module.
My goal was to make the messages compliant with Twitter Bootstrap alerts but the following technique can be used for about anything.
From inspection of ‘app/code/core/Mage/Core/Block/Messages.php’ it can be seen how Magento generates the HTML of the various messages. See for example the ‘getHtml’-method
/** * Retrieve messages in HTML format * * @param string $type * @return string */ public function getHtml($type=null) { $html = '<' . $this->_messagesFirstLevelTagName . ' id="admin_messages">'; foreach ($this->getMessages($type) as $message) { $html.= '<' . $this->_messagesSecondLevelTagName . ' class="'.$message->getType().'-msg">' . ($this->_escapeMessageFlag) ? $this->escapeHtml($message->getText()) : $message->getText() . '</' . $this->_messagesSecondLevelTagName . '>'; } $html .= '</' . $this->_messagesFirstLevelTagName . '>'; return $html; }
Most parts of the HTML are variable which allows easy overwriting by extending the original core-block.
Structure of the module
The structure of the module will be as shown below. It will be implemented as a modman module to allow for separation of our module code from the Magento installation.
├── modman └── src └── app ├── code │ └── local │ └── MyBrand │ └── MessagesBlock │ ├── Block │ │ └── Messages.php │ └── etc │ └── config.xml └── etc └── modules └── MyBrand_MessagesBlock.xml
There are four files in this module.
- modman file contains a list of how the various folders should be symlinked to your Magento installation.
- Messages.php will extend Magento’s core PHP block
- config.xml will instruct Magento to use our Messages.php Block instead of Magento’s core one
- MyBrand_MessagesBlock.xml is the module xml-file that tells Magento about the existence of our module
Module XML-file
Let’s start bottom-up. Create the MyBrand_MessagesBlock.xml (or whatever you would like to call it) and fill it up with the following XML.
<?xml version="1.0"?> <config> <modules> <MyBrand_MessagesBlock> <active>true</active> <codePool>local</codePool> </MyBrand_MessagesBlock> </modules> </config>
It will tell Magento of the existence of a module named ‘MyBrand_MessagesBlock’ that is active and located in the ‘local’ code pool.
Module Config-file
The Module Config-file is an XML-file too. Create an empty config.xml at the right location with the following content
<?xml version="1.0"?> <config> <modules> <MyBrand_MessagesBlock> <version>1.0.0</version> </MyBrand_MessagesBlock> </modules> <global> <blocks> <core> <rewrite> <messages>MyBrand_MessagesBlock_Block_Messages</messages> </rewrite> </core> </blocks> </global> </config>
This tells Magento about the version of the module. It also directs Magento to rewrite (relocate) the Block-code file ‘messages’ from the ‘core’ package. This is structured in the XML-file as follows
- **
** Configuration - **
** Global configuration - **
** Applies to (block, model, etc.) - **
** Package (core, cms, customers, etc.) - **
** What to configure - **
** What block of this package to rewrite - MyBrand_MessagesBlock_Block_Messages The full name of the replacement class
Overwrite Messages.php
This is the Block-code file that will extend the original class and overwrite whatever we want. In this case I changed the first- and second-level tag names and the behaviour of the ‘getGroupedHtml’ method so that it fits well with Twitter Bootstrap. Create it and write your own code. You can use the following as a guide.
<?php class MyBrand_MessagesBlock_Block_Messages extends Mage_Core_Block_Messages { protected $_messagesFirstLevelTagName = 'div'; protected $_messagesSecondLevelTagName = 'div'; /** * Retrieve messages in HTML format grouped by type * * @param string $type * @return string */ public function getGroupedHtml() { $types = array( Mage_Core_Model_Message::ERROR, Mage_Core_Model_Message::WARNING, Mage_Core_Model_Message::NOTICE, Mage_Core_Model_Message::SUCCESS ); $twbs_types = array( Mage_Core_Model_Message::ERROR => 'danger', Mage_Core_Model_Message::WARNING => 'warning', Mage_Core_Model_Message::NOTICE => 'info', Mage_Core_Model_Message::SUCCESS => 'success' ); $html = ''; foreach ($types as $type) { if ( $messages = $this->getMessages($type) ) { if ( !$html ) { $html .= '<' . $this->_messagesFirstLevelTagName . ' class="messages">'; } $html .= '<' . $this->_messagesSecondLevelTagName . ' class="alert alert-' . $twbs_types[$type] . '">'; $html .= '<' . $this->_messagesFirstLevelTagName . '>'; foreach ( $messages as $message ) { $html.= '<' . $this->_messagesSecondLevelTagName . '>'; $html.= '<' . $this->_messagesContentWrapperTagName . '>'; $html.= ($this->_escapeMessageFlag) ? $this->escapeHtml($message->getText()) : $message->getText(); $html.= '</' . $this->_messagesContentWrapperTagName . '>'; $html.= '</' . $this->_messagesSecondLevelTagName . '>'; } $html .= '</' . $this->_messagesFirstLevelTagName . '>'; $html .= '</' . $this->_messagesSecondLevelTagName . '>'; } } if ( $html) { $html .= '</' . $this->_messagesFirstLevelTagName . '>'; } return $html; } }
Modman file
Eventually, create the ‘modman’ file to enable easy deployment of your newly created module.
src/app/code/local/MyBrand/MessagesBlock app/code/local/MyBrand/MessagesBlock src/app/etc/modules/MyBrand_MessagesBlock.xml app/etc/modules/MyBrand_MessagesBlock.xml
How to deploy
The module can now be deployed by installing modman and running the following command:
modman init modman link modules/path_to_module modman deploy
If you are on Windows you could either use the unofficial PHP clone of modman or manually copy the module files to your installation (unfortunately polluting your installation a bit).
Conclusion
As you get more used to the quite complex structure of Magento its powerful flexibility will become apparent. This method is applicable to many situations in which you would like to change or improve core functionality of Magento.