2013-04-13 19 views
11

Thay vì trang lỗi/404 Tôi muốn chỉ hiển thị trang/sơ đồ trang web. Tất nhiên tôi không muốn chuyển hướng và tôi vẫn muốn đặt tiêu đề phản hồi HTTP 404.Hiển thị tuyến đường cụ thể thay vì trang lỗi (404) - Symfony2

Điều này có khả thi không? Tất cả những gì tôi có thể thấy là làm thế nào để thiết lập các mẫu trong Twig.

Tôi chắc chắn không muốn chuyển hướng.

Trả lời

17

Như đã trình bày trong the Symfony Cookbook bạn có thể ghi đè lên các trang lỗi theo hai cách:

  • Trọng mẫu
  • Sử dụng một bộ điều khiển tùy chỉnh ngoại lệ

Nếu bạn chỉ muốn hiển thị /sitemap tuyến đường trên một ngoại lệ 404 (HttpNotFoundException), bạn có thể ghi đè mẫu ngoại lệ Twig bằng cách tạo mẫu mới trong app/Resources/TwigBundle/views/Exception/error404.html.twig.

Một cách khác không được hiển thị trong sách dạy nấu ăn là sử dụng trình xử lý sự kiện. Khi hạt nhân gặp một ngoại lệ, một sự kiện kernel.exception được gửi đi. Theo mặc định, ngoại lệ này bị bắt bởi việc nghe ngoại lệ do Twig cung cấp. Bạn có thể create your own event listener mà nghe cho sự kiện kernel.exception và ám một page:

<?php 
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; 
use Symfony\Component\HttpKernel\Event\GetResponseForExceptionEvent; 
use Symfony\Component\HttpFoundation\Response; 

public function onKernelException(GetResponseForExceptionEvent $event) 
{ 
    if ($event->getException() instanceof NotFoundHttpException) { 
     $response = $this->templating->renderResponse(/* sitemap */); 

     $event->setResponse($response) 
    } 
} 

(tôi đã không kiểm tra mã này, vì vậy bạn nên thử nó cho mình Và bạn phải tiêm dịch vụ khuôn mẫu vào lắng nghe sự kiện chính mình! , tất nhiên).

+0

Cảm ơn, người nghe sự kiện là con đường để tôi nghĩ, nhưng $ this-> templating không hợp lệ. Tôi cũng đã thử $ event-> templating. Tôi không nghĩ rằng phương pháp điều khiển thông thường có sẵn. Tôi nhận được một thuộc tính Undefined: Symfony \ Component \ HttpKernel \ Event \ GetResponseForExceptionEvent :: $ templating in ... – user2143356

+0

Bạn đúng, các phương thức điều khiển thông thường không có sẵn vì đó là các bí danh cho các cuộc gọi phương thức trên các dịch vụ. Bạn nên tiêm dịch vụ 'templating' vào trình lắng nghe sự kiện trong phần mô tả dịch vụ. –

+0

Tôi đã không hiện thực tại thời điểm này chỉ cần thiết lập một mẫu Twig, không phải là một trang hoặc bộ điều khiển thực sự. – user2143356

0

Tôi có một ứng dụng web đơn giản được tạo bởi một số gói Symfony3, tất cả các bộ điều khiển của chúng đều mở rộng BaseController. Tôi cũng có một AdminBundle. Để hiển thị một trang nhất định cho mỗi url không tồn tại, tôi bị hack (và thực hiện đơn giản) các ExceptionController.php gốc (từ TwigBundle):

<?php 

namespace MyApp\AdminBundle\Controller; 

use Symfony\Bundle\FrameworkBundle\Controller\Controller; 
use Symfony\Component\HttpFoundation\Response; 
use Symfony\Component\HttpFoundation\Request; 

use Sensio\Bundle\FrameworkExtraBundle\Configuration\Method; 
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route; 
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Template; 
use MyApp\Controller\BaseController; 

use Symfony\Component\Debug\Exception\FlattenException; 
use Symfony\Component\HttpKernel\Log\DebugLoggerInterface; 

class ExceptionController extends BaseController 
{ 
    /** 
    * Converts an Exception to a Response. 
    * 
    * @param Request    $request The request 
    * @param FlattenException  $exception A FlattenException instance 
    * @param DebugLoggerInterface $logger A DebugLoggerInterface instance 
    * 
    * @return Response 
    * @throws \InvalidArgumentException When the exception template does not exist 
    */ 
    public function showAction(Request $request, FlattenException $exception, DebugLoggerInterface $logger = null) 
    { 
     $currentContent = $this->getAndCleanOutputBuffering($request->headers->get('X-Php-Ob-Level', -1)); 
     $code = $exception->getStatusCode(); 
     return $this->render('MyappAdminBundle:Admin:error.html.twig', 
      array(
       'status_code' => $code, 
       'status_text' => isset(Response::$statusTexts[$code]) ? Response::$statusTexts[$code] : '', 
       'exception' => $exception, 
       'logger' => $logger, 
       'currentContent' => $currentContent, 
      ) 
     ); 
    } 

    /** 
    * @param int $startObLevel 
    * 
    * @return string 
    */ 
    protected function getAndCleanOutputBuffering($startObLevel) 
    { 
     if (ob_get_level() <= $startObLevel) { 
      return ''; 
     } 

     Response::closeOutputBuffers($startObLevel + 1, true); 

     return ob_get_clean(); 
    } 
} 

tôi xác định mẫu lỗi của tôi như tôi thích.

tôi cần phải thêm dòng sau trong config.yml

twig: 
    exception_controller: MyappAdminBundle:Exception:show 

ps Tôi chắc chắn mã của tôi có thể được cải thiện, nhưng nó hoạt động tốt.

Các vấn đề liên quan