Magento Commerce has been on the OSS “market” for a while now and I see more and more developers, designers and of course store owners migrating their ecommerce sites to Magento or installing it for their new stores. I’ve been coding on Magento since its beta 0.6 version, actually my first integration was based on this beta. I’ve been advised not to use the beta and they were right. However, I had my reasons for recommending it, using it and somehow advocating for that fresh, promising open source piece of software. In the meanwhile, it turned out I was right – it’s one of the most complete, scalable & feature-rich free ecommerce solution. Not the easiest to integrate or use, not the smoothest or lightweight, but it’s come a long way and it still have room for improvements.
One of the things I liked from the start (as a developer) was the ability to extend it in a very simple and loosely coupled way (unlike other solutions). Adding the OOP and design patterns made it perfect for my way of thinking. And I think this is the way to go for any major application, even if it might seem cluttered or with a steep learning curve at a first glance. I remember one of the first problems I faced was module creation – I was adding all my code in the core/Mage folder, I was overwriting a lot of the core code although I knew it was bad and so on. However, once I understood how to create a module, things became clearer and much simpler. So here’s a beginner’s guide to creating a new module. Although it’s meant for beginners, you should know the basic folder layout (skins, library, js, apps).
All Magento code resides in app/code
and the lib
folder. If you check app/code
you’ll notice three subfolders: community
, core
, local
. You should be adding your stuff in local or community (usually only when it is a community contribution). So let’s create our first module. I’ll use the namespace mandagreen and the module will be called HelloWorld. For this I need to create the following folders under app/code/local
:
Mandagreen/HelloWorld
To keep things simple, in this example we’ll be creating one Block, one Helper and one Model – no controllers & no Resource Models. Here’s where each of these will reside:
blocks – app/code/local/Mandagreen/HelloWorld/Block
helpers – app/code/local/Mandagreen/HelloWorld/Helper
models – app/code/local/Mandagreen/HelloWorld/Model
Create these three folders and then also create a new etc
folder. The structure will then look like this:
app/code/local/Mandagreen/HelloWorld/Block
app/code/local/Mandagreen/HelloWorld/etc
app/code/local/Mandagreen/HelloWorld/Helper
app/code/local/Mandagreen/HelloWorld/Model
The etc
folder holds configuration information – in this case we’ll focus only on the module configuration file, which is config.xml
. Let’s create it and start adding some xml into it:
<?xml version="1.0"?>
<config>
<modules>
<Mandagreen_HelloWorld>
<version>0.0.1</version>
</Mandagreen_HelloWorld>
</modules>
<global>
<models>
<helloworld>
<class>Mandagreen_HelloWorld_Model</class>
</helloworld>
</models>
<blocks>
<helloworld>
<class>Mandagreen_HelloWorld_Block</class>
</helloworld>
</blocks>
<helpers>
<helloworld>
<class>Mandagreen_HelloWorld_Helper</class>
</helloworld>
</helpers>
</global>
<frontend>
<layout>
<updates>
<helloworld>
<file>mg_helloworld.xml</file>
</helloworld>
</updates>
</layout>
<translate>
<modules>
<Mandagreen_HelloWorld>
<files>
<default>Mandagreen_HelloWorld.csv</default>
</files>
</Mandagreen_HelloWorld>
</modules>
</translate>
</frontend>
</config>
That’s a lot, isn’t it? ? No worries, I’ll explain. Under the main node (config
), youll usually need the global node. The modules
node is being used to hold mode info about the current module, maybe dependencies and so on. The frontend
node is usually used for defining layout handlers and translation files, but they can do more than that. In this example, we’re gonna have our own layout file called mg_helloworld.xml – you can use any name on it (as long as it’s unique), but I prefer to namespace it as well. Also, I’ve defined a translation file Mandagreen_HelloWorld.csv
which needs to be created in app/locale/en_US
(or whatever your default locale is).
The global
node defines all the classes you’ll be using, in this case helpers, models and blocks. You can see that they are defined the same way, but in different locations: <helpers />, <models /> and <blocks />. Let’s use the helpers node as an example xenical orlistat.
<helpers>
<helloworld>
<class>Mandagreen_HelloWorld_Helper</class>
</helloworld>
</helpers>
The helloworld
node defines a handle and you should be careful to always use unique names. If you’re not sure if a certain name exist, namespace it (mghelloworld for example). This handle will be used to instantiate models, call helpers or use blocks using the Magento factory. For example, for models, you’ll be using Mage::getModel('helloworld/modelname');
instead of new Mandagreen_HelloWorld_Model_Modelname();
. Same with helpers, inside a block template – $this->helper('helloworld')->someMethod();
.
The other node, class
is being used to define the namespace of the class name. In the example above, the name of the Modelname class has to being with Mandagreen_HelloWorld_Helper
. A few examples might help:
Mandagreen_HelloWorld_Model_Salute
, will be found in Mandagreen/HelloWorld/Model/Salute.php
and can be accessed via Mage::getModel('helloworld/salute')
Mandagreen_HelloWorld_Model_Salute_Hi
, will be found in Mandagreen/HelloWorld/Model/Salute/Hi.php
and can be accessed via Mage::getModel('helloworld/salute_hi')
Mandagreen_HelloWorld_Helper_Help
, will be found in Mandagreen/HelloWorld/Model/Help.php
and can be accessed via Mage::helper('helloworld/help')
Now that we explained the config file, let’s move on to actually creating the classes and code. I’ll use the example above and create the following files:
Mandagreen/HelloWorld/Block/Standard.php
<?php
class Mandagreen_HelloWorld_Block_Standard extends Mage_Core_Block_Template {
function getSomething() {
return Mage::getModel('helloworld/salute')->getName();
}
}
Mandagreen/HelloWorld/Helper/Help.php
<?php
class Mandagreen_HelloWorld_Helper_Help extends Mage_Core_Helper_Abstract {
function shouldSayHi() {
return true;
}
}
Mandagreen/HelloWorld/Model/Salute.php
<?php
class Mandagreen_HelloWorld_Model_Salute extends Mage_Core_Model_Abstract { //or Varien_Object or none
function getName() {
//do some heavy logic here
return 'John';
}
}
One more file is required for the translations to work with this module – a “default” Data helper, defined in Mandagreen/HelloWorld/Helper/Data.php like this:
class Mandagreen_HelloWorld_Helper_Data extends Mage_Core_Helper_Abstract {}
We have the classes but we also need to use them in a template, so let’s create standard.phtml
in app/design/frontend/default/default/template/helloworld
(create all additional folders if needed). Also, create mg_helloworld.xml
under app/design/frontend/default/default/layout
.
For the template, things are very easy:
<div style="background: red; padding: 20px;">
<?php if( $this->helper('helloworld/help')->shouldSayHi() ): ?>
Hello <?php echo $this->getSomething(); ?>
<?php else: ?>
Can't say anything...
<?php endif; ?>
</div>
while for the layout we’ll use this approach:
<?xml version="1.0"?>
<layout version="0.1.0">
<default>
<reference name="content">
<block type="helloworld/standard" name="helloworld" template="helloworld/standard.phtml" after="-" />
</reference>
</default>
</layout>
This should display “Hello John” at the end of the content area on most of the pages, including the homepage. But wait, before you try that you’ll have to enable the module in app/etc/modules
. Create a file called Mandagreen_HelloWorld.xml
with the following code:
<?xml version="1.0"?>
<config>
<modules>
<Mandagreen_HelloWorld>
<active>true</active>
<codePool>local</codePool>
</Mandagreen_HelloWorld>
</modules>
</config>
Clear all magento cache and refresh the page – your first module, up and running! And here’s the archive for this tutorial – Download Hello World Magento Module (2.99 kB)
Further/recommended reads:
Cristi Magento Magento