@@ -534,24 +534,26 @@ priority. Typically, you will register this during the bootstrap event.
534534``` php
535535namespace Content;
536536
537+ use Zend\Mvc\MvcEvent;
538+
537539class Module
538540{
539541 /**
540- * @param \Zend\Mvc\ MvcEvent $e The MvcEvent instance
542+ * @param MvcEvent $e The MvcEvent instance
541543 * @return void
542544 */
543- public function onBootstrap($e)
545+ public function onBootstrap(MvcEvent $e)
544546 {
545547 // Register a dispatch event
546548 $app = $e->getParam('application');
547549 $app->getEventManager()->attach('dispatch', [$this, 'setLayout']);
548550 }
549551
550552 /**
551- * @param \Zend\Mvc\ MvcEvent $e The MvcEvent instance
553+ * @param MvcEvent $e The MvcEvent instance
552554 * @return void
553555 */
554- public function setLayout($e)
556+ public function setLayout(MvcEvent $e)
555557 {
556558 $matches = $e->getRouteMatch();
557559 $controller = $matches->getParam('controller');
@@ -583,16 +585,12 @@ within your application.
583585- ` Zend\View\Strategy\PhpRendererStrategy ` . This strategy is a "catch-all" in
584586 that it will always return the ` Zend\View\Renderer\PhpRenderer ` and populate
585587 the Response body with the results of rendering.
586- - ` Zend\View\Strategy\JsonStrategy ` . This strategy inspects the ` Accept ` HTTP
587- request header, if present, and determines if the client has indicated it
588- accepts an ` application/json ` response. If so, it will return the
588+ - ` Zend\View\Strategy\JsonStrategy ` . This strategy will return the
589589 ` Zend\View\Renderer\JsonRenderer ` , and populate the Response body with the
590590 JSON value returned, as well as set a ` Content-Type ` header with a value of
591591 ` application/json ` .
592- - ` Zend\View\Strategy\FeedStrategy ` . This strategy inspects the ` Accept ` HTTP
593- header, if present, and determines if the client has indicated it accepts
594- either an ` application/rss+xml ` or ` application/atom+xml ` response. If so, it
595- will return the ` Zend\View\Renderer\FeedRenderer ` , setting the feed type to
592+ - ` Zend\View\Strategy\FeedStrategy ` . This strategy will return the
593+ ` Zend\View\Renderer\FeedRenderer ` , setting the feed type to
596594 either "rss" or "atom", based on what was matched. Its Response strategy will
597595 populate the Response body with the generated feed, as well as set a
598596 ` Content-Type ` header with the appropriate value based on feed type.
@@ -606,13 +604,15 @@ register the `JsonStrategy`:
606604``` php
607605namespace Application;
608606
607+ use Zend\Mvc\MvcEvent;
608+
609609class Module
610610{
611611 /**
612- * @param \Zend\Mvc\ MvcEvent $e The MvcEvent instance
612+ * @param MvcEvent $e The MvcEvent instance
613613 * @return void
614614 */
615- public function onBootstrap($e)
615+ public function onBootstrap(MvcEvent $e)
616616 {
617617 // Register a "render" event, at high priority (so it executes prior
618618 // to the view attempting to render)
@@ -621,10 +621,10 @@ class Module
621621 }
622622
623623 /**
624- * @param \Zend\Mvc\ MvcEvent $e The MvcEvent instance
624+ * @param MvcEvent $e The MvcEvent instance
625625 * @return void
626626 */
627- public function registerJsonStrategy($e)
627+ public function registerJsonStrategy(MvcEvent $e)
628628 {
629629 $app = $e->getTarget();
630630 $locator = $app->getServiceManager();
@@ -639,34 +639,64 @@ class Module
639639
640640The above will register the ` JsonStrategy ` with the "render" event, such that it
641641executes prior to the ` PhpRendererStrategy ` , and thus ensure that a JSON payload
642- is created when requested.
642+ is created when the controller returns a ` JsonModel ` .
643+
644+ You could also use the module configuration to add the strategies:
645+ ``` php
646+ namespace Application;
647+
648+ use Zend\ModuleManager\Feature\ConfigProviderInterface;
649+
650+ class Module implements ConfigProviderInterface
651+ {
652+ /**
653+ * Returns configuration to merge with application configuration
654+ *
655+ * @return array
656+ */
657+ public function getConfig()
658+ {
659+ return [
660+ /* ... */
661+ 'view_manager' => [
662+ /* ... */
663+ 'strategies' => [
664+ 'ViewJsonStrategy',
665+ ],
666+ ],
667+ ];
668+ }
669+ }
670+ ```
643671
644672What if you want this to happen only in specific modules, or specific
645673controllers? One way is similar to the last example in the
646674[ previous section on layouts] ( #dealing-with-layouts ) , where we detailed changing
647675the layout for a specific module:
648676
649677``` php
650- namespace Content;
678+ namespace Application;
679+
680+ use Zend\Mvc\MvcEvent;
651681
652682class Module
653683{
654684 /**
655- * @param \Zend\Mvc\ MvcEvent $e The MvcEvent instance
685+ * @param MvcEvent $e The MvcEvent instance
656686 * @return void
657687 */
658- public function onBootstrap($e)
688+ public function onBootstrap(MvcEvent $e)
659689 {
660690 // Register a render event
661691 $app = $e->getParam('application');
662692 $app->getEventManager()->attach('render', [$this, 'registerJsonStrategy'], 100);
663693 }
664694
665695 /**
666- * @param \Zend\Mvc\ MvcEvent $e The MvcEvent instance
696+ * @param MvcEvent $e The MvcEvent instance
667697 * @return void
668698 */
669- public function registerJsonStrategy($e)
699+ public function registerJsonStrategy(MvcEvent $e)
670700 {
671701 $matches = $e->getRouteMatch();
672702 $controller = $matches->getParam('controller');
@@ -694,124 +724,51 @@ class Module
694724While the above examples detail using the ` JsonStrategy ` , the same could be done
695725for the ` FeedStrategy ` .
696726
697- What if you want to use a custom renderer? Or if your app might allow a
698- combination of JSON, Atom feeds, and HTML? At this point, you'll need to create
699- your own custom strategies. Below is an example that appropriately loops through
700- the HTTP ` Accept ` header, and selects the appropriate Renderer based on what is
701- matched first.
702-
727+ If you successfully registered the Strategy you need to use the appropriate ` ViewModel ` :
703728``` php
704- namespace Content\View ;
729+ namespace Application ;
705730
706- use Zend\EventManager\EventManagerInterface;
707- use Zend\EventManager\ListenerAggregateInterface;
708- use Zend\EventManager\ListenerAggregateTrait;
709- use Zend\Feed\Writer\Feed;
710- use Zend\View\Renderer\FeedRenderer;
711- use Zend\View\Renderer\JsonRenderer;
712- use Zend\View\Renderer\PhpRenderer;
731+ use Zend\Mvc\Controller\AbstractActionController;
732+ use Zend\View\Model\ViewModel;
733+ use Zend\View\Model\JsonModel;
734+ use Zend\View\Model\FeedModel;
713735
714- class AcceptStrategy implements ListenerAggregateInterface
736+ class MyController extends AbstractActionController
715737{
716- use ListenerAggregateTrait;
717-
718- protected $feedRenderer;
719- protected $jsonRenderer;
720- protected $phpRenderer;
721-
722- public function __construct(
723- PhpRenderer $phpRenderer,
724- JsonRenderer $jsonRenderer,
725- FeedRenderer $feedRenderer
726- ) {
727- $this->phpRenderer = $phpRenderer;
728- $this->jsonRenderer = $jsonRenderer;
729- $this->feedRenderer = $feedRenderer;
730- }
731-
732- public function attach(EventManagerInterface $events, $priority = 1)
738+ /**
739+ * Lists the items as HTML
740+ */
741+ public function listAction()
733742 {
734- $this->listeners[] = $events->attach('renderer', [$this, 'selectRenderer'], $priority);
735- $this->listeners[] = $events->attach('response', [$this, 'injectResponse'], $priority);
743+ $items = /* ... get items ... */;
744+ $viewModel = new ViewModel();
745+ $viewModel->setVariable('items', $items);
746+ return $viewModel;
736747 }
737-
748+
738749 /**
739- * @param \Zend\Mvc\MvcEvent $e The MvcEvent instance
740- * @return \Zend\View\Renderer\RendererInterface
750+ * Lists the items as JSON
741751 */
742- public function selectRenderer($e )
752+ public function listJsonAction( )
743753 {
744- $request = $e->getRequest();
745- $headers = $request->getHeaders();
746-
747- // No Accept header? return PhpRenderer
748- if (!$headers->has('accept')) {
749- return $this->phpRenderer;
750- }
751-
752- $accept = $headers->get('accept');
753- foreach ($accept->getPrioritized() as $mediaType) {
754- if (0 === strpos($mediaType, 'application/json')) {
755- return $this->jsonRenderer;
756- }
757-
758- if (0 === strpos($mediaType, 'application/rss+xml')) {
759- $this->feedRenderer->setFeedType('rss');
760- return $this->feedRenderer;
761- }
762-
763- if (0 === strpos($mediaType, 'application/atom+xml')) {
764- $this->feedRenderer->setFeedType('atom');
765- return $this->feedRenderer;
766- }
767- }
768-
769- // Nothing matched; return PhpRenderer. Technically, we should probably
770- // return an HTTP 415 Unsupported response.
771- return $this->phpRenderer;
754+ $items = /* ... get items ... */;
755+ $viewModel = new JsonModel();
756+ $viewModel->setVariable('items', $items);
757+ return $viewModel;
772758 }
773-
759+
774760 /**
775- * @param \Zend\Mvc\MvcEvent $e The MvcEvent instance
776- * @return void
761+ * Lists the items as a Feed
777762 */
778- public function injectResponse($e )
763+ public function listFeedAction( )
779764 {
780- $renderer = $e->getRenderer();
781- $response = $e->getResponse();
782- $result = $e->getResult();
783-
784- if ($renderer === $this->jsonRenderer) {
785- // JSON Renderer; set content-type header
786- $headers = $response->getHeaders();
787- $headers->addHeaderLine('content-type', 'application/json');
788- $response->setContent($result);
789- return
790- }
791-
792- if ($renderer === $this->feedRenderer) {
793- // Feed Renderer; set content-type header, and export the feed if
794- // necessary
795- $feedType = $this->feedRenderer->getFeedType();
796- $headers = $response->getHeaders();
797- $mediatype = 'application/'
798- . (('rss' == $feedType) ? 'rss' : 'atom')
799- . '+xml';
800- $headers->addHeaderLine('content-type', $mediatype);
801-
802- // If the $result is a feed, export it
803- if ($result instanceof Feed) {
804- $result = $result->export($feedType);
805- }
806-
807- $response->setContent($result);
808- return;
809- }
765+ $items = /* ... get items ... */;
766+ $viewModel = new FeedModel();
767+ $viewModel->setVariable('items', $items);
768+ return $viewModel;
810769 }
811770}
812771```
813772
814- This strategy would be registered just as we demonstrated registering the
815- ` JsonStrategy ` earlier. You would also need to define service manager
816- configuration to ensure the various renderers are injected when you retrieve the
817- strategy from the application's locator instance.
773+ Or you could switch the ` ViewModel ` dynamically based on the "Accept" HTTP Header with the
774+ [ Zend-Mvc-Plugin AcceptableViewModelSelector] ( http://zendframework.github.io/zend-mvc/plugins/#acceptableviewmodelselector-plugin ) .
0 commit comments