Building ZF3 composed pages using Nesting View Models and Forward Controller Plugin
Posted on August 23, 2017
| 5 minutes
| 1012 words
| Valerio Galano
Normally in ZF3 MVC projects, each controller action matches one view and use it to render its output.
Occasionally, we may want to build your ZF3 pages by dispatching various controllers from within the matched controller and merging outputs into a unique final view. In this way we can aggregate one or more views to create complex pages like report summaries or widget dashboards.
In this post, we will see how to write few lines of code to include output of an arbitrary action into action matched from route.
So, we have one or more actions that perfectly work standalone as final pages, are fully functional and are rendered inside their standard layout. For example, we could have an Example action that shows some content like following:
As you can see, it is a complete page with header, footer, etc.
Now, we decide to include this example action into our main page: most probably we want something that properly integrates into main page flow. The result of this operation should appear something like following image, where most of the page is generated by matched controller (indexAction of IndexController), while Example action section is a view resulting from an internally dispatched action:
In this way, we will point to a main page and its controller will have to invoke Example action (or every action we feel necessary), will have to grab its output and finally will have to include this output into an arbitrary point of the page.
As usual, let’s assume we just have a working Skeleton ZF3 Application. By connecting to index route (http://:/), we will see:
The first thing we have to do is to create an action to include into main page. We will implement exactly Example action shown in Fig.1. So, let’s add following method into IndexController:
<divclass="jumbotron"><h1><spanclass="zf-green">Example</span> action</h1><p> This action will be included as child into index action
to show <spanclass="zf-green">addChild()</span> method usage.
</p><p><aclass="btn btn-success btn-lg"href="https://daredevel.com"target="_blank">Give a look to Daredevel blog »</a></p></div>
At this point, we can browse to http://:/application/to-include and see same result shown in Fig.1
We will use indexAction into IndexController as main page, so we have to implement some code to invoke toIncludeAction (our Example action) and include its output, as shown in next snippet.
At line 7, we internally execute toIncludeAction by invoking dispatch() method of forward() plugin and passing it a controller identifier and an array containing a list of parameters (in our case, only action name).
At line 9, resulting output of dispatch(), stored into $dispatchOutput variable, is passed to addChild() method of ViewModel object. Second argument represent name assigned to children.
At this point, in view template, a variable correspondent to children name will be available to be rendered. We simply have to change it to echo $child1 variable as shown in line 15 of next snippet.
<divclass="jumbotron"><h1>Welcome to <spanclass="zf-green">Zend Framework</span></h1><p> Congratulations! You have successfully installed the
<ahref="https://github.com/zendframework/ZendSkeletonApplication"target="_blank">ZF Skeleton Application</a>.
You are currently running Zend Framework version <?= \Application\Module::VERSION ?>.
This skeleton can serve as a simple starting point for you to begin
building your application on ZF.
</p><p><aclass="btn btn-success btn-lg"href="https://github.com/zendframework/zendframework"target="_blank">Fork Zend Framework on GitHub »</a></p></div><?= $child1 ?><divclass="row"><divclass="col-md-4"><divclass="panel panel-default"><divclass="panel-heading"><h3class="panel-title">Follow Development</h3></div><divclass="panel-body"><p> Zend Framework is under active development. If you are
interested in following the development of ZF, you can check
<ahref="http://framework.zend.com/blog/">ZF dev blog</a>,
and <ahref="https://github.com/issues?utf8=%E2%9C%93&q=is:issue+org:zendframework">ZF issue tracker</a> (link requires a GitHub account). This is a great resource
for staying up to date with the latest developments!
</p><p><aclass="btn btn-success pull-right"href="http://framework.zend.com/"target="_blank">ZF Development Portal »</a></p></div></div></div><divclass="col-md-4"><divclass="panel panel-default"><divclass="panel-heading"><h3class="panel-title">Discover Modules</h3></div><divclass="panel-body"><p> The community is working on developing a community site to
serve as a repository and gallery for ZF modules. The
project is available <ahref="https://github.com/zendframework/modules.zendframework.com">on GitHub</a>.
The site is currently live and currently contains a list of
some of the modules already available for ZF.
</p><p><aclass="btn btn-success pull-right"href="http://modules.zendframework.com/"target="_blank">Explore ZF Modules »</a></p></div></div></div><divclass="col-md-4"><divclass="panel panel-default"><divclass="panel-heading"><h3class="panel-title">Help & Support</h3></div><divclass="panel-body"><p> If you need any help or support while developing with ZF,
you may reach us via IRC: <ahref="irc://irc.freenode.net/zftalk">#zftalk on Freenode</a>.
We'd love to hear any questions or feedback you may have
regarding this release. Alternatively, you may subscribe
and post questions to the <ahref="http://framework.zend.com/archives/">mailing lists</a>.
</p><p><aclass="btn btn-success pull-right"href="http://webchat.freenode.net?channels=zftalk"target="_blank">Ping us on IRC »</a></p></div></div></div></div>
Result of this rendering (still available at http://:/) will be the same as in Fig.2.