Create a custom route and controller action

Create a standard route

We’re going to create a simple route and controller, and we do that by create a new routes file at etc/frontend/routes.xml. Let’s populate the prolog with Beeline, and create a new route within the standard router.

<aside> ℹ️ Beeline keyword: m2routes

</aside>

The standard router accepts any number of route nodes. Let’s go ahead and create a new route named compare, and the module responsible for this route will be our Macademy_ProductCompare module.

etc/frontend/routes.xml

<?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="compare" frontName="compare">
            <module name="Macademy_ProductCompare"/>
        </route>
    </router>
</config>

Create a controller action

When someone visits /compare, we want our module to respond to this request, but at the moment, it returns a 404 error page. Let’s resolve this by creating a controller action class.

We will create a file at Controller/Index/Index.php. In this action class, we’ll respond with a simple page response. This involves injecting a PageFactory class into the constructor, then creating an instance of the Page object by calling the factory’s create() method within the execute() method, and returning it.

Be sure to also update the return type of this function to Page. We’ll also add the related docblocks for each function.

Controller/Index/Index.php

<?php

declare(strict_types=1);

namespace Macademy\\ProductCompare\\Controller\\Index;

use Magento\\Framework\\App\\Action\\HttpGetActionInterface;
use Magento\\Framework\\View\\Result\\Page;
use Magento\\Framework\\View\\Result\\PageFactory;

class Index implements HttpGetActionInterface
{
    /**
     * Index constructor.
     *
     * @param PageFactory $pageFactory
     */
    public function __construct(
        private readonly PageFactory $pageFactory,
    ) {
    }

    /**
     * Execute the controller action.
     *
     * @return Page
     */
    public function execute(): Page
    {
        return $this->pageFactory->create();
    }
}

When we now visit /compare, we should see a standard page response rather than our 404 error page.

Page title

The page is a bit bare. Let’s at least add a title to the page.

Instead of returning the page right away, let’s assign it to a $page variable. Then, we can return $page. This allows us to set properties and values on this page before returning it.

Magento’s title is set on a config property, so to override it, we need to first call getConfig(). Then we grab the title property with getTitle(), and then set(), passing in the string of our new title. Be sure to also wrap that title through the double underscore translation method __().

/**
 * Execute the controller action.
 *
 * @return Page
 */
public function execute(): Page
{
    $page = $this->pageFactory->create();
    $page->getConfig()->getTitle()->set(__('Product Compare'));

    return $page;
}

This sets both the h1 tag and the meta title for the page.

We need to clear our cache for the settings to take affect:

bin/magento cache:flush

Now when we refresh the page, we’ll see our page being returned.

Complete and Continue  
Extra lesson content locked
Enroll to access all lessons, source code & comments.
Enroll now to Unlock