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.
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 convention 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 paths to match an Action Controller from your Magento 2 custom module?
Max with his team of Magento enthusiasts won the Best Magento 1 to Magento 2 Migration Award at the Magento Imagine 2017. As CEO at Pronko Consulting, he is actively working with Magento 2, delivering superior customer experience. As one of the most famous developers on a market and in the Magento Community, he launched Magento 2 blog, Magento DevChannel – YouTube channel in 2017 where he shares his knowledge, experience and the best practices in the Magento field.
Subscribe to my Magento 2 tips and tutorials content.
Every week I send an interesting email directly to your inbox