Action Controller in the Magento 2 Custom Module

Action Controller in the Magento 2 Custom Module

I've been building a custom module for Magento 2 and faced with the uncertainty around Action Controllers. The obvious thing, when you create a new controller in a custom module is to have as simple as possible file structure. But it is not a case.

Creating an Action Controller

During the implementation of an Action Controller you should consider 3 steps. The routing declaration of the custom Magento 2 module, which should specify a custom module route name. The ACL rule for a custom page and finally, an Action Controller, which will be triggered to render a page.

The thing is. In case you have a module route name only in the URL, in my case it is a https://magento.com/custom_route/ where the "custom_route" is a declared frontName from the etc/frontend/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="admin">
        <route id="custom_route" frontName="custom_route">
            <module name="Pronko_CustomRoute" before="Magento_Backend" />
        </route>
    </router>
</config>

Then there is a question. What controller path should you have in the custom Magento 2 module for the Action Controller with the Index.php file name?

I was sure, that the app/code/Pronko/CustomRoute/Controller/Adminhtml/Index.php path is perfectly fine and the Front Controller would manage to find my controller. I was deadly wrong.

The Magento\Framework\App\Router\Base::matchAction method matches the "custom_route" from the URL and matches it according to the routes.xml file and gets the module name, which is in our case is a Pronko_CustomRoute.

Also, in order to prepare an action controller path and find the Action Controller, the default action and default controller name is used from the Magento\Framework\App\Router\Base class. Default Action and Controller Name in Magento 2 Router Base class

As a result, the Pronko\CustomRoute\Controller\Adminhtml\Index\Index class name will be prepared. Then this file is checked whether it exists and if not, the 404 action will be rendered. This is not what I was expecting.

Use Index directory together with Index Controller Class

Long story short. Always create an additional "Index" folder even if you have only one Action Controller in the Magento 2 custom module. Instead of Pronko\CustomRoute\Controller\Adminhtml\Index class name, which can be resolved to custom_route/index path, use the Pronko\CustomRoute\Controller\Adminhtml\Index\Index class name.

Why am I saying that? Well, it can save you 30-40 minutes of your time. Instead of debugging and looking for a reason, why the obvious naming convension in your module doesn't work, you may, for example, spend some time sharing knowledge over your blog. Or, building a Magento Admin User interface.

Do you think Magento 2 should support custom_route/index/index and custom_route/index pathes to match an Action Controller from your Magento 2 custom module?

magento 2 action controller

Related Articles

Comments

Next Article Previous Article

LinkedIn Twitter Facebook