Dynamicke routovani podle url
- turbo80
- Člen | 50
Zdravym, potrebuji poradit jak vytvorit dynamicke routocani.
Www.web.neco/krasny-den/
Presenter:clanky
action:show
V db bych mel ulozeno url(krasny-den), presenter(Clanky),action(show)
a podle url by se poznalo jakej presenter ma url zpracovat doufam ze chapete jak
to myslim. Vubec nevim cim zacit. Predem dekuji za vsechny rady..
- David Matějka
- Moderator | 6445
ahoj, muzes si napsat vlastni router nebo pouzit globalni filtry, kde provedes dotaz a vratis presenter a action v params
- Phalanx
- Člen | 310
Pokud budeš chtít dynamicky pouze články, tak ti bude stačit tohle:
<?php
public static function createRouter(
\CMS_Page $cms_page
) {
$pages = $cms_page->getStaticPagesIdentifiers($lang);
$router[] = new Route('<identifier [a-z0-9_-]+>', array(
'presenter' => 'Clanky',
'action' => 'show',
'identifier' => array(
Route::FILTER_IN => function($identifier) use($pages) {
return !empty($pages[$identifier]) ? $pages[$identifier] : NULL;
}
),
));
?>
přičemž $cms_page je model, kde si tahám všechny možné identifikátory a jen zkontroluju, jestli je identifikátor v poli.
Akorát si tím přidáváš do routeru závislost na databázi. Lepší
řešení by bylo mít v url blog/<slug>
, nechat routu
obecně čímž nepotřebuješ přístup k databázi a zkontroluješ jestli
slug existuje až v presenteru.
Editoval Phalanx (22. 9. 2018 12:48)
- MajklNajt
- Člen | 494
turbo80 napsal(a):
Nebude to jen pro clanky bude tam fotogalerie, apod.. Uz nevim jak na to hraju si stim uz 14 dni a porad nic. Kdyby slo udelat neco.neco/fotgalerie/dovolena-2018 apod neresil bych to fotogalerie by byl presenter dal by to byl slug(id) apod, ale takhle to prave nechci…
Najlepšie budeš mať napísať si vlastný router https://doc.nette.org/…tion/routing#…, tiež to mám tak poriešné na weboch, kde nechcem byť fixovaný na nejakú pevnú schému URL.
Čiže v match() si z databázy vytiahneš riadok podľa URL a vrátiš Nette\Application\Request
V constructUrl() si zas z databázy vytiahneš riadok podľa presenteru a akcie (príp. ID) a vrátiš string obsahujúci URL
Tu je pre inšpiráciu môj router:
use Nette;
use App\Model\RouteFacade;
use App\Model\Entities\Route;
class MyRouter implements Nette\Application\IRouter
{
/** @var RouteFacade */
private $routeFacade;
/**
* MyRouter constructor.
* @param RouteFacade $routeFacade
*/
public function __construct(RouteFacade $routeFacade)
{
$this->routeFacade = $routeFacade;
}
/**
* @param Nette\Http\IRequest $httpRequest
* @return Nette\Application\Request|null
*/
public function match(Nette\Http\IRequest $httpRequest)
{
$url = $httpRequest->getUrl();
$basePath = $url->getBasePath();
if (strncmp($url->getPath(), $basePath, strlen($basePath)) !== 0) {
return null;
}
$path = (string) substr($url->getPath(), strlen($basePath));
$route = $this->routeFacade->findByUrl($path);
if($route instanceof Route) {
$routeParams = $route->getTargetParams();
$params = ["action" => $route->getAction(), "id" => $route->getTargetId(), "locale" => $route->getLocale() ?: "sk"];
if($routeParams) $params += $routeParams;
$params += $httpRequest->getQuery();
return new Nette\Application\Request(
$route->getPresenter(),
$httpRequest->getMethod(),
$params,
$httpRequest->getPost(),
$httpRequest->getFiles(),
[Nette\Application\Request::SECURED => $httpRequest->isSecured()]
);
}
return null;
}
/**
* @param Nette\Application\Request $appRequest
* @param Nette\Http\Url $refUrl
* @return string|null
*/
public function constructUrl(Nette\Application\Request $appRequest, Nette\Http\Url $refUrl)
{
$scheme = $refUrl->getScheme();
$baseUrl = $scheme."://".$refUrl->getAuthority().$refUrl->getBasePath();
$presenter = $appRequest->getPresenterName();
$params = $appRequest->getParameters();
if(key_exists("action", $params)) {
$action = $params["action"];
unset($params["action"]);
}
else $action = "default";
if(key_exists("id", $params)) {
$id = $params["id"];
unset($params["id"]);
}
else $id = null;
if(key_exists("locale", $params)) {
$locale = $params["locale"];
unset($params["locale"]);
}
else $locale = null;
$route = $this->routeFacade->findByRequest($presenter, $action, $id, $params, $locale);
if($route instanceof Route) {
$url = $baseUrl.$route->getUrl();
$params = $this->filterUsedParams($params, $route->getTargetParams());
$query = http_build_query($params);
if($query !== "") {
$url .= "?".$query;
}
return $url;
}
return null;
}
/**
* @param array $params
* @param array|null $used
* @return array
*/
private function filterUsedParams(array $params, array $used = null)
{
if($used) {
foreach($used as $key => $param) {
unset($params[$key]);
}
}
return $params;
}
}