Chyba 404 – problém s odkazy

Terka04
Člen | 44
+
0
-

Zdravíčko,
už delší dobu mě trápí na Nette pracování se 404. Objevila jsem catchExceptions: true, který mi s tím znatelně pomáhá, ale aktuálně už netuším, jak se posunout dál. Potřebuji vyřešit 404 errory pro projekt, který má více modolů.

config.neon:

application:
	catchExceptions: true
	errorPresenter: Error
	mapping:
		*: App\Presenters\*Module\*Presenter

V adresáři app\Presenters mám moduly Front a Admin. Na stejené úrovni pak BasePresenter.php a ErrorPresenter.php. Pokud je 404 chyba, spustí se ErrorPresenter.php a ten forwarduje na Front/Error4×xPresenter. Ten mám teda upravený tak, že:

<?php
namespace App\Presenters\FrontModule;

use App\Presenters\BasePresenter as BasePresenter;

use Nette;

final class Error4xxPresenter extends BasePresenter
{
    public function renderDefault(Nette\Application\BadRequestException $exception): void
    {
		// Tahle šílenost tady je z důvodu, že mi při 404 (asi router) nepředá informace o locale. Toto by mělo být dočasné řešení.
        // Locale
        if (isset($exception->getTrace()[0]['args'][0]->getParameters()['locale'])) {
            $locale = $exception->getTrace()[0]['args'][0]->getParameters()['locale'];
            $this->locale = $locale;
            $this->template->locale_vlajka = $locale;
        }

		// Pak nějaká kouzla s ověřováním existující šablony a spuštění šablony
		$sablona = "cesta_k_sablone.latte";
		$this->template->setFile($sablona);
?>

Spustí se mi ve správném modulu správný Error404 a přiřadí k němu připravená šablona. Jenže v té šabloně mám odkaz na změnu jazyk (contributte/translator). Ten nedělá nic jiného, než že změní locale (řeší router).

<a n:href="this, 'locale'=>'sk'>Odkaz na změnu jazyka na sk</a>

Router:

$front->addRoute('[<locale=cs cs|pl|sk>/]<presenter>/<action>', 'Homepage:default');

Po redirectu mi to z neexistující stránky domena.local/pl/neco-co-neexistuje přesměruje na domena.local/sk/error4×x a vyskočí mi tuna různorodých chyb. Vypadá to, jako by se nenačetly moduly, @inject atp.

Problém vidím v tom, že to odkáže na /sk/error4×x namísto /sk/neco-co-neexistuje. Neporadil by mi někdo, jak to upravit? :) Moc děkuji za pomoc.

Editoval Terka04 (7. 2. 2023 14:33)

Marek Bartoš
Nette Blogger | 1146
+
0
-

Nette zakazuje routování pro error presenter, a tak v error presenteru správně nefunguje generování odkazů, parametry apod.
Řešení spočívá v tom mít interní error presenter, který dělá forward na jiný error presenter a předává mu originální request. Pro presenter na který se forwarduje už můžeš routu vytvořit, takže v něm vše bude fungovat správně. Jediné co musíš ve forwardovaném error presenteru řešit je, zda k němu uživatel nepřistoupil přímo přes url a simulovat 404


V odkazovaném kódu mám upravené logování, mapování presenterů přímo přes název třídy, action a render bez Default a odlišné hledání šablon, tak si je uprav tak, jak obvykle v Nette fungují. Jinak můžeš použít prakticky celý můj src/Error.

Error presentery pro konkrétní moduly přidávám v neonu – podle regexu se kontroluje, zda název třídy obsahuje Admin nebo Administration a forwarduje se na error presenter z administrace. Šlo by to upravit i na detekci podle url, aby to fungovalo i v případě, kdy se přistoupilo na url, pro kterou žádný presenter není.

Editoval Marek Bartoš (7. 2. 2023 14:56)

Terka04
Člen | 44
+
0
-

Moc děkuji za odpověď a popostrčení. Nevím, jestli jsem to všechno pochopila správně, pokrok v přepínání jazyků je, už asi jen ten router vyřešit.

config.neon

application:
	catchExceptions: true
	errorPresenter: Front:Error4xx
	mapping:
		*: App\Presenters\*Module\*Presenter

Aktuálně testuji vše na frontu, tedy by tady určitě nemělo zůstat Front:Error4×x, ale nějak univerzálně pro všechny moduly. Tu nevím, jak toho docílit.

Simulaci 404 jsem doplnila do error4×xPresenter takto:

$this->httpResponse->setCode(404);

Do routeru jsem přidala toto:

$front->addRoute('[<locale=cs cs|pl|sk>/]chyba', "Error4xx:default");

Aktuálně tedy přepínání jazyků jde, chyby už to nehází, ale při odkazu změně jazyk (klik na link) mi to z domena.cz/pl/neexistujici odkáže na domena.local/sk/chyba.
Ta chyba se tam objeví kvůli routeru, ale jak docílit toho, aby se tam furt ukazovala špatně ta adresa, tzn. domena.cz/sk/neexistujici?

Moc děkuji.

Marek Bartoš
Nette Blogger | 1146
+
0
-

jak docílit toho, aby se tam furt ukazovala špatně ta adresa

Napadá mě routa s parametrem, který odchytí všechno za jazykem, včetně lomítka a routa bude poslední v route listu. Tak bys neměla string chyba, ale cokoli co zaslal uživatel.

Případně použít redirectToUrl a nahradit jazyk v routě přes string replace, kdybys první řešení nemohla použít.

Aktuálně testuji vše na frontu, tedy by tady určitě nemělo zůstat Front:Error4×x, ale nějak univerzálně pro všechny moduly. Tu nevím, jak toho docílit

Je to tak v mém ErrorForwardPresenter. Je to ten presenter, který má Nette zapsaný v konfiguraci. Pokud regex obsažený v $this->errorPresenters matchne, tak se přesměruje na konfigurovaný error presenter (např. v administraci). Pokud ne, tak se přesměruje na výchozí error v presenter ve veřejné části webu.

Simulaci 404 jsem doplnila do error4×xPresenter takto

Nezapomínej zpracovat i exception předanou z interního error presenteru. Jen pokud žádná exception není, tak chceš simulovat 404

Editoval Marek Bartoš (7. 2. 2023 15:30)