Hello World
Enough theory, it's time for Hello World.
We're going to
1.
Create a Hello World
module in the Magento system
2.
Configure this module
with routes
3.
Create Action
Controller(s) for our routes
Create Hello World Module
First, we'll create a directory structure for
this module. Our directory structure should look as follows:
app/code/local/Magentotutorial/Helloworld/Block
app/code/local/Magentotutorial/Helloworld/controllers
app/code/local/Magentotutorial/Helloworld/etc
app/code/local/Magentotutorial/Helloworld/Helper
app/code/local/Magentotutorial/Helloworld/Model
app/code/local/Magentotutorial/Helloworld/sql
Then create a
configuration file for the module (at pathapp/code/local/Magentotutorial/Helloworld/etc/config.xml):
<config>
<modules>
<Magentotutorial_Helloworld>
<version>0.1.0</version>
</Magentotutorial_Helloworld>
</modules>
</config>
<modules>
<Magentotutorial_Helloworld>
<version>0.1.0</version>
</Magentotutorial_Helloworld>
</modules>
</config>
Then create a file to
activate the module (at path app/etc/modules/Magentotutorial_Helloworld.xml):
<config>
<modules>
<Magentotutorial_Helloworld>
<active>true</active>
<codePool>local</codePool>
</Magentotutorial_Helloworld>
</modules>
</config>
<modules>
<Magentotutorial_Helloworld>
<active>true</active>
<codePool>local</codePool>
</Magentotutorial_Helloworld>
</modules>
</config>
Finally, we ensure the module is active:
1.
Clear your Magento
cache.
2.
In the Magento Admin,
go to System->Configuration->Advanced.
3.
Expand "Disable
Modules Output" (if it isn't already).
4.
Ensure that
Magentotutorial_Helloworld shows up.
Configuring Routes
Next, we're going to configure a route. A
route will turn a URL into an Action Controller and a method. Unlike other
convention based PHP MVC systems, with Magento you need to explicitly define a
route in the global Magento config.
In your config.xml file, add the following
section:
<config>
...
<frontend>
<routers>
<helloworld>
<use>standard</use>
<args>
<module>Magentotutorial_Helloworld</module>
<frontName>helloworld</frontName>
</args>
</helloworld>
</routers>
</frontend>
...
</config>
...
<frontend>
<routers>
<helloworld>
<use>standard</use>
<args>
<module>Magentotutorial_Helloworld</module>
<frontName>helloworld</frontName>
</args>
</helloworld>
</routers>
</frontend>
...
</config>
We have a lot of new terminology here, let's
break it down.
What is a <frontend>?
The <frontend> tag refers to a Magento
Area. For now, think of Areas as individual Magento applications. The
"frontend" Area is the public facing Magento shopping cart
application. The "admin" Area is the the private administrative
console application. The "install" Area is the application you use to
run though installing Magento the first time.
Why a <routers> tags if we're configuring individual
routes?
There's a famous quote about computer science,
often attributed to Phil Karlton:
"There are only two hard things in
Computer Science: cache invalidation and naming things"
Magento, like all
large systems, suffers from the naming problem in spades. You'll find there are
are many places in the global config, and the system in general, where the
naming conventions seem unintuitive or even ambiguous. This is one of those
places. Sometimes the <routers> tag will enclose configuration information about routers, other
times it will enclose configuration information about the actual router objects
that do the routing. This is going to seem counter intuitive at first, but as
you start to work with Magento more and more, you'll start to understand its
world view a little better. (Or, in the words of Han Solo, "Hey, trust
me!").
What is a <frontName>?
When a router parses a URL, it gets separated
as follows
http://example.com/frontName/actionControllerName/actionMethod/
So, by defining a value of
"helloworld" in the <frontName> tags, we're telling Magento
that we want the system to respond to URLs in the form of
http://example.com/helloworld/*
Many developers new to
Magento confuse this frontName with the Front Controller object. They are not the same thing. The
frontName belongs solely to routing.
What's the <helloworld> tag for?
This tag should be the
lowercase version of you module name. Our module name is Helloworld, this tag
is helloworld. Technically this tag defines our route name
You'll also notice our frontName matches our
module name. It's a loose convention to have frontNames match the module names,
but it's not a requirement. In your own modules, it's probably better to use a
route name that's a combination of your module name and package name to avoid
possible namespace collisions.
What's <module>Magentotutorial_Helloworld</module>
for?
This module tag should be the full name of
your module, including its package/namespace name. This will be used by the
system to locate your Controller files.
Create Action Controller(s) for our Routes
One last step to go, and we'll have our Action
Controller. Create a file at
app/code/local/Magentotutorial/Helloworld/controllers/IndexController.php
That contains the following
class Magentotutorial_Helloworld_IndexController extends Mage_Core_Controller_Front_Action {
public function indexAction() {
echo 'Hello Index!';
}
}
public function indexAction() {
echo 'Hello Index!';
}
}
Clear your config cache, and load the
following URL
http://exmaple.com/helloworld/index/index
You should also be able to load
You should see a blank page with the text
"Hello World". Congratulations, you've setup your first Magento
Controller!
Where do Action Controllers go?
Action Controllers
should be placed in a module's controllers (lowercase c) folder. This is where the system will look for
them.
How should Action Controllers be named?
Remember the <module> tag back in
config.xml?
<module>Magentotutorial_Helloworld</module>
An Action Controller's name will
1.
Start with this string specified in config.xml (Magentotutorial_Helloworld)
2.
Be followed by an
underscore (Magentotutorial_Helloworld_)
3.
Which will be followed
by the Action Controller's name (Magentotutorial_Helloworld_Index)
4.
And finally, the word
"Controller" (Magentotutorial_Helloworld_IndexController)
All Action Controllers
need Mage_Core_Controller_Front_Action as an ancestor.
What's that index/index nonsense?
As we previously mentioned, Magento URLs are
routed (by default) as follows
http://example.com/frontName/actionControllerName/actionMethod/
So in the URL
http://example.com/helloworld/index/index
the URI portion
"helloworld" is the frontName, which is followed by index (The Action
Controller name), which is followed by another index, which is the name of the
Action Method that will be called. (an Action of index will call the method public function indexAction(){...}.
If a URL is incomplete, Magento uses
"index" as the default, which is why the following URLs are
equivalent.
If we had a URL that looked like this
http://example.com/checkout/cart/add
Magento would
1.
Consult the global
config to find the module to use for the frontName checkout (Mage_Checkout)
2.
Look for the cart
Action Controller (Mage_Checkout_CartController)
3.
Call the addAction method on the cart
Action Controller
Other Action Controller Tricks
Let's try adding a non-default method to our
Action Controller. Add the following code to IndexController.php
public function goodbyeAction() {
echo 'Goodbye World!';
}
echo 'Goodbye World!';
}
And then visit the URL to test it out:
http://example.com/helloworld/index/goodbye
Because we're
extending the Mage_Core_Controller_Front_Action class, we get some methods for free. For example, additional URL
elements are automatically parsed into key/value pairs for us. Add the
following method to your Action Controller.
public function paramsAction() {
echo '<dl>';
foreach($this->getRequest()->getParams() as $key=>$value) {
echo '<dt><strong>Param: </strong>'.$key.'</dt>';
echo '<dt><strong>Value: </strong>'.$value.'</dt>';
}
echo '</dl>';
}
echo '<dl>';
foreach($this->getRequest()->getParams() as $key=>$value) {
echo '<dt><strong>Param: </strong>'.$key.'</dt>';
echo '<dt><strong>Value: </strong>'.$value.'</dt>';
}
echo '</dl>';
}
and visit the following URL
http://example.com/helloworld/index/params?foo=bar&baz=eof
You should see each parameter and value
printed out.
Finally, what would we do if we wanted a URL
that responded at
http://example.com/helloworld/messages/goodbye
Here our Action Controller's name is messages,
so we'd create a file at
app/code/local/Magentotutorial/Helloworld/controllers/MessagesController.php
with an Action
Controller named Magentotutorial_Helloworld_MessagesController and an Action Method that looked something like
public function goodbyeAction()
{
echo 'Another Goodbye';
}
{
echo 'Another Goodbye';
}
And that, in a nutshell, is how Magento
implements the Controller portion of MVC. While it's a little more complicated
than other PHP MVC framework's, it's a highly flexible system that will allow
you build almost any URL structure you want.
No comments:
Post a Comment