Skip to content
This repository was archived by the owner on Jan 31, 2020. It is now read-only.

Commit 39f8d3a

Browse files
Clarify Quickstart regarding renderer strategies
1 parent dd718ca commit 39f8d3a

File tree

1 file changed

+54
-107
lines changed

1 file changed

+54
-107
lines changed

doc/book/quick-start.md

Lines changed: 54 additions & 107 deletions
Original file line numberDiff line numberDiff line change
@@ -635,15 +635,40 @@ class Module
635635

636636
The above will register the `JsonStrategy` with the "render" event, such that it
637637
executes prior to the `PhpRendererStrategy`, and thus ensure that a JSON payload
638-
is created when requested.
638+
is created when the controller returns an `JsonModel`.
639+
640+
You could also use the module configuration to add the strategies:
641+
```php
642+
namespace Application;
643+
644+
class Module implements \Zend\ModuleManager\Feature\ConfigProviderInterface
645+
{
646+
/**
647+
* Returns configuration to merge with application configuration
648+
*
649+
* @return array
650+
*/
651+
public function getConfig()
652+
{
653+
return [
654+
// ...
655+
'view_manager' => [
656+
'strategies' => [
657+
'ViewJsonStrategy',
658+
],
659+
],
660+
];
661+
}
662+
}
663+
```
639664

640665
What if you want this to happen only in specific modules, or specific
641666
controllers? One way is similar to the last example in the
642667
[previous section on layouts](#dealing-with-layouts), where we detailed changing
643668
the layout for a specific module:
644669

645670
```php
646-
namespace Content;
671+
namespace Application;
647672

648673
class Module
649674
{
@@ -690,124 +715,46 @@ class Module
690715
While the above examples detail using the `JsonStrategy`, the same could be done
691716
for the `FeedStrategy`.
692717

693-
What if you want to use a custom renderer? Or if your app might allow a
694-
combination of JSON, Atom feeds, and HTML? At this point, you'll need to create
695-
your own custom strategies. Below is an example that appropriately loops through
696-
the HTTP `Accept` header, and selects the appropriate Renderer based on what is
697-
matched first.
698-
718+
If you successfully registered the Strategy you need to use the appropriate `ViewModel`:
699719
```php
700-
namespace Content\View;
701-
702-
use Zend\EventManager\EventManagerInterface;
703-
use Zend\EventManager\ListenerAggregateInterface;
704-
use Zend\EventManager\ListenerAggregateTrait;
705-
use Zend\Feed\Writer\Feed;
706-
use Zend\View\Renderer\FeedRenderer;
707-
use Zend\View\Renderer\JsonRenderer;
708-
use Zend\View\Renderer\PhpRenderer;
720+
namespace Application;
709721

710-
class AcceptStrategy implements ListenerAggregateInterface
722+
class MyController extends \Zend\Mvc\Controller\AbstractActionController
711723
{
712-
use ListenerAggregateTrait;
713-
714-
protected $feedRenderer;
715-
protected $jsonRenderer;
716-
protected $phpRenderer;
717-
718-
public function __construct(
719-
PhpRenderer $phpRenderer,
720-
JsonRenderer $jsonRenderer,
721-
FeedRenderer $feedRenderer
722-
) {
723-
$this->phpRenderer = $phpRenderer;
724-
$this->jsonRenderer = $jsonRenderer;
725-
$this->feedRenderer = $feedRenderer;
726-
}
727-
728-
public function attach(EventManagerInterface $events, $priority = 1)
724+
/**
725+
* Lists the items as HTML
726+
*/
727+
public function listAction()
729728
{
730-
$this->listeners[] = $events->attach('renderer', [$this, 'selectRenderer'], $priority);
731-
$this->listeners[] = $events->attach('response', [$this, 'injectResponse'], $priority);
729+
$items = /* ... get items .. .*/;
730+
$viewModel = new \Zend\View\Model\ViewModel();
731+
$viewModel->setVariable('items', $items);
732+
return $viewModel;
732733
}
733-
734+
734735
/**
735-
* @param \Zend\Mvc\MvcEvent $e The MvcEvent instance
736-
* @return \Zend\View\Renderer\RendererInterface
736+
* Lists the items as JSON
737737
*/
738-
public function selectRenderer($e)
738+
public function listJsonAction()
739739
{
740-
$request = $e->getRequest();
741-
$headers = $request->getHeaders();
742-
743-
// No Accept header? return PhpRenderer
744-
if (!$headers->has('accept')) {
745-
return $this->phpRenderer;
746-
}
747-
748-
$accept = $headers->get('accept');
749-
foreach ($accept->getPrioritized() as $mediaType) {
750-
if (0 === strpos($mediaType, 'application/json')) {
751-
return $this->jsonRenderer;
752-
}
753-
754-
if (0 === strpos($mediaType, 'application/rss+xml')) {
755-
$this->feedRenderer->setFeedType('rss');
756-
return $this->feedRenderer;
757-
}
758-
759-
if (0 === strpos($mediaType, 'application/atom+xml')) {
760-
$this->feedRenderer->setFeedType('atom');
761-
return $this->feedRenderer;
762-
}
763-
}
764-
765-
// Nothing matched; return PhpRenderer. Technically, we should probably
766-
// return an HTTP 415 Unsupported response.
767-
return $this->phpRenderer;
740+
$items = /* ... get items .. .*/;
741+
$viewModel = new \Zend\View\Model\JsonModel();
742+
$viewModel->setVariable('items', $items);
743+
return $viewModel;
768744
}
769-
745+
770746
/**
771-
* @param \Zend\Mvc\MvcEvent $e The MvcEvent instance
772-
* @return void
747+
* Lists the items as a Feed
773748
*/
774-
public function injectResponse($e)
749+
public function listFeedAction()
775750
{
776-
$renderer = $e->getRenderer();
777-
$response = $e->getResponse();
778-
$result = $e->getResult();
779-
780-
if ($renderer === $this->jsonRenderer) {
781-
// JSON Renderer; set content-type header
782-
$headers = $response->getHeaders();
783-
$headers->addHeaderLine('content-type', 'application/json');
784-
$response->setContent($result);
785-
return
786-
}
787-
788-
if ($renderer === $this->feedRenderer) {
789-
// Feed Renderer; set content-type header, and export the feed if
790-
// necessary
791-
$feedType = $this->feedRenderer->getFeedType();
792-
$headers = $response->getHeaders();
793-
$mediatype = 'application/'
794-
. (('rss' == $feedType) ? 'rss' : 'atom')
795-
. '+xml';
796-
$headers->addHeaderLine('content-type', $mediatype);
797-
798-
// If the $result is a feed, export it
799-
if ($result instanceof Feed) {
800-
$result = $result->export($feedType);
801-
}
802-
803-
$response->setContent($result);
804-
return;
805-
}
751+
$items = /* ... get items .. .*/;
752+
$viewModel = new \Zend\View\Model\FeedModel();
753+
$viewModel->setVariable('items', $items);
754+
return $viewModel;
806755
}
807756
}
808757
```
809758

810-
This strategy would be registered just as we demonstrated registering the
811-
`JsonStrategy` earlier. You would also need to define service manager
812-
configuration to ensure the various renderers are injected when you retrieve the
813-
strategy from the application's locator instance.
759+
Or you could switch the `ViewModel` dynamically based on the "Accept" HTTP Header:
760+
[Zend-Mvc: AcceptableViewModelSelector Plugin](http://zendframework.github.io/zend-mvc/plugins/#acceptableviewmodelselector-plugin).

0 commit comments

Comments
 (0)