I'm trying to map pages from database to root of domain:
now I have have
/posts/post1-url
/posts/post2-url/slashed
I want
/post1-url
/post2-url/slashed
How can I make router that matches the strings above with db, and if not matched, continues matching routeList like below?
<?php
public static function createRouter(): RouteList
{
$router = new RouteList;
$router->addRoute('/', 'Home:default');
$router->addRoute('/auth', 'Auth:default');
$router->addRoute('/auth/<action>', 'Auth:<action>');
$router->addRoute('/admin', 'Admin:default');
$router->addRoute('/admin[/<action>][/<slug>]', 'Admin:<action>');
$router->addRoute('/<slug>', 'Home:viewPage');
$router->addRoute('<presenter>/<action>', '<presenter>:<action>');
return $router;
}
I have presenter action that can process showing the database post, but found no way to match route list in action, or other way to combine the match+routeList
I am using this approach.
BlogRouter.php
<?php declare(strict_types=1);
namespace App\Router;
use Nette\Http\IRequest;
use Nette\Http\UrlScript;
use Nette\Routing\Router;
use Nette\Utils\Strings;
final class BlogRouter implements Router
{
private const Posts = [
'first-page',
'second/page',
];
public function match(IRequest $httpRequest): ?array
{
$slug = Strings::trim($httpRequest->getUrl()->getPath(), '/');
if (in_array($slug, self::Posts)) {
return [
'presenter' => 'Blog',
'action' => 'post',
'slug' => $slug,
];
}
return null;
}
public function constructUrl(array $params, UrlScript $refUrl): ?string
{
if (!array_key_exists('slug', $params) || !in_array($params['slug'], self::Posts)) {
return null;
}
return $refUrl->getHostUrl() . '/' . $params['slug'] . '/';
}
}
RouterFactory.php
<?php declare(strict_types=1);
namespace App\Router;
use Nette\Application\Routers\RouteList;
use Nette\Routing\Router;
use Nette\StaticClass;
final class RouterFactory
{
use StaticClass;
public static function createRouter(): RouteList
{
$router = new RouteList;
$router->add(new BlogRouter());
$router->addRoute('/<slug [0-9a-z-]+>/', 'Page:default');
$router->addRoute('/', 'Homepage:default');
return $router;
}
}
You can simply update BlogRouter code to use database. But you should cache uris, not query them on each request.