Nastavit z presenteru jiný presenter nebo jak mít info o 404 na homepage?
- nettolog
- Člen | 68
Asi na to jdu špatně, ale potřeboval bych, aby se při neexistující stránce zobrazila homepage s flashmessage, že stránka nebyla nalezena.
Na to, že požadavek je 404 přijde aplikace buď tím, že:
- neexistuje routa
- v konkrétním presenteru – nějaký povinný parametr v routě vede na neexistující záznam v databázi (http://example.com/clanek/50; presenter Clanek posléze zjistí, že článek s ID 50 neexistuje)
Napadlo mě v těchto případech poslat status 404, nastavit flashmessage a dát přesměrování na homepage, což funguje, ale to asi není pro vyhledávače vhodné. Nenapadá vás tedy způsob, jak z presenteru říct, že potřebuji jiný presenter a view v jiném presenteru?
Editoval nettolog (1. 8. 2015 16:15)
- nettolog
- Člen | 68
Díky, přesně to jsem hledal. Ale nenapadá vás, jak při forwardu poslat
HTTP header 404? Já sice před forwardem pošlu
header('HTTP/1.1 404 Not Found');
, ale on ho zřejmě ten další
presenter přepíše na 200. Když za forward dám die();
, tak tam
ta 404 je.
Je to ale zvláštní, protože pokud v ErrorPresenteru použiji to samé (forward), tak 404 zůstane.
ErrorPresenter:
class ErrorPresenter extends BasePresenter
{
/** @var ILogger */
private $logger;
public function __construct(ILogger $logger)
{
$this->logger = $logger;
}
/**
* @param Exception
* @return void
*/
public function renderDefault($exception)
{
if ($exception instanceof Nette\Application\BadRequestException) {
$code = $exception->getCode();
// load template 403.latte or 404.latte or ... 4xx.latte
if($code == 404) {
$this->logger->log("HTTP code $code: {$exception->getMessage()} in {$exception->getFile()}:{$exception->getLine()}", 'access');
$this->notify->set("404_page");
$this->forward("Homepage:default");
} else {
$this->setView(in_array($code, array(403, 404, 405, 410, 500)) ? $code : '4xx');
}
// log to access.log
$this->logger->log("HTTP code $code: {$exception->getMessage()} in {$exception->getFile()}:{$exception->getLine()}", 'access');
} else {
$this->setView('500'); // load template 500.latte
$this->logger->log($exception, ILogger::EXCEPTION); // and log exception
}
if ($this->isAjax()) { // AJAX request? Note this error in payload.
$this->payload->error = TRUE;
$this->terminate();
}
}
}
Presenter třeba článků, kde o 404 vím až na základě selectů do db:
<?php
namespace App\Presenters;
use Nette,
App\Model;
/**
* Homepage presenter.
*/
class TestPresenter extends BasePresenter
{
public $database;
public $row;
public function __construct(Nette\Database\Context $database)
{
$this->database = $database;
}
public function actionDefault(){
/* selecty do databaze */
if($row){
$this->row = $row;
}
else
{
header('HTTP/1.1 404 Not Found');
$this->notify->set('404_page');
$this->forward("Homepage:default");
}
}
Netušíte, čím by to mohlo být?
Editoval nettolog (2. 8. 2015 17:31)
- nettolog
- Člen | 68
Tak problém s 200 a 404 jsem vyřešil tak, že místo manuálního
posílání headeru 404 a forwardu vyhodím jen výjimku
Nette\Application\BadRequestException
. Tu pak zpracuji
v ErrorPresenteru úplně stejně jako jsem poslal výše (s forwardem).
Takže to je v pořádku a 404 se načte všude, kde má. Ideálně
vyřešeno, díky za radu.
Editoval nettolog (2. 8. 2015 17:31)