2. renderResponse()
Select page
display variant
Is a
#type ‘page’
render array?
hook_page_attachments()
hook_page_(top|bottom)()
Example: BlockPageVariant selected.
render()
main content
Yes
No
Build page display
variant
The result of a built page display variant is a #type ‘page’ render array.
hook_page_attachments() operates on #type ‘page’.
The main content must already be rendered, because it might set the
page title.
render()
entire HTML document
Only accepts render arrays of #type ‘page’!
Wrap in #type ‘html’
Example: response for the path /admin.
Renders the 3 parts of the HTML body: page_top, page, page_bottom
(where page corresponds to #type ‘page’ and hence page.html.twig).
Then renders the entire HTML (i.e. the html.html.twig template).
render()
main content
Add InsertCommand
new AjaxResponse()
Get dialog options from
Request
Calculate title if not
provided by main content
Calculate title if not
provided by main content
render()
main content
Add OpenDialogCmd
new AjaxResponse()
The flow for all four formats supported in core in their respect is
displayed next, but the explanations below only apply to the
HtmlController!
If an unsupported format was negotiated, a 406 response is generated.
new HtmlResponse()
5. Calling the Controller
6. The kernel.view Event
7. The kernel.response Event
DialogRenderer ModalRendererHtmlRenderer AjaxRenderer
No
Response
Initialize the corresponding
main content renderer
Is render array?
Yes
Main content
renderer for request
format exists?
Yes
Call ::renderResponse()
Set Response on Event
Generate 406
Response
No
Controller returns either:
No
1. prepare() helper
Calculate title if not
provided by main content
render()
main content
Add OpenModalDialogCmd
new AjaxResponse()
format = ‘ajax’format = ‘modal’
MainContentViewSubscriber
Response
Response
Response
main content renderers
format = ‘html’ format = ‘dialog’
\D\s\C\SystemController::systemAdminMenuBlockPage is called, it
returns a render array with no #type.
MainContentViewSubscriber only handles render arrays!
If it’s anything else (e.g. an object), then it’s up to another VIEW event
subscriber to turn it into a Response.
MainContentViewSubscriber looks at the available main content
renderer services. These are tagged with render.main_content_renderer.
Contributed modules can additional renderers.
Example: GET /admin.
HTTP request
1. The kernel.request event
Determine
route &
controller
HTTP response
Negotiate
format
Request handling and rendering flow
Example: /admin path system.admin route
That route has the following attributes:
_content: '\D\s\C\SystemController::systemAdminMenuBlockPage'
_title: ‘Administration’
Explanation
KernelEvents::REQUEST
2. Resolve the Controller
3. The kernel.controller event
See http://symfony.com/doc/2.7/components/
http_kernel/introduction.html
for more details — this shows the same steps.
4. Getting the Controller Arguments
Yes
index.php
3. Call Response::prepare()
2. Call HttpKernel::handle()
1. Create Request from globals
4. Call Response::send()
5. Call HttpKernel::terminate()
HttpKernel::handle()
Symfony (HttpKernel) Drupal (Controller, MainContentViewSubscriber, main content renderers)Event handling
KernelEvents::CONTROLLER
Some parts are greyed out because they’re of lesser importance:
they do happen, but are not crucial for understanding the flow.
Typically, the format will be html, but it could also be
ajax, dialog, modal, json, hal_json, and more.
See: Symfony’s Request::setFormat().
_controller is set to '\D\s\C\SystemController::systemAdminMenuBlockPage'
KernelEvents::VIEW
SELECT_PAGE_DISPLAY_VARIANT
KernelEvents::TERMINATE
Response
Is Response?
render
array
object with
associated
kernel.view
event
subscriber
Colored overlaid arrows: showing the flow of the
dierent types of Controller return values.
Typical flow
Note that HtmlResponse (as well as AjaxResponse) at this point still
contains attachments: asset libraries, headers … but also placeholders.
Return placeholders
unchanged
SingleFlush (core) BigPipe (contrib)
Transform placeholders to
BigPipe placeholders
placeholder strategies (HTML responses only)
Is HTML response
and has placeholders
attached?
::processPlaceholders()
Set final placeholders on
HtmlResponse
Yes
HtmlRes’PlaceholderStrat’Sub
Placeholder strategies can transform standard Drupal placeholders
(designed for non-deferred rendering) into other placeholders, which
may be replaced with the final markup using any way possible.
For example: BigPipe, ESI …
ChainedPlaceholderStrategy looks at the available placeholder
strategies. These are tagged with placeholder_strategy.
Contributed modules can additional renderers.
BigPipe is a contrib module during 8.0.x, will likely be in 8.1.x core.
See https://www.drupal.org/project/big_pipe
KernelEvents::RESPONSE
No
HtmlRes’AttachmentsProcessor
Render placeholders
Update HTML to load final assets, set
attached headers on response …
Process all other HtmlResponse attachments: asset libraries, HTML
<head> elements, headers …
BigPipe placeholders rendered at the end of::send(), after most is sent.