ZF2 – Come modificare la pagina di errore / risposta 404? Non solo template ma per impostare un nuovo ViewModel

Per impostazione predefinita, la pagina è impostata in questo modo nell'arrays module.config Application :

 'template_map' => arrays( 'error/404' => __DIR__ . '/../view/error/404.phtml' 

Voglio cambiare la pagina. Voglio un nuovo ViewModel pieno di variables. Significa che semplicemente cambiare il model non è abbastanza:

 'error/404' => __DIR__ . '/../view/error/my_new_404_template.phtml' 

Ma non riesco a capire come farlo. Non riesco a vedere il modo in cui la richiesta arriva all 'error/404' .

Ad esempio, ho un tale metodo per la pagina 'error/404' :

 public function pageNotFoundAction() { $view = new ViewModel(); $view->setTemplate('error/404'); // set my template $sm = $this->getServiceLocator()->get('SessionManager'); $cont = new Container('SomeNamespace', $sm); $view->var1 = $cont->offsetGet('someValue1'); // the "error/404" template $view->var2 = $cont->offsetGet('someValue2'); // is full of variables $view->var3 = $cont->offsetGet('someValue3'); $view->var4 = "One more view variable"; // And now I return it somewhere and want it to be called // in case of "the page is not found" return $view; } 

Come fare un tale cambiamento? Non riesco a get il sistema che hanno creato per gestire cose come 'error/404' . Per favore aiuto.

UPD 1

Compito ancora più complicato Come avere diverse pagine di 'error/404' ? Vorrei chiedere ai ragazzi che hanno creato il framework se sanno che 'not_found_template' non può avere un arrays di pagine 'error/404' . Come può essere? Se imposto questa opzione in questo modo:

 'template_map' => arrays( 'error/404' => __DIR__ . '/../view/error/404.phtml', 'my-page/one_more_error404' => __DIR__ . '/../view/my-page/my-page/one_more_error404.phtml', 'other_page/second_404' => __DIR__ . '/../view/other-page/one_more_error404.phtml', 'not_found_template' => arrays( 'error/404', 'my-page/one_more_error404', 'other-page/second_404', ); 

genera un errore. 'not_found_template' ti obbliga ad avere un solo model 'error/404' ?

C'è un altro modo. Per prendere un EVENT_DISPATCH_ERROR e ribuild totalmente viewModel . Cavern è quel layout – è un root viewModel , e il contenuto aggiunto al layout di default è un altro viewModel (figlio). Questi punti non sono così chiari descritti nei documenti ufficiali.

Ecco come può apparire nel tuo Module.php :

 public function onBootstrap(MvcEvent $event) { $app = $event->getParam( 'application' ); $eventManager = $app->getEventManager(); /** attach Front layout for 404 errors */ $eventManager->attach( MvcEvent::EVENT_DISPATCH_ERROR, function( MvcEvent $event ){ /** here you can retrieve anything from your serviceManager */ $serviceManager = $event->getApplication()->getServiceManager(); $someVar = $serviceManager->get( 'Some\Factory' )->getSomeValue(); /** here you redefine layout used to publish an error */ $layout = $serviceManager->get( 'viewManager' )->getViewModel(); $layout->setTemplate( 'layout/start' ); /** here you redefine template used to the error exactly and pass custom variable into ViewModel */ $viewModel = $event->getViewModel(); $viewModel->setVariables( arrays( 'someVar' => $someVar ) ) ->setTemplate( 'error/404' ); }); } 

Non sono sicuro di seguire ciò che stai cercando di get, puoi dare un chiaro esempio di ciò che stai cercando di fare?

Se stai semplicemente cercando di aggiungere variables al model di visualizzazione passato, potresti farlo anche sul controller, controlla AbstractActionController

 /** * Action called if matched action does not exist * * @return arrays */ public function notFoundAction() { $response = $this->response; $event = $this->getEvent(); $routeMatch = $event->getRouteMatch(); $routeMatch->setParam('action', 'not-found'); if ($response instanceof HttpResponse) { return $this->createHttpNotFoundModel($response); } return $this->createConsoleNotFoundModel($response); } /** * Create an HTTP view model representing a "not found" page * * @param HttpResponse $response * @return ViewModel */ protected function createHttpNotFoundModel(HttpResponse $response) { $response->setStatusCode(404); // Add in extra stuff from your ServiceLocator here... // $viewModel->setTemplate(..); return new ViewModel(arrays( 'content' => 'Page not found', )); } 

La prima cosa è creare le viste:

moduli / Yourapplication / view / yourapplication / error / index.phtml

moduli / Yourapplication / view / yourapplication / error / 404.phtml

La seconda cosa è registrare le viste nella configuration del module:

In module.config.php della tua applicazione

 'view_manager' => arrays( //[...] 'not_found_template' => 'error/404', 'exception_template' => 'error/index', 'template_map' => arrays( //[...] 'error/404' => __DIR__ . '/../view/yourapplication/error/404.phtml', 'error/index' => __DIR__ . '/../view/yourapplication/error/index.phtml', ), // [...] ), 

L'ho usato per gestire l'errore 404 (ho spostato il mio sito web da spip a ZF2 basato su cms):

Nella function module onBootstrap:

 $eventManager->getSharedManager()->attach('*', MvcEvent::EVENT_DISPATCH_ERROR, arrays($this, 'onDispatchError'), -100); 

Poi

 public function onDispatchError(MvcEvent $event) { $response = $event->getResponse(); if ($response->getStatusCode() == 404) { $url = $event->getRouter()->assemble(arrays(), arrays('name' => 'index')); $requestUri = $event->getRequest()->getRequestUri(); $response->getHeaders()->addHeaderLine('Location', "$url?url=$requestUri"); $response->setStatusCode(200); $response->sendHeaders(); $event->stopPropagation(true); } elseif($response->getStatusCode() == 500){ //DO SOMETHING else? return; } } 

In questo codice non restituiamo mai un errore 404, chiamiamo semplicemente la route (nel mio indice di esempio) con l'url richiesto come param

Spero di aiutarti.

O più semplicemente (where vuoi):

 /* @var \Zend\Mvc\View\Http\RouteNotFoundStrategy $strategy */ $strategy = $this->getServiceLocator()->get('HttpRouteNotFoundStrategy'); $strategy->setNotFoundTemplate('application/other/404'); $view = new ViewModel(); //$view->setTemplate('application/other/404'); return $view; 

Per prima cosa devi dissociare la notfundundategategy di default e nel tuo Module.php e nel caso di un 404, dovresti restituire un nuovo viewmodel dal controller. Si prega di consultare questo post: http://www.cagataygurturk.com/zf2-controller-specific-not-found-page/

in module.php puoi anche cambiare template e layout.

 function onBootstrap(EventInterface $e) { $app = $e->getApplication(); $evt = $app->getEventManager(); $evt->attach(MvcEvent::EVENT_DISPATCH_ERROR, arrays($this,'onDispatchError'), 100); } function onDispatchError(MvcEvent $e) { $vm = $e->getViewModel(); $vm->setTemplate('layout/blank'); }