You need to create custom router (matcher) for route to your action controller
1. Define your custom router
app/code/Acme/StackExchange/etc/frontend/di.xml
<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
<type name="Magento\Framework\App\RouterList">
<arguments>
<argument name="routerList" xsi:type="array">
<item name="acme_stackexchange" xsi:type="array">
<item name="class" xsi:type="string">Acme\StackExchange\Controller\Router</item>
<item name="disable" xsi:type="boolean">false</item>
<item name="sortOrder" xsi:type="string">50</item>
</item>
</argument>
</arguments>
</type>
</config>
2. Create Routed and implement your match logic
app/code/Acme/StackExchange/Controller/Router.php
<?php
declare(strict_types=1);
namespace Acme\StackExchange\Controller;
use Magento\Framework\App\Action\Forward as ActionForward;
use Magento\Framework\App\ActionFactory;
use Magento\Framework\App\RequestInterface;
use Magento\Framework\App\ResponseInterface;
use Magento\Framework\DataObject;
use Magento\Framework\Event\ManagerInterface as EventManagerInterface;
use Magento\Store\Model\StoreManagerInterface;
class Router implements \Magento\Framework\App\RouterInterface
{
protected ActionFactory $actionFactory;
protected EventManagerInterface $eventManager;
protected StoreManagerInterface $storeManager;
protected ResponseInterface $response;
public function __construct(
ActionFactory $actionFactory,
EventManagerInterface $eventManager,
StoreManagerInterface $storeManager,
ResponseInterface $response
) {
$this->actionFactory = $actionFactory;
$this->eventManager = $eventManager;
$this->storeManager = $storeManager;
$this->response = $response;
}
/**
* @inheritDoc
*/
public function match(RequestInterface $request)
{
$requestPath = $request->getPathInfo();
if (!str_contains($requestPath, '/some-review/')) {
return null;
}
// optional create event
$condition = new DataObject(['request' => $request, 'custom' => 'custom_value']);
$this->eventManager->dispatch(
'acme_controller_router_match_before',
['router' => $this, 'condition' => $condition]
);
// example to verify in store if needed
$store = $this->storeManager->getStore();
// parse request and set your action if applicable
$request->setModuleName('acme')
->setControllerName('result')
->setActionName('review');
// you can set dynamic variables to request like
$request->setParam('param_name', 'param_value');
return $this->actionFactory->create(ActionForward::class);
}
}