简体   繁体   中英

Symfony2 - Use same controller but different view based on HTTP host?

Like the title says, I would like to use the same controller, but different views, based on the HTTP host name. Is this possible? What would be the best architecture to accomplish it?

If the controller returns null then the Symfony 2 request handler will dispatch a KernelEvents::VIEW event.

You can make yourself a view listener ( http://symfony.com/doc/current/cookbook/service_container/event_listener.html ) to catch the event. Your view listener would then need the logic to determine which view to create based on request parameters such as the host name. The view would then create the response object. The listener then sets the response in the event.

Is this the "best" approach. Hard to say. There is no reason why the controller itself could not create the view. On the other hand, with a view listener you can share views with multiple controllers. Really depends on your application.

Here is an example of a view listener which kicks off different views depending on the _format attribute.

namespace Cerad\Bundle\CoreBundle\EventListener;

use Symfony\Component\DependencyInjection\ContainerAware;

use Symfony\Component\HttpKernel\KernelEvents;
use Symfony\Component\HttpKernel\Event\GetResponseForControllerResultEvent;

use Symfony\Component\EventDispatcher\EventSubscriberInterface;

class ViewEventListener extends ContainerAware implements EventSubscriberInterface
{

const ViewEventListenerPriority = -1900;

public static function getSubscribedEvents()
{
    return array(
        KernelEvents::VIEW => array(
            array('onView', self::ViewEventListenerPriority),
        ),
    );
}
/* =================================================================
 * Creates and renders a view
 */
public function onView(GetResponseForControllerResultEvent $event)
{
    $request = $event->getRequest();

    if ($request->attributes->has('_format')) 
    {
        $viewAttrName = '_view_' . $request->attributes->get('_format');
    }
    else $viewAttrName = '_view';

    if (!$request->attributes->has($viewAttrName)) return;

    $viewServiceId = $request->attributes->get($viewAttrName);

    $view = $this->container->get($viewServiceId);

    $response = $view->renderResponse($request);

    $event->setResponse($response);
}
# services.yml
cerad_core__view_event_listener:
    class:  '%cerad_core__view_event_listener__class%'
    calls:
        - [setContainer, ['@service_container']]
    tags:
        - { name: kernel.event_subscriber }

# routing.yml
cerad_game__project__schedule_team__show:
    path:  /project/{_project}/schedule-team.{_format}
    defaults: 
        _controller: cerad_game__project__schedule_team__show_controller:action
        _model:      cerad_game__project__schedule_team__show_model_factory
        _form:       cerad_game__project__schedule_team__show_form_factory
        _template: '@CeradGame\Project\Schedule\Team\Show\Twig\ScheduleTeamShowPage.html.twig'
        _format:     html
        _view_csv:   cerad_game__project__schedule_team__show_view_csv
        _view_xls:   cerad_game__project__schedule_team__show_view_xls
        _view_html:  cerad_game__project__schedule_team__show_view_html
    requirements:
        _format:  html|csv|xls|pdf

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM