2

I'm using Magento 2 CE Version 2.1.0.

app\code\Custom\Module\etc\frontend\di.xml

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../lib/internal/Magento/Framework/ObjectManager/etc/config.xsd">
    <type name="Magento\Framework\App\RouterList">
        <arguments>
            <argument name="routerList" xsi:type="array">
                <item name="custom_module" xsi:type="array">
                    <item name="class" xsi:type="string">Custom\Module\Controller\Router</item>
                    <item name="disable" xsi:type="boolean">false</item>
                    <item name="sortOrder" xsi:type="string">22</item>
                </item>
            </argument>
        </arguments>
    </type>
    <virtualType name="CustomModuleRoutingEntityPosts" type="custom\module\Model\Routing\Entity">
        <arguments>
            <argument name="prefixConfigPath" xsi:type="const">Custom\Module\Model\Posts\Url::URL_PREFIX_CONFIG_PATH</argument>
            <argument name="suffixConfigPath" xsi:type="const">Custom\Module\Model\Posts\Url::URL_SUFFIX_CONFIG_PATH</argument>
            <argument name="factory" xsi:type="object">Custom\Module\Model\PostsFactory</argument>
            <argument name="controller" xsi:type="string">posts</argument>
        </arguments>
    </virtualType>
    <type name="Custom\Module\Controller\Router">
        <arguments>
            <argument name="routingEntities" xsi:type="array">
                <item name="posts" xsi:type="object">CustomModuleRoutingEntityPosts</item>
            </argument>
        </arguments>
    </type>
</config>

For Defining Scope there will be <argument name="defaultScope" xsi:type="string">posts</argument> Global, Frontend, Primary i have seen.

I would like to put condition in di.xml if there is particular URL http://localhost/magento2/mymodule/test.html then only it will call this di.xml file otherwise not.

I have created custom Router.php, when i call Magento 2 Default Category/Product List then also it goes to my custom Router.php, So what's the best way so it's limited to my Custom Module Only.

I'm following https://github.com/tzyganu/Magento2SampleModule/blob/master/Controller/Router.php

When i do

 public function match(\Magento\Framework\App\RequestInterface $request) {
     echo 1;exit;
 }

Each & every Request call this custom router. Which i think not correct. So that's why it needed to define Scope for Router.php via di.xml or Any other Magento Standard way.

Thanks

0

I dont think it is possible to conditionally add router or define that url XXX will be served by this router only.

However i believe there is a way to minimize your problem. In your di.xml, you define sortOrder for the router.

Looking at \Magento\Framework\App\RouterList you will see that magento sorts the routers by this information.

In \Magento\Framework\App\FrontendController

you can see how the route is looked up:

while (!$request->isDispatched() && $routingCycleCounter++ < 100) {
        /** @var \Magento\Framework\App\RouterInterface $router */
        foreach ($this->_routerList as $router) {
            try {
                $actionInstance = $router->match($request);
                if ($actionInstance) {
                    $request->setDispatched(true);
                    $this->response->setNoCacheHeaders();
                    if ($actionInstance instanceof \Magento\Framework\App\Action\AbstractAction) {
                        $result = $actionInstance->dispatch($request);
                    } else {
                        $result = $actionInstance->execute();
                    }
                    break;
                }
            } catch (\Magento\Framework\Exception\NotFoundException $e) {
                $request->initForward();
                $request->setActionName('noroute');
                $request->setDispatched(false);
                break;
            }
        }
    }

Magento goes over the sorted routers, until one of them dispatches the request and then stops. So ideally you want to have as high sort order as possible, so you router is called almost last.

I said almost, because i think CMS module should be last, since it takes care of 404 page. (not tested what happens)

For instance CMS module uses router sort order 60 and the catalog module you mentioned uses 40 (This is in Magento_Url_Rewrite i assume). You use 22 so your router will run first.

I would say if you set sortOrder higher than 40, you should be getting decent results.

Alternatively there are plugins. You can create plugin and do your magic in code. Especially dispatch() function in FrontendController seems like a decent place.

  • So it's thing only related to sortOrder? – Ankit Shah Sep 22 '16 at 2:59
  • It really depends on what are you trying to achieve, but yes. The sortOrder attribute determines which Router gets executed first, second and so on. – Langley Sep 22 '16 at 6:56
  • This answer is useful for me , by using sortOrder node i have managed to change router loading flow like this 1. Catalog Product 2. Custom Router 3. CMS router . For a Custom router i have used sort order as 50. – Aniruddha A Deshpande May 22 '17 at 6:40

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.