0

I'm looking to create a custom router so that if I go to www.mysite.com/promotions/cruise-trip it would route to www.mysite/offers/promotions/index/id/5 for example. I'm not really sure how to do this though. I currently have the following set up:

etc/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 frontName="offers" id="offers">
            <module name="Hurdo_Offers"/>
        </route>
    </router>
</config>

etc/di.xml

<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="customrouter" xsi:type="array">
                    <item name="class" xsi:type="string">Hurdo\Promotions\Controller\Router</item>
                    <item name="disable" xsi:type="boolean">false</item>
                    <item name="sortOrder" xsi:type="string">22</item>
                </item>
            </argument>
        </arguments>
    </type>
</config>

Hurdo/Promotions/Controller/Router.php

<?php
namespace Hurdo\Promotions\Controller;

use \Magento\Framework\App\ActionFactory;
use \Magento\Framework\App\ResponseInterface;
use \Magento\Framework\App\RequestInterface;

class Router implements \Magento\Framework\App\RouterInterface
{
    protected $actionFactory;

    protected $_response;

    public function __construct(
        ActionFactory $actionFactory,
        ResponseInterface $response
    ) {
        $this->actionFactory = $actionFactory;
        $this->_response = $response;
    }

    public function match(RequestInterface $request)
    {
        $identifier = trim($request->getPathInfo(), '/');

        if (strpos($identifier, 'promotions') !== false) {
            $request->setModuleName('offers')-> //module name
                setControllerName('promotions')-> //controller name
                setActionName('index')-> //action name
                setParam('id', 5); //custom parameters
        } else {
            return false;
        }

        return $this->actionFactory->create(
            'Magento\Framework\App\Action\Forward',
            ['request' => $request]
        );
    }
}

But I've no idea how to get this to work with a url key such as cruise-trip etc. Thanks guys for your help

1 Answer 1

1

Please replace below code with your router file according to your url-key.

<?php
namespace Hurdo\Promotions\Controller;

use \Magento\Framework\App\ActionFactory;
use \Magento\Framework\App\ResponseInterface;
use \Magento\Framework\App\RequestInterface;

class Router implements \Magento\Framework\App\RouterInterface
{
    protected $actionFactory;

    protected $_response;

    public function __construct(
        ActionFactory $actionFactory,
        ResponseInterface $response
    ) {
        $this->actionFactory = $actionFactory;
        $this->_response = $response;
    }

    public function match(RequestInterface $request)
    {
        $identifier = trim($request->getPathInfo(), '/');
        $id = '';
        if (strpos($identifier, 'promotions') !== false) {

            $finalKey = explode('/', $identifier);
            $urlKey = end($finalKey);

            $objectManager = \Magento\Framework\App\ObjectManager::getInstance();
            $offerModel = $objectManager->get('Namespace\Vendor\Model\Offers')->load($urlKey,'url-key');
            if($offerModel->getId() {
                $id = $offerModel->getId();
            }

            if($id) {
                $request->setModuleName('offers')-> //module name
                    setControllerName('promotions')-> //controller name
                    setActionName('index')-> //action name
                    setParam('id', $id); //custom parameters
            } 
        }else {
            return false;
        }

        return $this->actionFactory->create(
            'Magento\Framework\App\Action\Forward',
            ['request' => $request]
        );
    }
}
14
  • Thanks for your reply @ZealousWeb. Hmm, it's still not working as expected. Just to give a little bit more detail, I have a model set up called Offer. Each instance of this has an id as well as a url-key parameter. So what I'm looking for, is when I search for www.mysite.com/promotions/cruise-trip, it would set the information for the Cruise Trip object matching with id 5 and url-key cruise-trip in the database. I hope that makes sense?
    – SNAFU
    Commented Mar 18, 2021 at 11:53
  • If you want like this then you need to get parameter id in your block or template file then you need to filter by id in your custom collection.
    – ZealousWeb
    Commented Mar 18, 2021 at 11:58
  • that's the issue at the moment, I want the user who enters www.mysite.com/promotion/cruise-ship to be taken to the mysqite.com/offers/promotions/id/5 at which point in my template, I could get the id parameter to load the relevant information for the cruise ship offer with id 5 etc. I just need to know how to process the end of a Url like /promotions/cruise-ship or promotions/five-star-hotel so that it knows whether to load information for the cruise ship offer, or the 5 star hotel offer for example.
    – SNAFU
    Commented Mar 18, 2021 at 12:11
  • 1
    Edited my answer again. We don't need to put condition in your case.
    – ZealousWeb
    Commented Mar 18, 2021 at 12:35
  • 1
    Your answer has resolved this @ZealousWeb, thanks again for your help man :) I really need to double check that my di.xml is in etc/frontend instead of /etc in future :D
    – SNAFU
    Commented Mar 18, 2021 at 13:18

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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