This course is archived!
This tutorial is built using Drupal 8.0. The fundamental concepts of Drupal 8 - like services & routing - are still valid, but newer versions of Drupal *do* have major differences.
The Render Array... and Event Listeners
Keep on Learning!
If you liked what you've learned so far, dive in! Subscribe to get access to this tutorial plus video, code and script downloads.
With a Subscription, click any sentence in the script to jump to that part of the video!
Login SubscribeWhile we're on the topic, the render array works via a listener. When I told you earlier that a controller always returns a Response object, that was a bloody lie! Return an array instead, and set #title
to $roar
:
// ... lines 1 - 10 | |
class RoarController extends ControllerBase | |
{ | |
// ... lines 13 - 35 | |
public function roar($count) | |
{ | |
// ... lines 38 - 41 | |
return [ | |
'#title' => $roar | |
]; | |
} | |
} |
Head to /the/dino/says/50
in the browser. As expected, here is a fully-themed page. And I say "as expected", but is it expected? One of the cardinal rules of a Symfony controller is that it must return a Symfony Response
object. But this is most certainly not a Response
: it's an array.
In truth, there's an exception to that rule: if you don't return an array, Drupal, well, Symfony, dispatches an event called kernel.view
. There it is! It runs after the controller and has one job: try to convert the controller return value into a Response.
Check out this MainContentViewSubscriber
. Surprise! This is the listener responsible for handling the render array, via its onViewRenderArray()
method. I love how the magic of Drupal gets more transparency via events.
So if you want to see how the render array system works, you just need to open that class. In fact, I'll give you a little preview. Find core.services.yml
again. Inside, there's a section that includes some services, main_content_renderer_html
and main_content_renderer_ajax
:
// ... lines 1 - 983 | |
main_content_renderer.html: | |
class: Drupal\Core\Render\MainContent\HtmlRenderer | |
arguments: ['@title_resolver', '@plugin.manager.display_variant', '@event_dispatcher', '@module_handler', '@renderer', '@render_cache', '%renderer.config%'] | |
tags: | |
- { name: render.main_content_renderer, format: html } | |
main_content_renderer.ajax: | |
class: Drupal\Core\Render\MainContent\AjaxRenderer | |
arguments: ['@element_info'] | |
tags: | |
- { name: render.main_content_renderer, format: drupal_ajax } | |
- { name: render.main_content_renderer, format: iframeupload } | |
// ... lines 995 - 1576 |
If you looked into MainContentViewSubscriber
far enough, you'd see it uses these classes behind the scenes to figure out how to render the page. What's really interesting - at least for me, admittedly, I love this stuff - is this tag: main_content_renderer
with format: html
. The AJAX service also has one, with format: drupal_ajax
.
I'm getting really, really advanced on you guys, but this is the power of the new way things are done in Drupal. If you wanted to have your own "main_content_renderer" for some other format, like JSON, all you need to do is create a service, and give it this tag with the new format. You may never need to do this, but as you dig, Drupal's layers start to open up.
That's if for now. If there's something that's confusing you or mysterious in D8, let me know and we'll dive in together. Ok, see ya guys next time!