The render pipeline

In Chapter 1, Developing for Drupal 8, when we outlined a high-level example of how Drupal 8 handles a user request in order to turn it into a response, we touched on the notion of a render pipeline. So let's see what this is about, as there are essentially two render pipelines to speak of: the Symfony render pipeline and the Drupal one.

As you know, Drupal 8 uses many Symfony components, one of which being the HTTPKernel component (http://symfony.com/doc/current/components/http_kernel.html). Its main role is to turn a user request (built from PHP super globals into a Request object) into a standardized response object that gets sent back to the user. These objects are defined in the Symfony HTTP Foundation component (http://symfony.com/components/HttpFoundation). To assist in this process, it uses the Event Dispatcher component to dispatch events meant to handle the workload on multiple layers. As we saw, this is what happens in Drupal 8 as well.

Controllers in Drupal 8 can return one of two things—either a Response object directly or a render array. If they return the first, the job is almost done, as the Symfony render pipeline knows exactly what to do with that (assuming the response is correct). However, if they return a render array, the Drupal render pipeline kicks in at a lower level to try to turn that into a Response. We always need a Response.

The kernel.view event is triggered in order to determine who can take care of this render array. Drupal 8 comes with the MainContentViewSubscriber which listens to this event and checks the request format and whether the controller has returned a render array. Based on the former, it instantiates a MainContentRendererInterface object (which, by default—and most of the time—will be the HTML-based HtmlRenderer) and asks it to turn the render array into a Response. Then, it sets the Response onto the event so that the Symfony render pipeline can continue on its merry way.

In addition to the HTML renderer, Drupal 8 comes with a few others that need to handle different types of requests:

  • The AjaxRenderer handles Ajax requests and integrates with the Ajax framework. We'll see examples of Ajax-powered functionalities later in the book.
  • The DialogRenderer handles requests meant to open up a dialog on the screen.
  • The ModalRenderer handles requests meant to open up a modal on the screen.

Returning to the HTML renderer, let's see what it does to turn our render arrays into actual relevant HTML on a Response object. Without going into too much detail, here is the high-level of what it does:

  • Its first goal is to build a render array that has the #type => 'page' as a property because this is the render element responsible for the entire page. Meaning that if the Controller returned it, it doesn't have to do much. However, usually controllers don't include that so it dispatches an event to determine who can build this render array.
  • By default, the SimplePageVariant plugin is used for building up the page array, but with the Block module enabled, the BlockPageVariant plugin is used, taking things even further down some levels in the render pipeline. The main content area gets wrapped with blocks in the sidebar, header, footer, and so on.
  • Once it has the page render array, it wraps it into yet another render element which is the #type => 'html' (responsible for things such as the <head> elements).
  • Once it has the main render array of the entire page, it uses the Renderer service to traverse it and do the actual rendering at each level (and there can be many). It does so by translating render elements (#type), theme hooks (#theme), simply marked-up text bits (#markup), or plain text bits (#plain_text) into their respective HTML representations.

So, as you see, the render pipeline starts at Symfony level, goes down into Drupal territory when it encounters render arrays, but continues going down to build each component found on a page around the main content returned by the Controller. Then, it comes back up those levels, all the way until a great render array is created and can be turned into HTML. Also, as it goes back up, various metadata can bubble up to the main render array.

I purposefully left out caching from this equation, which although very important, we will cover in a later chapter. However, suffice it to say, cache metadata is one such example that bubbles up from the lower levels all the way to the top and is gathered to determine page-level caching. But more on that later.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset