Router na články, aktuality, statické stránky

Terka04
Člen | 44
+
0
-

Dobrý den,
potřebovala bych poradit, jakým způsobem mohu nastavit router a presentery. Hledal jsem v návodu, ale nenašla jsem to, co bych potřebovala.

https://www.domain.tld/neco
https://www.domain.tld/neco-jineho
https://www.domain.tld/neco-uplne-jineho

Výsledkem by mělo být, aby tyto adresy fungovaly, nicméně za lomítkem je uvedena adresa, která je uložena v databázi.

  • /neco = aktualita
  • /neco-jineho = článek v blogu
  • /neco-uplne-jineho = statická stránka

Podle databáze se určí, jestli se jedná o aktualitu, článek na blogu nebo statickou stránku a dle toho to zvolilo příslušný presenter. Parametr url nikdy nebude stejný, tzn. nemůže se stát, že by stejné URL bylo např. v aktualitě i blogu.

Jde mi tedy vlastně o to, aby:

  • /neco = /aktualita/neco | aktualita[/url]
  • /neco-jineho = /blog/neco-jinaho | blog[/url]
  • /neco-uplne-jineho = /staticka-stranka/neco-uplne-jineho | staticka-stranka[/url]

Ale vlastně aby se v URL nezobrazoval reálný presenter.

Neřešil jste to už někdo? :) Děkuji za pomoc.

Pavel Kravčík
Člen | 1196
+
+2
-

Jasně, můžeš si zavolat custom callback a tam si upravit cokoliv. :)

https://doc.nette.org/…tion/routing#…

Kamil Valenta
Člen | 820
+
+3
-
$router[] = new Route('/<slug>', [
    'presenter' => 'Aktualita',
    'action' => 'default',
    NULL => array(
        Route::FILTER_IN => function (array $params) {
            return $this->filterAktualityIn($params);
        },
        Route::FILTER_OUT => function (array $params) {
            return $this->filterAktualityOut($params);
        }
    ),
]);

$router[] = new Route('/<slug>', [
    'presenter' => 'Blog',
    'action' => 'default',
    NULL => array(
        Route::FILTER_IN => function (array $params) {
            return $this->filterBlogIn($params);
        },
        Route::FILTER_OUT => function (array $params) {
            return $this->filterBlogOut($params);
        }
    ),
]);

$router[] = new Route('/<slug>', [
    'presenter' => 'StatickaStranka',
    'action' => 'default',
    NULL => array(
        Route::FILTER_IN => function (array $params) {
            return $this->filterStatickeStrankyIn($params);
        },
        Route::FILTER_OUT => function (array $params) {
            return $this->filterStatickeStrankyOut($params);
        }
    ),
]);

public function filterAktualityIn($params)
{
    if ($this->database->table('aktuality')->where('slug', $params['slug'])->fetch()) {
        return $params;
    } else {
        return NULL;
    }
}

V reálu je dobré ještě slugy cachovat, ať každá routa nesahá do db…

Terka04
Člen | 44
+
0
-

Kamil Valenta
Ty jsi bůh! Mockrát děkuji! :) Trochu jsem si to upravila pro novou verzi routeru a pro testování a vypadá to funkčně! Už si to jen upravím dle potřeby a bude to fungovat. Tohle mi opravdu moc pomohlo. :)

Jen drobnost.

$this->filterAktualityIn($params);

mi nechce odkazovat na

public function filterAktualityIn()

Hlásí mi to „Using $this when not in object context“. Co mohu mít špatně? Metoda existuje. Obecně mi v routeru nechce fungovat ani __construct() – nedělá nic.

Editoval Terka04 (19. 4. 2022 13:44)

Pepino
Člen | 257
+
0
-

@Terka04 Jak máš udělaný router? Pokud podle dokumentace tak ho musíš trošku upravit.
místo

public static function createRouter()
public function createRouter()

a v neonu ho zaregistruj

	- App\Model\Router\RouterFactory
	router:
		class: Nette\Application\IRouter
		create: @App\Model\Router\RouterFactory::create

pak by ti to mělo fungovat. Včetně konstruktoru.

Terka04
Člen | 44
+
0
-

Ořezaně (dala jsem pryč ONE_WAY a další moduly a úpravený moduly) mám router takto:

<?php
declare(strict_types=1);

namespace App\Router;

use Nette;
use Nette\Application\Routers\Route;
use Nette\Application\Routers\RouteList;
use Nette\Database\Context;
use Tracy\Debugger;

final class RouterFactory
{
    use Nette\StaticClass;

    public static function createRouter(Context $database): RouteList
    {
        $router = new RouteList();

        /** Back **/
        $router[] = $admin = new RouteList('Back');
        $admin->addRoute('admin/<presenter>/<action>[/<id>]', 'Homepage:default');

        /** Front **/
        $router[] = $front = new RouteList('Front');
        $front->addRoute('<presenter>/<action>', 'Homepage:default');

        return $router;
    }
}

Static vyhodit nemůžu (už jsem zkoušela), protože

Non-static method App\Router\RouterFactory::createRouter() should not be called statically

Editoval Terka04 (19. 4. 2022 14:15)

Pepino
Člen | 257
+
+2
-

@Terka04

<?php
declare(strict_types=1);

namespace App\Router;

use Nette;
use Nette\Application\Routers\Route;
use Nette\Application\Routers\RouteList;
use Nette\Database\Context;
use Tracy\Debugger;

final class RouterFactory
{
    use Nette\StaticClass;

	public $database;

	public function __construct(Context $database) {
		$this->database = $database;
	}

    public function createRouter(): RouteList
    {
        $router = new RouteList();

        /** Back **/
        $router[] = $admin = new RouteList('Back');
        $admin->addRoute('admin/<presenter>/<action>[/<id>]', 'Homepage:default');

        /** Front **/
        $router[] = $front = new RouteList('Front');
        $front->addRoute('<presenter>/<action>', 'Homepage:default');

        return $router;
    }
}

a v neonu

	- App\Router\RouterFactory
	router:
		class: Nette\Application\IRouter
		create: @App\Router\RouterFactory::createRouter

Editoval Pepino (19. 4. 2022 14:17)

Terka04
Člen | 44
+
0
-

Ok, bylo to neonem. Tak mi to šlape jak hodinky. Díky moc, kluci! ♥