Magento 2 Development Workshop Learn More

Magento 2 for Beginners

10 lessons

Create a Page in Magento 2

Create a Page in Magento 2

Magento 2 provides a set of framework features that allow to easily create different entry points. One of the entry points we are going to learn in this lesson is a Page.

A page in Magento 2 is a result of an Action Controller execution. Each controller either returns an HTML content or redirects to another controller for further processing. In this lesson, we are going to create a Page, that shows a JSON message in a browser when it has been accessed via a custom route.

Lesson Overview

In this lesson we are going to learn the following:

  • How to create a page in Magento 2?
  • How to create an Action Controller?
  • How to register a new route?
  • How to return a JSON data from a Controller?

Before we begin

For this tutorial, I've created the MageMastery_FirstPage module with the registration.php and module.xml files. And the module has been successfully registered with the bin/magento setup:upgrade CLI command.

The registration.php file:

<?php

use Magento\Framework\Component\ComponentRegistrar;

ComponentRegistrar::register(
    ComponentRegistrar::MODULE,
    'MageMastery_FirstPage',
    __DIR__
);

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_FirstPage" />
</config>

For more information about the module creation and registration, please refer to the previous lesson A Module in Magento 2.

Registering a new route

In order to create a new page in Magento 2, which is accessible via a browser, there are two files that have to be created in a Magento 2 module. The first file is routes.xml. The file is responsible for providing information to Magento 2 where to look for a particular controller module's name and additional rules to match a URI.

The second file is a controller class, that should be executed and process the incoming request.

Let's go ahead and create a new routes.xml file under the MageMastery/FirstPage/etc/ directory.

Configuration in Magento 2

The configuration can be provided for the two different areas: frontend and adminhtml areas. There is also a default that is used to provide a configuration for both areas.

Configuration Areas in Magento 2

For the storefront configuration changes, we have to add a new frontend directory inside the MageMastery/FirstPage/etc/ directory. We will talk more about the adminhtml directory in the upcoming lessons.

If you haven't created the etc/frontend directory this is the right time to do it.

The routes.xml file

Inside the etc/frontend directory let's create the routes.xml configuration file. All routes configuration files from all Magento 2 registered modules including the MageMastery/FirstPage module will be merged and provided for the execution.

The routes.xml initial file state:

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
        xsi:noNamespaceSchemaLocation="urn:magento:framework:App/etc/routes.xsd">

</config>

Magento 2 Open Source provides so-called routers, and each router has its own identifier. We are not going to go deeply into the router implementation just now. We are going to use the standard router that is identified as "standard". This is what you see in the code below:

<?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">
    
    </router>
</config>

Inside the standard router node, we can add routes configuration. Each route is responsible for providing a front name that is used to match the route with a request URL. Also, the route should provide a module name, that includes an action controller class.

The route configuration for the MageMastery_FirstPage module and the magemastery front name looks as follow:

<route id="magemastery_firstpage" frontName="magemastery">
    <module name="MageMastery_FirstPage" />
</route>

Note the id argument of the route. It has to be unique across the Magento 2 application. The recommended naming convention for the route id is lower-case module name e.g. magemastery_firstpage to ensure the uniqueness.

Let's see the final state 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_firstpage" frontName="magemastery">
            <module name="MageMastery_FirstPage" />
        </route>
    </router>
</config>

Magento 2 standard router reads the route configuration that starts with the magemastery request URI part, finds a module name with the name MageMastery_FirstPage, and will check for a controller, which can process the request.

A controller in a module is the second bit or file to be created in this lesson.

Action Controller

All controllers of a module should be located in a directory called Controller. There is another directory level that should exist inside the Controller directory before the class can be located. For this lesson, we are going to create a Page directory in the Controller.

Inside the Page directory, let's create the View.php file.

As a result, you should have the following module structure.

Module Structure

The View.php file is a MageMastery\FirstPage\Controller\Page\View class. The View class should extend the Magento\Framework\App\Action\Action class.

<?php

declare(strict_types=1);

namespace MageMastery\FirstPage\Controller\Page;

use Magento\Framework\App\Action\Action;

class View extends Action
{
    public function execute()
    {

    }
}

The Action class requires to provide implementation of the execute() method. Once Magento 2 will resolve the route it will trigger the View::execute() method. The execute() method's logic should be added in order to render something on a front end. For this lesson, we are going to return a JSON response with the message.

In order to return anything from the execute() method, there is a resultFactory variable that is provided to us from the Action parent class. The create() method of the Magento\Framework\Controller\ResultFactory class creates an instance of a Magento\Framework\Controller\Result\Json class. The Json class then can be used to convert an array into a JSON and return back from the execute() method.

$jsonResult = $this->resultFactory->create(ResultFactory::TYPE_JSON);

We can use the $jsonResult to set an array with the key message and the value to be My First Page.

$jsonResult->setData([
    'message' => 'My First Page'
]);

The resulting code of the View controller class looks as follow:

<?php

declare(strict_types=1);

namespace MageMastery\FirstPage\Controller\Page;

use Magento\Framework\Controller\Result\Json;
use Magento\Framework\App\Action\Action;
use Magento\Framework\Controller\ResultFactory;

class View extends Action
{
    public function execute()
    {
        /** @var Json $jsonResult */
        $jsonResult = $this->resultFactory->create(ResultFactory::TYPE_JSON);
        $jsonResult->setData([
            'message' => 'My First Page'
        ]);
        return $jsonResult;
    }
}

In order to a result in a browser, the Magento 2 configuration cache has to be cleaned. The cache cleanup can be done with the Magento CLI command cache:clean. The command has to be executed from the Magento 2 project root directory.

bin/magento cache:clean

Navigate to the http://magento2ce.magemastery.net/magemastery/page/view url, where the magento2ce.magemastery.net domain name can be different one, depending on what domain name you provided during the Magento 2 installation.

Page in Magento 2

Let's have a closer look at /magemastery/page/view path for the page. The first part is the magemastery, this is a front name that is configured in the routes.xml file. The page is the name of a directory Page inside which there is a View class. The View::execute() method returns the JSON object.

Homework

The homework for this lesson. Create a custom controller with the custom JSON message which has to be rendered on a page with the route /magemastery/custom/page.

Next Steps

Subscribe to the Mage Mastery newsletter to hear first about new lessons and courses.