Chyba 404 – problém s odkazy
- Terka04
- Člen | 44
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/Error4xxPresenter. 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/error4xx 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/error4xx 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 | 1280
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
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:Error4xx, ale nějak univerzálně pro všechny moduly. Tu nevím, jak toho docílit.
Simulaci 404 jsem doplnila do error4xxPresenter 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 | 1280
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)