How do I create a simple “Hello World” module in Magento 2?
Magento 2 is a well-engineered framework for building e-commerce websites. It is based on the PHP programming language and MySQL/MariaDB (relational) database. All functionality in Magento 2 is built based on the Oriented Programming approach.
Every feature in Magento 2 is located in a module. A module is a package that contains all necessary files and logic that helps a feature be “alive” in Magento 2. The vendor/magento/module-cms
is one of the examples of a Magento 2 module.
Creating a Module
A module is located in the app/code/
directory and includes the vendor folder name. Inside the vendor name, the Magento 2 module is created. Let’s create a new Magento 2 module with the vendor name “MageMastery” and the module/feature name “HelloWorld”.
cd app/code/
mkdir -p MageMastery/HelloWorld
Let’s create 2 mandatory files inside the HelloWorld module so that Magento 2 can register it in the system.
The registration.php
file:
<?php
use Magento\Framework\Component\ComponentRegistrar;
ComponentRegistrar::register(
ComponentRegistrar::MODULE,
'MageMastery_HelloWorld',
__DIR__
);
The ComponentRegistrar::register()
call registers a new module with the name MageMastery_HelloWorld inside the current directory using the __DIR__
PHP constant.
The module.xml
file is located inside the etc
directory of the HelloWorld module.
mkdir etc
touch etc/module.xml
Let’s add the routing configuration to the module.xml
file:
<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Module/etc/module.xsd">
<module name="MageMastery_HelloWorld" />
</config>
The <module />
XML node provides the name of the Magento 2 module. The name is then going to be used by the Magento 2 application. For instance, you can see the module name when using the bin/magento module:enable
CLI command.
Registering a Module
Magento 2 provides a Magento CLI script for operations related to setting up an application, registering new modules, clearing caches, reindexing a catalog of products, etc. The Magento CLI script is located inside the bin directory and can be accessed by running it via the command line.
bin/magento
Let’s enable the module by running the following command:
bin/magento module:enable MageMastery_HelloWorld
After that, the module has to be installed and registered in a Magento 2 application. Here is the second command, that should be executed:
bin/magento setup:upgrade
Setting up Module’s Routing
The module we’ve created does nothing, except show itself via Magento CLI. The next step in the Hello World tutorial is to register the module’s routing configuration. It will allow us to create a controller and view it on a storefront.
First, let’s create a new routes.xml
file.
mkdir -p etc/frontend
touch etc/frontend/routes.xml
The configuration of the routes.xml
file:
<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:App/etc/routes.xsd">
<router id="standard">
<route id="magemastery_helloworld" frontName="helloworld">
<module name="MageMastery_HelloWorld" />
</route>
</router>
</config>
With the above configuration, we register a new module’s front name “helloworld”. The front name can be used to access controller classes.
If we access the https://magento.test/helloworld
URL, we can see the 404 Page Not Found page. It is time to create an Index controller that is responsible for handling and rendering content when we try to access the above URL again.
Let’s create the Index controller class. First, we have to create the Controller/Index directory.
mkdir -p Controller/Index
touch Controller/Index/Index.php
The Index controller class:
<?php declare(strict_types=1);
namespace MageMastery\HelloWorld\Controller\Index;
use Magento\Framework\App\Action\HttpGetActionInterface;
class Index implements HttpGetActionInterface
{
public function execute()
{
// TODO: Implement execute() method.
}
}
After refreshing the https://magento.test/helloworld
URL in a browser, we can see the below result:
1 exception(s):
Exception #0 (InvalidArgumentException): Invalid return type
The execute()
method has to return an instance of the Magento\Framework\Controller\ResultInterface
interface. Let’s update the implementation of the execute()
method as below:
public function execute(): ResultInterface
{
/** @var Raw $result */
$result = $this->resultFactory->create(ResultFactory::TYPE_RAW);
$result->setContents('Hello World');
return $result;
}
The full implementation of the Index controller:
<?php declare(strict_types=1);
namespace MageMastery\HelloWorld\Controller\Index;
use Magento\Framework\App\Action\HttpGetActionInterface;
use Magento\Framework\Controller\Result\Raw;
use Magento\Framework\Controller\ResultFactory;
use Magento\Framework\Controller\ResultInterface;
class Index implements HttpGetActionInterface
{
public function __construct(
private readonly ResultFactory $resultFactory
) {
}
public function execute(): ResultInterface
{
/** @var Raw $result */
$result = $this->resultFactory->create(ResultFactory::TYPE_RAW);
$result->setContents('Hello World');
return $result;
}
}
The result after refreshing the https://magento.test/helloworld
URL.
The same result can be viewed if we navigate to the https://magento.test/helloworld/index/index
URL or even https://magento.test/helloworld/index
URL. It happens because the default controller directory name is Index and the controller class is… drum roll – Index.php. The routing resolves both default names and we can access the Index controller without explicitly specifying the controller name and directory.
It is also possible to have a different directory name inside the “Controller” directory, as well as the name of a controller class. For example, the helloworld/product/add
route matches the MageMastery\HelloWorld\Controller\Product\Add
controller.
What’s Next
We learned the very basics of Magento 2 development and created our first Magento 2 module. The module consists of the registration files, routing configuration, and controller that renders the “Hello World” text on a storefront.
It is recommended to learn how to create layout and template files, going forward. It will help to get an idea of the alternative response objects, that are created in controllers. We will also render the Hello World as part of a fully functional Magento 2 website, wrapped with the header, and footer.