Nastavit z presenteru jiný presenter nebo jak mít info o 404 na homepage?

Upozornění: Tohle vlákno je hodně staré a informace nemusí být platné pro současné Nette.
nettolog
Člen | 68
+
0
-

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)

Unlink
Člen | 298
+
+2
-

No neviem či to je správny prístup, ale to čo požaduješ by mal riešiť forward

nettolog
Člen | 68
+
0
-

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
+
0
-

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)