2013-04-13 13 views

Antwort

17

Wie in the Symfony Cookbook gezeigt können Sie Fehlerseiten auf zwei Arten überschreiben:

  • Aufschalten die Vorlagen
  • eine benutzerdefinierte Ausnahme Controller

Wenn Sie nur auf die /sitemap Route anzeigen möchten eine Exception 404 (HttpNotFoundException) Sie konnten die Twig-Ausnahmevorlage überschreiben, indem Sie eine neue Vorlage in app/Resources/TwigBundle/views/Exception/error404.html.twig erstellen.

Eine andere Möglichkeit, die im Kochbuch nicht gezeigt wird, ist die Verwendung eines Ereignis-Listeners. Wenn der Kernel auf eine Ausnahme stößt, wird ein kernel.exception-Ereignis ausgelöst. Standardmäßig wird diese Ausnahme von der Ausnahme abgefangen, die von Twig bereitgestellt wird. Sie können create your own event listener, die für die kernel.exception Ereignis hört und macht eine Seite:

<?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) 
    } 
} 

(ich diesen Code nicht getestet haben, so dass Sie es selbst versuchen sollten, und Sie müssen den Templat-Service in den Hörer Ereignis injizieren selbst! , Na sicher).

+0

Danke, der Event-Listener ist der Weg zu gehen, denke ich, aber $ this-> Templating ist nicht gültig. Ich habe auch versucht $ Event-> Templating. Ich denke nicht, dass übliche Controller-Methoden verfügbar sind. Ich bekomme eine nicht definierte Eigenschaft: Symfony \ Component \ HttpKernel \ Event \ GetResponseForExceptionEvent :: $ Templating in ... – user2143356

+0

Sie haben Recht, die üblichen Controller-Methoden sind nicht verfügbar, da diese Aliasnamen für Methodenaufrufe auf Services sind. Sie sollten den Dienst "Templating" in der Ereignisbeschreibung selbst in den Ereignis-Listener einfügen. –

+0

Ich habe zu dieser Zeit keine Realisten gemacht, das setzt nur eine Twig-Vorlage, keine tatsächliche Seite oder Controller. – user2143356

0

Ich habe eine einfache Web-App, die aus mehreren Symfony3-Bundles besteht, deren Controller einen BaseController erweitern. Ich habe auch einen AdminBundle. Um eine bestimmte Seite für jede nicht existente URL zu zeigen, gehackt ich (und einfacher gemacht) das Original ExceptionController.php (vom 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(); 
    } 
} 

ich meinen Fehler Vorlage definieren, wie ich wollte.

Ich brauche die folgende Zeile in config.yml

twig: 
    exception_controller: MyappAdminBundle:Exception:show 

ps Ich bin sicher, dass mein Code verbessert werden kann hinzufügen, aber es funktioniert gut.

Verwandte Themen