ZF2 - How to change the error/404 response page? Not just template but to set a new ViewModel

前端 未结 7 2447
离开以前
离开以前 2021-01-05 22:46

By default the page is set like this in the Application module.config array:

\'template_map\' => array(
    \'error/404\' => __DIR__ . \'/         


        
相关标签:
7条回答
  • 2021-01-05 23:22

    The First thing is to create the views :

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

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

    The second thing is to register the views in the module config:

    In module.config.php of your application

    'view_manager' => array(
            //[...]
            'not_found_template'       => 'error/404',
            'exception_template'       => 'error/index',
            'template_map' => array(
            //[...]
            'error/404'   => __DIR__ . '/../view/yourapplication/error/404.phtml',
            'error/index' => __DIR__ . '/../view/yourapplication/error/index.phtml',
            ),
       // [...]
        ),
    
    0 讨论(0)
  • 2021-01-05 23:23

    Or more simply (where you want) :

    /* @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;
    
    0 讨论(0)
  • 2021-01-05 23:30

    You should first detach default notfoundstrategy and in your Module.php and in case of a 404, you should return a new viewmodel from the controller. Please see this post: http://www.cagataygurturk.com/zf2-controller-specific-not-found-page/

    0 讨论(0)
  • 2021-01-05 23:31

    I used this to manage 404 error (I moved my website from spip to ZF2 based cms) :

    In module onBootstrap function :

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

    Then

    public function onDispatchError(MvcEvent $event)
    {
        $response = $event->getResponse();
        if ($response->getStatusCode() == 404) {
            $url = $event->getRouter()->assemble(array(), array('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 this code we never return a 404 error, we just call the route (in my example index) with the requested url as param

    I hope that help you.

    0 讨论(0)
  • 2021-01-05 23:38

    There is another way. To catch an EVENT_DISPATCH_ERROR and totally rebuild viewModel. Cavern is that layout – is a root viewModel, and content appended into layout by default is another viewModel (child). These points are not such clear described in official docs.

    Here is how it can look like in your 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( array( 'someVar' => $someVar ) )
                      ->setTemplate( 'error/404' );
        });
    }
    
    0 讨论(0)
  • 2021-01-05 23:39

    I am not sure I follow what you are trying to achieve, can you give a clear example of what you are trying to do?

    If you are simply trying to add variables to the view model passed you could even do this in your controller, check out AbstractActionController

    /**
     * Action called if matched action does not exist
     *
     * @return array
     */
    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(array(
            'content' => 'Page not found',
        ));
    }
    
    0 讨论(0)
提交回复
热议问题