Routing in Magento is one of the most essential parts every developer should be aware of. Processing URL request and router classes responsible for matching and processing that request influence the application flow. Let’s get into the nuts and bolts together.
Admin Router → Standard Router → Custom router → Default Router
It’s used for backend requests
It’s used for frontend requests
CMS Pages for example
It’s used when other routers don’t match. The value is specified in “Default No-route URL” field at “System/Configuration/General/Web/Default Pages”. The value “cms/index/noRoute” is used by default and redirects to 404 page.
Base Router → CMS Router → UrlRewrite Router → Custom router → Default Router
Match method will parseRequest and matchAction, and in the second method it will set module front name, controller path name, action name, controller module and route name. At base router standard Magento URL (front_name/action_path/action/param_1/etc_params/) is matched.
It’s used for cms pages
It searches for UrlRewrite in the database
The routers information for the modules is described in the routerList parameter of Magento\Framework\App\RouterList type in your di.xml. Each area has its own set of the routers. The Magento\Framework\App\RouterList model is injected into FrontController.
It’s used when other routers don’t match. Page 404 will be displayed.
What occurs in router classes
Let’s take the main page as an example and consider how it works. It uses the class Mage_Core_Controller_Varien_Router_Standard. The class contains the method match() which obtains the object $request of the type Zend_Controller_Request_Http. Let’s have a closer look at what occurs then:
1. Define the module name
We try to extract the module name from the object $request. If there’s no name, we try to get the value using $request->getPathInfo(). In case when the module name is not found (from admin’s side), the value is $module = ‘admin’; otherwise, the function stops executing.
For the main page: $module = ‘cms’.
2. After the module name is defined, we search router args
For the main page: $modules = [‘0’ => ‘Mage_cms’]
3. Go through modules to find appropriate controller.
Here we get the instance of the class found.
The example of the main page: $controllerClassName = ‘Mage_Cms_IndexController’
4. If we don’t find any suitable function, the function stops executing.
5. After the module name, controller and action are defined successfully, for the object $request we specify the value of module name (ModuleName), controller (ControllerName), action (ActionName) and (ControllerModule).
The example of the main page:
$realModule = ‘Mage_cms’
$controller = ‘index’
$controllerClassName = ‘Mage_Cms_IndexController’
6. Then on the object $request we put dispatched = true, and controller dispatches the action method.
As an example of the main page, in Magento 2
is responsible for match application action by request.
The method dispatch iterates through routersList which contains the classes described above and tries to find matches.
$actionInstance = $router->match($request);
If there are matches, as is the case with Magento 1 there will be dispatched = true and dispatch request.
What occurs in match? Let’s consider \vendor\magento\framework\App\Router\Base.php:
1. The method “match” parses the request and calls the method matchAction().
2. When getting in matchAction, you can see the part of the code known due to Magento 1 where we also get the list of modules by route front name.
For main page: $modules = [‘0’ => ‘Magento_Cms’].
3. Then go through modules to find appropriate controller. We define $actionClassName and get the instance of the class found.
The example of the main page: $actionClassName = ‘Magento\Cms\Controller\Index\Index’.
4. Here we follow the way if $actionInstance is empty.
5. After the module name, controller and action are defined successfully, for the object $request we specify the value of module name (ModuleName), controller (ControllerName), action (ActionName), (ControllerModule) and (setRouteName).
The example of main page:
$moduleFrontName = ‘cms’
$actionPath = ‘index’
$action = ‘index’
$currentModuleName = ‘Magento_Cms’
$routeName = ‘cms’
6. Return $actionInstance and get back in Magento\Framework\App\FrontController::dispatch() where we put dispatched = true and dispatch request.