Magento custom module: Step by step to create it in Magento 2

Magento custom module is a crucial development process for any Magento developer. As you know, at some point in time, a developer might need to integrate his own functionality or module. In this blog post today, we’ll guide you step by step to develop a custom module in Magento 2.

Magento is a very versatile platform that comes with a lot of useful features and supports both free and paid modules. It provides modules that can be installed online as well as can be customized in order to meet the client’s needs. Customization is achieved by generating a module and then can be modified according to the choice utilizing the power of PHP language. For example, if our website has a specific feature or set of features or requirements that are not common to the market, a module can fill that gap for us.

Magento comes with 3 types of code pool (Code, Core, and Local)where custom and core modules reside. The local pool(folder) is where all the custom modules reside or should be placed. Below given are the components that a module should include.

  • Blocks – Here you need to provide the features used to show data in our templates.
  • Models – All business logic is contained here.
  • Resource – Models include functions that are used for database interaction.
  • Controllers – Defines page layout and blocks files and are loaded when a URL is requested.
  • etc – Includes configuration files in XML formats that show Magento how many files modules have and how the module interacts.
  • Helpers – Includes functions that are utilized for defining common business logic (such as image resize, validation). These functions can be used anywhere across the Magento application
  • sql – Contains SQL scripts to create, modify, or delete SQL tables.

How to create a Magento custom module?

magento-custom-module

Create a simple module in Magento 2

Generating a simple module in Magento 2 is easy. You will need to achieve the following tasks:

  • Create a new directory for the module
  • Create a registration.php script
  • Create a etc/module.xml information file
  • Install the new module

Create a new directory for the module

There are two options to select for the position of the new directory

  • app/code/{vendor}/
  • vendor/{vendor}/

You can choose the first option if your module is intended for a specific online store you’re working on. But if you’re generating a module with the purpose of it being used on various websites, it’s more suitable to select the second option.  Now I’ll use the first option for this example.

Firstly, you need to create a directory named EndPoint (our vendor name) with a subdirectory inside it, MyModule:

cd {website_root}
mkdir -p app/code/EndPoint/MyModule

Create the registration.php script

The registration.php the file tells Magento to register the new module under a specific name and location.

Generate a file named app/code/EndPoint/MyModule/registration.php with the below code

<?php
\Magento\Framework\Component\ComponentRegistrar::register(
    \Magento\Framework\Component\ComponentRegistrar::MODULE,
    'EndPoint_MyModule',
    __DIR__
);

Create the etc/module.xml information file

At this step, you need to create our module information file, where we’ll specify the module version number. First, we have to gennerate the etc directory inside app/code/EndPoint/MyModule:

mkdir app/code/EndPoint/MyModule/etc

then create module.xml with the following  command line

<?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="EndPoint_MyModule" setup_version="1.0.0">
    </module>
</config>

Install the new module

Now we need to install and enable the new module, So from our website root, we need to run the command

php bin/magento setup:upgrade

Magento will take out a list of module names and configuration updates and the new module EndPoint_MyModule should be listed in that list

Add a custom route to our module

Now we have a working, enabled module, but it’s not doing anything yet! What’s a simple way to check that our module is enabled? Let’s set up a custom route, so if we hit a URL like https://{our_website}/mymodule/test/helloworld we can return a custom response from a controller.

Creating a custom route will need some steps on its own:

  • Create a new directory for the controller
  • Create a etc/routes.xml file
  • Create the controller
  • Upgrade the new module

Create a new directory for the controller

First, we need to create a new directory where the new PHP controller for our custom route will live. The new directory path should be:

app/code/EndPoint/MyModule/Controller

You can generate as many directory levels as you want, based on our desired path. For instance, if you generate a class named Index in app/code/EndPoint/MyModule/Controller, the URL that will be routed to this controller will be https://{our_website}/mymodule/index (the “Controller” directory is ignored).

Buy If you generate a class named HelloWorld in app/code/EndPoint/MyModule/Controller/Test, the resulting URL will be https://{our_website}/mymodule/test/helloworld.

Create the etc/routes.xml file

routes.xml will tell Magento what base URL will be used for our module. First, we need to create the “frontend” directory where the routes.xml file needs to be placed:

mkdir app/code/EndPoint/MyModule/etc/frontend

When you need the base URL to be MyModule, you have to generate an XML file inside the new directory that will route all requests made to the given URL to our module controllers:

<?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 frontName="mymodule" id="mymodule">
            <module name="EndPoint_MyModule"/>
        </route>
    </router>
</config>

Create the controller

If we want to respond to requests for https://{our_website}/mymodule/test/helloworld you will need to generate the base Controller directory and the Test subdirectory:

mkdir -p app/code/EndPoint/MyModule/Controller/Test

Under this directory, you need to generate our custom Magento controller. All route controllers should extend \Magento\Framework\App\Action\Action. We also need to have a public construct() method to pass the context to our ancestor and an execute() a function that will be called when the URL is hit:

<?php

namespace EndPoint\MyModule\Controller\Test;

class HelloWorld extends \Magento\Framework\App\Action\Action
{

    public function __construct(
        \Magento\Framework\App\Action\Context $context
    ) {
        parent::__construct(
            $context
        );
    }

    public function execute()
    {
        echo "Hello world!";
    }

}

Upgrade the new module

At this step, you need to upgrade our Magento setup. But because you included a new controller that gets parameters from the dependency injector in the construct. You also need to compile the dependency injection engine (such as factories, proxies, and interceptors). At last, you need to clear the cache so new content will be served from our custom URL:

php bin/magento setup:upgrade
php bin/magento setup:di:compile
php bin/magento cache:flush

And that’s it. Open the /helloworld/index/index URL in your browser and you should get something like this: That means our module is working!

Final words

It comes to the end of the tutorials: Magento custom module: Step by step to create it in Magento 2. We hope this is a useful blog for you. If you want to understand more about Magento you can read our Magento Platform article for more detail. In case you want to find an agency who can assist you with your Magento store, come to Magesolution. We have more than 15 years of experience in eCommerce development, thus, we can deliver to you the best Magento Website Development Services. Contact us now for a free consultation!