Drupal 8 Render Pipeline is the sequence of steps through which Drupal 8 generates a response to an HTTP request. ie, what is going on under the hood of Drupal 8 in the process of generating an HTML output. This presentation is a walk-through of the steps followed by Drupal 8 between getting a request and sending back the corresponding response, in that order, with specific details and examples mentioned when deemed necessary. It will provide an overview of the whole process, with emphasis on the Event Mechanism and the Routing Process.
SQL Database Design For Developers at php[tek] 2024
Learn Drupal 8 Render Pipeline
1. The Drupal 8 Render
Pipeline
Anish M. M.
Adrian McDonald Tariang
Summer Interns
Date: 2017-06-08
From Request to Response
2. Introduction
In order to generate a response for a request, Drupal
performs a sequence of steps, called the Drupal
Render Pipeline. In the following slides, we will go
through these steps one by one.
5. 1.The Front Controller[index.php]
This is the entry point of execution where Drupal
creates the Request Object from the HTTP request,
processes it and and returns the response back to
the browser.
6. 1.The Front Controller[index.php]
Key Components
HttpFoundation
Component of Symfony that creates an object-
oriented layer from the superglobals of the PHP
request.
HttpKernel
Another Symfony component used to provide a
structured pipeline to render a response for the
Drupal System.
7. Loads all the dependencies using the autoload.php
file.
Instantiates the DrupalKernel class.
Creates a $request object of Symfony’s Request
class from the component HttpFoundation.
Calls the DrupalKernel::handle() method and passes
the $request object as argument.
1.The Front Controller[index.php]
Steps Followed
8. DrupalKernel::handle()
This handle() method :
Calls DrupalKernel::bootEnvironment() -
which sets the PHP environment variables that
need to be set to ensure security.
Calls DrupalKernel::initializeSettings() which
locates site path and initializes the Drupal
settings.
Calls HttpKernel::handle() method which is a
part of the Symfony component HttpKernel.
10. Events, Event Listeners.
An event is like a notice on a bulletin board. Event
Listeners are the people who wait (‘listen’) for a
notice. Listeners listen for a particular kind of event,
say, for a kernel.exception event. Dispatching an
event is like putting it on the notice board.
When the event they are listening to is dispatched,
they check whether they can perform the required
action. If so, they respond to the dispatched event
using the setResponse() method and stops the
propagation of the event.
11. REQUEST event
During this event, exceptions could occur which
could run its own controller (see kernel.exception)
and send back a response.
The first event in the
kernel.handle() method.
Subscribers to the request
event perform task such as:
1. Format negotiation of the
response data i.e. html, json.
2. Controller selection to
handle the request.
13. Routing
Drupal’s routing system is responsible for
providing an appropriate controller to a requested
path.
It is based on the Symfony component Routing,
which uses routes.yml files present in the module
directory to map the routes to controllers.
The route file contains data such as the format the
response is to be produced, the controller to be
used, security requirements and other supporting
data.
14. RouteBuilder::rebuild()
building the route information
This workflow represents how
the routes are loaded from
the modules’ routing.yml
files and other sources into
the Drupal database.
15. Routing
The controller performs the business logic for the
application.
The routing.yml file contains one of these
“controller” types:
_content
_controller
_form
_entity[_form | _view | _list]
Which specify how the output is generated. This
data is then set into the request attributes.
16. Routing Example
In this example, during the
request event, if the URL request is
as specified in `path`, the
controller defined at `_form` is to
be used to provide the given menu
form.
This YAML file also specifies that
the client needs to be logged in to
access the page.
colorbox.routing.yml
file to the Colorbox
module.
An example request:
17. Controller Resolution
Now, the handle()
method is required to
select the exact
Controller using the
request attributes that
was set by the routing
Component.
This is performed using the getController() method of
a class implementing the ControllerResolverInterface
of the Symfony component HttpKernel.
18. Resolving Controller
Parameters
The given section is used to
provide an array of
arguments for the Controller
to operate.
This is performed by the
Drupal System and may even
include the entire request
object if required.
19. CONTROLLER event
During this event,
subscribers or listeners
perform initialization or
testing before the controller
is allowed to be executed.
The Listeners also have the
privilege to change the
Controller to be used if
required.
20. Resolving Controller
Parameters
The given section is used to
provide an array of
arguments for the Controller
to operate.
This is performed by the
Drupal System and may even
include the entire request
object if required.
21. Calling the controller
The selected controller is
now called by handle() with
its arguments. The Drupal
controllers return either:
The Response Object
Render Array
or other objects.
If the controller returns a response object, it moves
directly to the response event without going
through the view event.
Render arrays and other objects are converted into
Response objects through the listeners of the view
event, which is dispatched after controller
completion.
22. VIEW event
Listeners to this event, also
called View Subscribers,
convert render arrays and
objects into Response objects
by delegating the task to
specified renderers to a given
format. (html, json, xml).
Listeners, can also use
templates to provide the
response object in the
specified format.
24. Render Arrays
A render array is a classic Drupal structured array
that provides data (probably nested) along with
hints as to how it should be rendered (properties
like #type).
Modules have the capability of defining “elements”,
which are essentially prepackaged default render
arrays. They use hook_element_info() to do this.
When #type is declared for a render array, the
default properties of the element type named are
loaded through the use of hook_element_info().
25. Render Arrays
They allow the modules to treat the content as
data for as long as possible in the page
generation process.
26. MainContentViewSubscriber
This view subscriber converts Render Arrays into
Response objects. It checks whether a maincontent
renderer service for the requested response format
exists. If it does, it is initialized. Else, a 406 (Not
Acceptable) response is generated.
Other objects may be converted by corresponding
view subscribers on seeing the kernel.view event,
either directly into Response objects, or into Render
Arrays. In the latter case, the
MainContentViewSubscriber converts it into a
Response object.
27. RESPONSE event
During the event, final
modifications are performed
over the Response object
such as inserting javascripts
or cookies.
Placeholders in the Response
object are replaced through
Placeholder Strategies such
as BigPipe and SingleFlush.
It is after this event that the
Response is sent back to the
Front controller through the
handle() method.
28. SingleFlush vs BigPipe
Caching
Cache, in computing, is a component that stores
frequently used data so that future requests for that
data can be served faster.
Frequently used / common data can be cached and
loaded faster, while dynamic / personalized data is
generated.
In Drupal 8, Caching is performed through cache-
tags, cache-contexts and max-age.
29. SingleFlush vs BigPipe
By default, responses to requests are delivered in a
SingleFlush method.
The server generates all the content to be
displayed and then dumps it to the browser screen.
So, entire pages are cache-able, but not as parts of
one.
Here, the perceived time for loading the web page
is more and user has to sometimes stare at a white
screen till the full page loads.
30. SingleFlush vs BigPipe
An alternative to SingleFlush, is the BigPipe
method.
Here, the pages are sent in a way which allows the
browser to display them much faster.
Caching of parts of pages is possible.
So, the cached parts are displayed and then the
dynamic parts are added as and when received.
The total time for loading the page may be the
same, but the perceived time is lesser.
Also, the user is provided with some workable
content before the whole page is loaded.
31. TERMINATE event
This event is triggered after
the Response object is
already sent back to the
client.
Used to perform slower tasks
such as system logging and
sending emails which now
would not increase response
time.
This is made possible by the
TerminableInterface provided
by the Symfony component
HttpKernel.
32. EXCEPTION event
Triggered to handle
exceptions and tailor
appropriate responses to the
client.
For example, if the client does
not have sufficient
permissions or if the
requested data does not
exist.
An exception is also thrown
when no listeners to events
such as request and view are
triggered.
33. References
Site Point: From Request to Response
Drupal Render API Documentation
Drupal 8 Render Pipeline talk
Symfony 2 HttpKernel Component
Drupal API Documentation
Drupal Cache API Documentation
Credits
Wim Leers, author to material such as the
render pipeline diagram and the DrupalCon talk,
which have been used extensively in this
presentation.
Images taken from symfony.com/docs