Closed sitole closed 5 years ago
Can be solved now at least in two ways. I'm using following router, when no need to setup different DI container:
<?php
declare(strict_types=1);
namespace App\Routing;
use App\Strict;
use Nette;
use Nette\Application\IRouter;
use Nette\Application\Request;
class DomainRouter implements IRouter
{
use Strict;
/** @var IRouter[] */
private $domains = [];
/** @var IRouter|null */
private $matched;
public function addRouter(string $host, IRouter $router): void
{
$this->domains[$host] = $router;
}
public function match(Nette\Http\IRequest $httpRequest)
{
$host = $httpRequest->getUrl()->getHost();
$this->matched = $this->domains[$host] ?? null;
return $this->matched ? $this->matched->match($httpRequest) : null;
}
public function constructUrl(Request $appRequest, Nette\Http\Url $refUrl)
{
return $this->matched
? $this->matched->constructUrl($appRequest, $refUrl)
: null;
}
}
Usage
$presentation = new RouteList;
$presentation[] = new Route('', 'Home:default');
$section = new RouteList;
$section[] = new Route('', 'Home:default');
$section[] = new Route('login', 'Login:fefault');
$section[] = new Route('logout', 'Login:logout');
$section[] = new Route('clanky', 'Articles:default');
$section[] = new Route('novinky', 'News:default');
$router = new DomainRouter;
$router->addDomain('example.com', $presentation);
$router->addDomain('section.example.com', $section);
And when you need different DI container, setup web server for a different document root with separated index.php
and setup DI container with different router factories.
It looks like a possible solution, but the meaning is different. The list of routers may be a group with specific settings.
Something like:
$params = [
RouteList::PREFIX => '//section.example.com',
RouteList::POSTFIX=> '/',
];
$section = new RouteList('Section', $params);
But I do not know if it's for wide use or just for me. In that case, it does not make sense to add it as new feature.
I want to add to RouteList syntactic sugar similar to forms, ie. instead of
$router = new RouteList();
$router[] = new Route(...);
$router[] = new Route(...);
$router[] = new MyRouter(...);
to allow something like
$router = new RouteList();
$router->addRoute(...);
$router->addRoute(...);
$router->add(new MyRouter...);
Because man don't need to deal with class names so much. And classes can be confusing after merging nette/application#208.
In relation to this issue your code can be written this way:
$router = new RouteList;
$router->withDomain('section.example.com')->withModule('Section')
->addRoute('', 'Home:default')
// Register login presenter
->addRoute('login', 'Login:login')
->addRoute('logout', 'Login:logout')
->addRoute('clanky', 'Articles:default')
->addRoute('novinky', 'News:default');
$router->withDomain('example.com')->withModule('Presentation')
->addRoute('', 'Home:default');
What do you think?
It looks perfect. This features are comming in Nette 3/4 or later?
In my opinion setDomain and setModule is better than with*.
It's not a typical setter. In that case with and add methods return new instances. Also, second call to set* overrides previous call, it's not that case.
@mabar My bad. I thought the addRoute method is called on the $router.
:+1: The withDomain()
will work with patterns, like <foo>.example.com
?
Variables like %tld%
are important, parameters like <foo>
would be useful, but I'm afraid it would complicate the implementation.
Could I still use only RouteList and Route? I have own router builder which prefixes all routes with base part and sort them. Requirement to use domain and module routers would complicate that approach.
In route builder configuration could be base uri defined e.g. like
<part1>.%sld%.%tld%/<part2>/<part3>
(admin.example.com/eshop/eshop-extension
)<lang>.%sld%.%tld%/<part1>/<part2>/<part3>
(en.example.com/admin/eshop/eshop-extension
)RouteList define just these 3 base parts and nette module, without knowledge about how will base url look.
Description
Recently, I've created many multi-domain sites and routing was painful. I think the route list can be the smartest than a simple array of routes and cache. There's my idea about prefix system.
Before:
After: