@@ -534,24 +534,26 @@ priority. Typically, you will register this during the bootstrap event.
534
534
``` php
535
535
namespace Content;
536
536
537
+ use Zend\Mvc\MvcEvent;
538
+
537
539
class Module
538
540
{
539
541
/**
540
- * @param \Zend\Mvc\ MvcEvent $e The MvcEvent instance
542
+ * @param MvcEvent $e The MvcEvent instance
541
543
* @return void
542
544
*/
543
- public function onBootstrap($e)
545
+ public function onBootstrap(MvcEvent $e)
544
546
{
545
547
// Register a dispatch event
546
548
$app = $e->getParam('application');
547
549
$app->getEventManager()->attach('dispatch', [$this, 'setLayout']);
548
550
}
549
551
550
552
/**
551
- * @param \Zend\Mvc\ MvcEvent $e The MvcEvent instance
553
+ * @param MvcEvent $e The MvcEvent instance
552
554
* @return void
553
555
*/
554
- public function setLayout($e)
556
+ public function setLayout(MvcEvent $e)
555
557
{
556
558
$matches = $e->getRouteMatch();
557
559
$controller = $matches->getParam('controller');
@@ -583,16 +585,12 @@ within your application.
583
585
- ` Zend\View\Strategy\PhpRendererStrategy ` . This strategy is a "catch-all" in
584
586
that it will always return the ` Zend\View\Renderer\PhpRenderer ` and populate
585
587
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
589
589
` Zend\View\Renderer\JsonRenderer ` , and populate the Response body with the
590
590
JSON value returned, as well as set a ` Content-Type ` header with a value of
591
591
` 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
596
594
either "rss" or "atom", based on what was matched. Its Response strategy will
597
595
populate the Response body with the generated feed, as well as set a
598
596
` Content-Type ` header with the appropriate value based on feed type.
@@ -606,13 +604,15 @@ register the `JsonStrategy`:
606
604
``` php
607
605
namespace Application;
608
606
607
+ use Zend\Mvc\MvcEvent;
608
+
609
609
class Module
610
610
{
611
611
/**
612
- * @param \Zend\Mvc\ MvcEvent $e The MvcEvent instance
612
+ * @param MvcEvent $e The MvcEvent instance
613
613
* @return void
614
614
*/
615
- public function onBootstrap($e)
615
+ public function onBootstrap(MvcEvent $e)
616
616
{
617
617
// Register a "render" event, at high priority (so it executes prior
618
618
// to the view attempting to render)
@@ -621,10 +621,10 @@ class Module
621
621
}
622
622
623
623
/**
624
- * @param \Zend\Mvc\ MvcEvent $e The MvcEvent instance
624
+ * @param MvcEvent $e The MvcEvent instance
625
625
* @return void
626
626
*/
627
- public function registerJsonStrategy($e)
627
+ public function registerJsonStrategy(MvcEvent $e)
628
628
{
629
629
$app = $e->getTarget();
630
630
$locator = $app->getServiceManager();
@@ -639,34 +639,64 @@ class Module
639
639
640
640
The above will register the ` JsonStrategy ` with the "render" event, such that it
641
641
executes 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
+ ```
643
671
644
672
What if you want this to happen only in specific modules, or specific
645
673
controllers? One way is similar to the last example in the
646
674
[ previous section on layouts] ( #dealing-with-layouts ) , where we detailed changing
647
675
the layout for a specific module:
648
676
649
677
``` php
650
- namespace Content;
678
+ namespace Application;
679
+
680
+ use Zend\Mvc\MvcEvent;
651
681
652
682
class Module
653
683
{
654
684
/**
655
- * @param \Zend\Mvc\ MvcEvent $e The MvcEvent instance
685
+ * @param MvcEvent $e The MvcEvent instance
656
686
* @return void
657
687
*/
658
- public function onBootstrap($e)
688
+ public function onBootstrap(MvcEvent $e)
659
689
{
660
690
// Register a render event
661
691
$app = $e->getParam('application');
662
692
$app->getEventManager()->attach('render', [$this, 'registerJsonStrategy'], 100);
663
693
}
664
694
665
695
/**
666
- * @param \Zend\Mvc\ MvcEvent $e The MvcEvent instance
696
+ * @param MvcEvent $e The MvcEvent instance
667
697
* @return void
668
698
*/
669
- public function registerJsonStrategy($e)
699
+ public function registerJsonStrategy(MvcEvent $e)
670
700
{
671
701
$matches = $e->getRouteMatch();
672
702
$controller = $matches->getParam('controller');
@@ -694,124 +724,51 @@ class Module
694
724
While the above examples detail using the ` JsonStrategy ` , the same could be done
695
725
for the ` FeedStrategy ` .
696
726
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 ` :
703
728
``` php
704
- namespace Content\View ;
729
+ namespace Application ;
705
730
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;
713
735
714
- class AcceptStrategy implements ListenerAggregateInterface
736
+ class MyController extends AbstractActionController
715
737
{
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()
733
742
{
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;
736
747
}
737
-
748
+
738
749
/**
739
- * @param \Zend\Mvc\MvcEvent $e The MvcEvent instance
740
- * @return \Zend\View\Renderer\RendererInterface
750
+ * Lists the items as JSON
741
751
*/
742
- public function selectRenderer($e )
752
+ public function listJsonAction( )
743
753
{
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;
772
758
}
773
-
759
+
774
760
/**
775
- * @param \Zend\Mvc\MvcEvent $e The MvcEvent instance
776
- * @return void
761
+ * Lists the items as a Feed
777
762
*/
778
- public function injectResponse($e )
763
+ public function listFeedAction( )
779
764
{
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;
810
769
}
811
770
}
812
771
```
813
772
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