SlideShare a Scribd company logo
1 of 54
Download to read offline
lussoluca
How Drupal builds your pages
D10 edition
Luca Lusso
Drupal / PHP / Go developer @ SparkFabrik
Drupal contributor (WebProfiler, Monolog,
Symfony Messenger, …) and speaker
Drupal.org: www.drupal.org/u/lussoluca
Twitter: www.twitter.com/lussoluca
LinkedIn: www.linkedin.com/in/lussoluca
drupal.slack.com: lussoluca
@lussoluca
We are a tech company of engineers,
developers and designers, capable of
accompanying customers step by step
in the CLOUD NATIVE era,
with an agile and pragmatic approach.
We are committed to OPEN SOURCE
and we embrace its philosophy
in our internal practices.
TECHNOLOGY,
STRATEGY AND METHOD
4
5
All Drupal pages are built in the same way:
A Request is received and a Response is
produced
In this session we’ll see how Drupal turns an
HTTP Request into an HTML Response
6
GET /en/forecast/lille HTTP/2 <!DOCTYPE html
>
<html lang="en" dir="ltr">
<head>
<meta charset="utf-8" />
<meta
name
="Generator"
content
="Drupal 10 (https://www.drupal.org)
" />
...
</html>
7
➔ Custom module (machine name: weather)
➔ Custom page
➔ Not build using the Node system (even if the flow is
the same, the Node system is too complex to be
analyzed in a short time)
➔ There is a custom Entity called “City” used to store a
description and some geographic coordinates
➔ On this page we retrieve the city, call an external
service to get weather forecasts and build the
output
➔ Demo module repository:
https://github.com/lussoluca/weather
/en/forecast/lille
8
9
In the context of computer programming, instrumentation
refers to the measure of a product's performance, in order
to diagnose errors and to write trace information.
➔ Profiling
➔ Tracing
➔ Logging
Instrumentation
10
➔ New settings page available from Drupal 10.1
➔ /admin/config/development/settings
➔ Useful during inspection and development
➔
Disable optimizations
Profiling: WebProfiler
11
WebProfiler adds a toolbar at the bottom of every page and
shows you all sorts of stats, such as the amount of
database queries loaded on the page, which services are
used, and much more.
Depends on:
➔ Devel
➔ Tracer
https://www.drupal.org/project/webprofiler/
12
index.php
13
➔ Require the Composer
autoload file
➔ Create a new Kernel
➔ Handle the request to build a
response
➔ Return the response
➔ Terminate the Kernel
➔ Front controller pattern
use DrupalCoreDrupalKernel;
use SymfonyComponentHttpFoundationRequest;
$autoloader = require_once 'autoload.php';
$kernel = new DrupalKernel('prod', $autoloader);
$request = Request::createFromGlobals();
$response = $kernel->handle($request);
$response->send();
$kernel->terminate($request, $response);
➔ https://stackphp.com/
➔ DrupalKernel is decorated by a set of middlewares
Stack middleware
14
DrupalKernel
➔ Ordered by priority desc on request and by priority
asc on response
Stack middleware
15
16
After passing through all the middlewares, the Request is
handled by a router that finds the code responsible for
converting the Request into a Response.
In this case the Request is managed by a Controller:
ForecastController.
Request collector
17
Routing and controllers
➔ weather.routing.yml
➔ Route name: weather.forecast
➔ {city} placeholder
➔ _controller
➔ _title
➔ Requirements
➔ Param converters
Routing
weather.forecast:
path: '/forecast/{city}'
defaults:
_controller: 'DrupalweatherControllerForecastController::page'
_title_callback: 'DrupalweatherControllerForecastController::title'
requirements:
_permission: 'access content'
options:
parameters:
city:
type: 'weather:city'
18
Routes collector
19
Routes collector
Param converters
weather.forecast:
path: '/forecast/{city}'
defaults:
_controller: 'DrupalweatherControllerForecastController::page'
_title_callback: 'DrupalweatherControllerForecastController::title'
requirements:
_permission: 'access content'
options:
parameters:
city:
type: 'weather:city'
The Node module uses the same
technique to upcast the nid to full
Node objects.
20
Param converters
public function applies( $definition , $name, Route $route):bool {
if (!empty($definition ['type']) && $definition ['type'] === 'weather:city' ) {
return TRUE;
}
return FALSE;
}
public function convert( $value, $definition , $name, array $defaults ):?CityInterface
{
$cities = $this
-> entityTypeManager
->getStorage( 'city')
->loadByProperties([ 'label' => $value]);
if (count( $cities) == 0) {
return NULL;
}
return reset($cities);
}
➔ applies is used to check if this
param converter should be
used for this route
➔ convert will takes the value
from the url (lille) and convert
it to something more
structured (typically an
object). If convert return
NULL, Drupal will return a 404
error page.
21
Services collector
22
Services collector
Services collector
23
Database collector
Title callback
weather.forecast:
path: '/forecast/{city}'
defaults:
_controller: 'DrupalweatherControllerForecastController::page'
_title_callback: 'DrupalweatherControllerForecastController::title'
requirements:
_permission: 'access content'
options:
parameters:
city:
type: 'weather:city'
Method used by Drupal to retrieve
the title of a route
24
Title callback
public function title(CityInterface $city): string {
return $this->t('Weather forecast for @city', [
'@city' => $city->label(),
]);
}
➔ Returns a string
➔ Can use the parameters
(upcasted) from the URL
25
Controller callback
weather.forecast:
path: '/forecast/{city}'
defaults:
_controller: 'DrupalweatherControllerForecastController::page'
_title_callback: 'DrupalweatherControllerForecastController::title'
requirements:
_permission: 'access content'
options:
parameters:
city:
type: 'weather:city'
Method used by Drupal to retrieve
the main content of a route
26
Controller callback
public function page(CityInterface $city): array {
$forecast = $this->weatherClient ->getForecastData( $city->label());
$build['content' ] = [
'#theme' => 'weather_forecast' ,
'#forecast' => $forecast ,
'#units' => $this->config( 'weather.settings' )->get('units'),
'#description' => $city->getDescription(),
'#coordinates' => $city->getCoordinates(),
'#cache' => [
'max-age' => 10800, // 3 hours.
'tags' => [
'forecast:' . strtolower( $city->label()),
],
'contexts' => [
'url',
],
],
];
return $build;
}
27
Services
public function page(CityInterface $city): array {
$forecast = $this->weatherClient ->getForecastData( $city->label());
$build['content'] = [
'#theme' => 'weather_forecast',
'#forecast' => $forecast,
'#units' => $this->config('weather.settings')->get('units'),
'#description' => $city->getDescription(),
'#coordinates' => $city->getCoordinates(),
'#cache' => [
'max-age' => 10800, // 3 hours.
'tags' => [
'forecast:' . strtolower($city->label()),
],
'contexts' => [
'url',
],
],
];
return $build;
}
➔ PHP classes to perform some
useful task
◆ Sending email
◆ Authenticate users
◆ Call external services
◆ …
➔ Drupal core has more than 500
services
➔ We’ve seen a couple of them
already:
◆ Middlewares are
services
◆ Param converters are
services
28
Services collector
29
Services collector
30
Http collector
31
➔ Well done! We found that the ForecastController has
the piece of code that render this route!
➔ But wait…
➔ ForecastController returns the title of the page and a
simple array…
◆ Where all this markup comes from?
◆ Where are loaded and placed the blocks (like
the header and the footer)?
◆ How CSS and JavaScript assets are managed?
Entering the Drupal render pipeline
/en/forecast/lille
32
Render pipeline
Render arrays
public function page(CityInterface $city): array {
$forecast = $this->weatherClient->getForecastData($city->label());
$build['content' ] = [
'#theme' => 'weather_forecast' ,
'#forecast' => $forecast ,
'#units' => $this->config( 'weather.settings' )->get('units'),
'#description' => $city->getDescription(),
'#coordinates' => $city->getCoordinates(),
'#cache' => [
'max-age' => 10800, // 3 hours.
'tags' => [
'forecast:' . strtolower( $city->label()),
],
'contexts' => [
'url',
],
],
];
return $build;
}
➔ weather_forecast: theme hook
➔ Keys that starts with ‘#’ are the
properties
➔ Keys that doesn’t start with ‘#’
are nested render arrays
➔ Must declare ‘#cache’
information
33
➔ Where I can find the whole list of
available theme hooks?
➔ Which arguments are available?
Theme registry
"weather_details" => array:6 [ ▶]
"weather_forecast" => array:6 [▼
"variables" => array:4 [▼
"forecast" => []
"units" => "metric"
"description" => ""
"coordinates" => []
]
"type" => "module"
"theme path" => "modules/custom/weather"
"template" => "weather-forecast"
"path" => "modules/custom/weather/templates"
"preprocess functions" => array:2 [▼
0 => "template_preprocess"
1 => "contextual_preprocess"
]
]
"weather_forecast_single" => array:6 [ ▶]
➔ Provided by Devel module (on
/devel/theme/registry)
➔ For each theme hook
◆ List of variables (with
default values)
◆ Path on the filesystem
◆ Template
◆ Proprocess functions
34
Defining a theme hook
function weather_theme(): array {
return [
'weather_forecast' => [
'variables' => [
'forecast' => [],
'units' => 'metric',
'description' => '',
'coordinates' => [],
],
],
];
}
➔ weather.module
➔ List of theme hooks defined by
a module, with a machine
name and a list of accepted
variables (and their default
values)
35
weather-forecast.html.twig
{{ attach_library('
weather/map
') }}
{{ attach_library('
weather/base
') }}
<div class="forecast-list
">
{% for item in forecast.list %}
<div class="forecast-element
">
<h3 class="forecast-element__date
">{{ item.dt_txt|date("
d/m/Y H:i") }}</h3>
<p class="forecast-element__temp
">{{ item.main.temp }} °{{ units == '
metric' ? 'C' : 'F' }}</p>
<p class="forecast-element__description
">{{ item.weather[
0].description|title }}</
p>
<a href="{{ path('weather.details
', {city:forecast.city.name, date:item.dt_txt}) }}" class="use-ajax"
data-dialog-type
="dialog"
data-dialog-options
='{"width":700,"title":"{{ 'Details'|t }}"}'>More info</
a>
</div>
{% endfor %}
</div>
<div class="city-wrapper
">
<div class="city-description
">
{{ description }}
</div>
<div class="city-map">
<div id="map" data-lat="{{ coordinates
.0 }}" data-lng="{{ coordinates
.1 }}"></div>
</div>
</div>
36
Controller output
public function page(CityInterface $city): array {
$forecast = $this->weatherClient->getForecastData($city->label());
$build['content'] = [
'#theme' => 'weather_forecast',
'#forecast' => $forecast,
'#units' => $this->config('weather.settings')->get('units'),
'#description' => $city->getDescription(),
'#coordinates' => $city->getCoordinates(),
'#cache' => [
'max-age' => 10800, // 3 hours.
'tags' => [
'forecast:' . strtolower($city->label()),
],
'contexts' => [
'url',
],
],
];
return $build;
}
➔ Controllers return a render
array most of the time
➔ This is still not a Response
37
Drupal uses the render array returned from a controller to
fill the main page content.
We now need to understand how Drupal builds the render
array for the whole page and how it turns it into an HTML
response.
But at this point, even if you follow the source code, it’s
challenging to understand where the conversion
happens.
Controller output
A lot of systems in Drupal are loosely coupled and the
communications between them happens through the
event system.
When a controller returns something different from a
Response object, the Drupal Kernel takes the render
array and dispatches a kernel.view event.
38
How we discover that?
By tracing our page!
Tracing: o11y
39
➔ Observability suite
➔ Uses data collected by the Tracer module
➔ https://www.drupal.org/project/o11y/
➔ https://www.slideshare.net/sparkfabrik/do-you-kn
ow-what-your-drupal-is-doing-observe-it-drupalco
n-prague-2022
Drupal timeline
40
Events collector
41
$request = $event->getRequest();
$result = $event->getControllerResult();
// Render the controller result into a response if it's a render array.
if (
is_array($result) &&
($request->query->has(static::WRAPPER_FORMAT) || $request->getRequestFormat() == 'html')) {
$wrapper = $request->query->get(static::WRAPPER_FORMAT, 'html');
...
$renderer = $this->classResolver->getInstanceFromDefinition($this->mainContentRenderers[$wrapper]);
$response = $renderer->renderResponse($result, $request, $this->routeMatch);
...
$event->setResponse($response);
}
42
MainContentViewSubscriber
Events collector
43
foreach (
$this->blockRepository
->getVisibleBlocksPerRegion( $cacheable_metadata_list ) as $region => $blocks) {
/** @var DrupalblockBlockInterface [] $blocks */
foreach ($blocks as $key => $block) {
$block_plugin = $block->getPlugin();
if ($block_plugin instanceof MainContentBlockPluginInterface ) {
$block_plugin ->setMainContent( $this->mainContent );
$main_content_block_displayed = TRUE;
}
elseif ($block_plugin instanceof TitleBlockPluginInterface ) {
$block_plugin ->setTitle( $this->title);
}
elseif ($block_plugin instanceof MessagesBlockPluginInterface ) {
$messages_block_displayed = TRUE;
}
$build[$region][$key] = $this->blockViewBuilder ->view($block);
...
44
➔ Builds a render array with all
the visible blocks
BlockPageVariant
Blocks collector
45
index.php
46
Finally, the full HTML has been built.
The latest steps are to send the
response back to the browser and to
terminate the kernel.
use DrupalCoreDrupalKernel;
use SymfonyComponentHttpFoundationRequest;
$autoloader = require_once 'autoload.php';
$kernel = new DrupalKernel('prod', $autoloader);
$request = Request::createFromGlobals();
$response = $kernel->handle($request);
$response->send();
$kernel->terminate($request, $response);
47
Theme collector - Rendering Call Graph
48
Theme collector - Twig filters
49
Asset collector - Libraries
50
➔ Theme collector lists SDC components
➔ Frontend collector shows Core Web Vitals information (on Chrome)
➔ Ajax collector lists ajax calls made from a page
➔ Some pages are forms or views, you can inspect them too
➔ WebProfiler collects redirects and forwards
➔ WebProfiler collects sub-requests made by BigPipe
https://tech.sparkfabrik.com/en/blog/drupal-sdc/
https://tech.sparkfabrik.com/en/blog/webprofiler_updates/
Discover more
51
Chapter 1 - Setting Up a Local Environment
…
Chapter 3 - How Drupal Renders an HTML Page
Chapter 4 - Mapping the Design to Drupal Components
…
Chapter 11 - Single Directory Components
…
Chapter 15 - Building a Decoupled Frontend
Learn more
Join us for
contribution opportunities
17-20 October, 2023
Room 4.1 & 4.2
Mentored
Contribution
First Time
Contributor Workshop
General
Contribution
#DrupalContributions
17 - 20 October: 9:00 - 18:00
Room 4.1
17 October: 17:15 - 18:00
Room 2.4
18 October : 10:30 - 11:15
Room 2.4
20 October : 09:00 - 12:30
Room 4.2
20 October : 09:00 – 18:00
Room 4.2
What did you think?
Please fill in this session survey directly from the Mobile App.
We appreciate your feedback!
Please take a moment to fill out:
the Individual
session surveys
(in the Mobile App or
QR code at the entrance of each room)
1 2
the general
conference survey
Flash the QR code
OR
It will be sent by email

More Related Content

What's hot

Yocto Project : Custom Embedded Linux Distribution
Yocto Project : Custom Embedded Linux DistributionYocto Project : Custom Embedded Linux Distribution
Yocto Project : Custom Embedded Linux Distributionemertxemarketing
 
how to install VMware
how to install VMwarehow to install VMware
how to install VMwarertchandu
 
Memory Mapping Implementation (mmap) in Linux Kernel
Memory Mapping Implementation (mmap) in Linux KernelMemory Mapping Implementation (mmap) in Linux Kernel
Memory Mapping Implementation (mmap) in Linux KernelAdrian Huang
 
Scheduling in Android
Scheduling in AndroidScheduling in Android
Scheduling in AndroidOpersys inc.
 
Process Address Space: The way to create virtual address (page table) of user...
Process Address Space: The way to create virtual address (page table) of user...Process Address Space: The way to create virtual address (page table) of user...
Process Address Space: The way to create virtual address (page table) of user...Adrian Huang
 
[1A7]Ansible의이해와활용
[1A7]Ansible의이해와활용[1A7]Ansible의이해와활용
[1A7]Ansible의이해와활용NAVER D2
 
Reverse Mapping (rmap) in Linux Kernel
Reverse Mapping (rmap) in Linux KernelReverse Mapping (rmap) in Linux Kernel
Reverse Mapping (rmap) in Linux KernelAdrian Huang
 
April, 2021 OpenNTF Webinar - Domino Administration Best Practices
April, 2021 OpenNTF Webinar - Domino Administration Best PracticesApril, 2021 OpenNTF Webinar - Domino Administration Best Practices
April, 2021 OpenNTF Webinar - Domino Administration Best PracticesHoward Greenberg
 
malloc & vmalloc in Linux
malloc & vmalloc in Linuxmalloc & vmalloc in Linux
malloc & vmalloc in LinuxAdrian Huang
 
Userfaultfd: Current Features, Limitations and Future Development
Userfaultfd: Current Features, Limitations and Future DevelopmentUserfaultfd: Current Features, Limitations and Future Development
Userfaultfd: Current Features, Limitations and Future DevelopmentKernel TLV
 
Linux memory consumption
Linux memory consumptionLinux memory consumption
Linux memory consumptionhaish
 
Physical Memory Management.pdf
Physical Memory Management.pdfPhysical Memory Management.pdf
Physical Memory Management.pdfAdrian Huang
 
Monitoring in CloudStack
Monitoring in CloudStackMonitoring in CloudStack
Monitoring in CloudStackShapeBlue
 

What's hot (20)

Yocto Project : Custom Embedded Linux Distribution
Yocto Project : Custom Embedded Linux DistributionYocto Project : Custom Embedded Linux Distribution
Yocto Project : Custom Embedded Linux Distribution
 
Ansible
AnsibleAnsible
Ansible
 
how to install VMware
how to install VMwarehow to install VMware
how to install VMware
 
Memory Mapping Implementation (mmap) in Linux Kernel
Memory Mapping Implementation (mmap) in Linux KernelMemory Mapping Implementation (mmap) in Linux Kernel
Memory Mapping Implementation (mmap) in Linux Kernel
 
Scheduling in Android
Scheduling in AndroidScheduling in Android
Scheduling in Android
 
EMEA Airheads- Layer-3 Redundancy for Mobility Master - ArubaOS 8.x
EMEA Airheads- Layer-3 Redundancy for Mobility Master - ArubaOS 8.xEMEA Airheads- Layer-3 Redundancy for Mobility Master - ArubaOS 8.x
EMEA Airheads- Layer-3 Redundancy for Mobility Master - ArubaOS 8.x
 
Process Address Space: The way to create virtual address (page table) of user...
Process Address Space: The way to create virtual address (page table) of user...Process Address Space: The way to create virtual address (page table) of user...
Process Address Space: The way to create virtual address (page table) of user...
 
[1A7]Ansible의이해와활용
[1A7]Ansible의이해와활용[1A7]Ansible의이해와활용
[1A7]Ansible의이해와활용
 
Reverse Mapping (rmap) in Linux Kernel
Reverse Mapping (rmap) in Linux KernelReverse Mapping (rmap) in Linux Kernel
Reverse Mapping (rmap) in Linux Kernel
 
Linux DMA Engine
Linux DMA EngineLinux DMA Engine
Linux DMA Engine
 
April, 2021 OpenNTF Webinar - Domino Administration Best Practices
April, 2021 OpenNTF Webinar - Domino Administration Best PracticesApril, 2021 OpenNTF Webinar - Domino Administration Best Practices
April, 2021 OpenNTF Webinar - Domino Administration Best Practices
 
malloc & vmalloc in Linux
malloc & vmalloc in Linuxmalloc & vmalloc in Linux
malloc & vmalloc in Linux
 
Userfaultfd: Current Features, Limitations and Future Development
Userfaultfd: Current Features, Limitations and Future DevelopmentUserfaultfd: Current Features, Limitations and Future Development
Userfaultfd: Current Features, Limitations and Future Development
 
BIND DNS Configuration Red Hat 5
BIND DNS Configuration Red Hat 5BIND DNS Configuration Red Hat 5
BIND DNS Configuration Red Hat 5
 
Configuration Management in Ansible
Configuration Management in Ansible Configuration Management in Ansible
Configuration Management in Ansible
 
Linux Internals - Part I
Linux Internals - Part ILinux Internals - Part I
Linux Internals - Part I
 
Ansible 101
Ansible 101Ansible 101
Ansible 101
 
Linux memory consumption
Linux memory consumptionLinux memory consumption
Linux memory consumption
 
Physical Memory Management.pdf
Physical Memory Management.pdfPhysical Memory Management.pdf
Physical Memory Management.pdf
 
Monitoring in CloudStack
Monitoring in CloudStackMonitoring in CloudStack
Monitoring in CloudStack
 

Similar to Drupalcon 2023 - How Drupal builds your pages.pdf

Web applications with Catalyst
Web applications with CatalystWeb applications with Catalyst
Web applications with Catalystsvilen.ivanov
 
Drupal Day 2012 - Automating Drupal Development: Make!les, Features and Beyond
Drupal Day 2012 - Automating Drupal Development: Make!les, Features and BeyondDrupal Day 2012 - Automating Drupal Development: Make!les, Features and Beyond
Drupal Day 2012 - Automating Drupal Development: Make!les, Features and BeyondDrupalDay
 
Doctrine For Beginners
Doctrine For BeginnersDoctrine For Beginners
Doctrine For BeginnersJonathan Wage
 
Debugging in drupal 8
Debugging in drupal 8Debugging in drupal 8
Debugging in drupal 8Allie Jones
 
Prefixルーティングとthemeのススメ
PrefixルーティングとthemeのススメPrefixルーティングとthemeのススメ
PrefixルーティングとthemeのススメShusuke Otomo
 
Drupal Development
Drupal DevelopmentDrupal Development
Drupal DevelopmentJeff Eaton
 
Perl web frameworks
Perl web frameworksPerl web frameworks
Perl web frameworksdiego_k
 
Curscatalyst
CurscatalystCurscatalyst
CurscatalystKar Juan
 
CodeIgniter PHP MVC Framework
CodeIgniter PHP MVC FrameworkCodeIgniter PHP MVC Framework
CodeIgniter PHP MVC FrameworkBo-Yi Wu
 
What's New In Laravel 5
What's New In Laravel 5What's New In Laravel 5
What's New In Laravel 5Darren Craig
 
Andy Postnikov - Drupal 7 vs Drupal 8: от бутстрапа до рендера
Andy Postnikov - Drupal 7 vs Drupal 8: от бутстрапа до рендераAndy Postnikov - Drupal 7 vs Drupal 8: от бутстрапа до рендера
Andy Postnikov - Drupal 7 vs Drupal 8: от бутстрапа до рендераLEDC 2016
 
Phpne august-2012-symfony-components-friends
Phpne august-2012-symfony-components-friendsPhpne august-2012-symfony-components-friends
Phpne august-2012-symfony-components-friendsMichael Peacock
 
Auto-loading of Drupal CCK Nodes
Auto-loading of Drupal CCK NodesAuto-loading of Drupal CCK Nodes
Auto-loading of Drupal CCK Nodesnihiliad
 
Convert modules from 6.x to 7.x
Convert modules from 6.x to 7.xConvert modules from 6.x to 7.x
Convert modules from 6.x to 7.xJoão Ventura
 
Automating Drupal Development: Makefiles, features and beyond
Automating Drupal Development: Makefiles, features and beyondAutomating Drupal Development: Makefiles, features and beyond
Automating Drupal Development: Makefiles, features and beyondNuvole
 
Drupal 8 simple page: Mi primer proyecto en Drupal 8.
Drupal 8 simple page: Mi primer proyecto en Drupal 8.Drupal 8 simple page: Mi primer proyecto en Drupal 8.
Drupal 8 simple page: Mi primer proyecto en Drupal 8.Samuel Solís Fuentes
 

Similar to Drupalcon 2023 - How Drupal builds your pages.pdf (20)

Web applications with Catalyst
Web applications with CatalystWeb applications with Catalyst
Web applications with Catalyst
 
Drupal Day 2012 - Automating Drupal Development: Make!les, Features and Beyond
Drupal Day 2012 - Automating Drupal Development: Make!les, Features and BeyondDrupal Day 2012 - Automating Drupal Development: Make!les, Features and Beyond
Drupal Day 2012 - Automating Drupal Development: Make!les, Features and Beyond
 
Doctrine For Beginners
Doctrine For BeginnersDoctrine For Beginners
Doctrine For Beginners
 
RESTful web services
RESTful web servicesRESTful web services
RESTful web services
 
Debugging in drupal 8
Debugging in drupal 8Debugging in drupal 8
Debugging in drupal 8
 
Prefixルーティングとthemeのススメ
PrefixルーティングとthemeのススメPrefixルーティングとthemeのススメ
Prefixルーティングとthemeのススメ
 
Drupal Development
Drupal DevelopmentDrupal Development
Drupal Development
 
Perl web frameworks
Perl web frameworksPerl web frameworks
Perl web frameworks
 
Curscatalyst
CurscatalystCurscatalyst
Curscatalyst
 
CodeIgniter PHP MVC Framework
CodeIgniter PHP MVC FrameworkCodeIgniter PHP MVC Framework
CodeIgniter PHP MVC Framework
 
What's New In Laravel 5
What's New In Laravel 5What's New In Laravel 5
What's New In Laravel 5
 
Andy Postnikov - Drupal 7 vs Drupal 8: от бутстрапа до рендера
Andy Postnikov - Drupal 7 vs Drupal 8: от бутстрапа до рендераAndy Postnikov - Drupal 7 vs Drupal 8: от бутстрапа до рендера
Andy Postnikov - Drupal 7 vs Drupal 8: от бутстрапа до рендера
 
Lviv 2013 d7 vs d8
Lviv 2013   d7 vs d8Lviv 2013   d7 vs d8
Lviv 2013 d7 vs d8
 
Phpne august-2012-symfony-components-friends
Phpne august-2012-symfony-components-friendsPhpne august-2012-symfony-components-friends
Phpne august-2012-symfony-components-friends
 
Drupal 8 Services
Drupal 8 ServicesDrupal 8 Services
Drupal 8 Services
 
Auto-loading of Drupal CCK Nodes
Auto-loading of Drupal CCK NodesAuto-loading of Drupal CCK Nodes
Auto-loading of Drupal CCK Nodes
 
Introduction to angular js
Introduction to angular jsIntroduction to angular js
Introduction to angular js
 
Convert modules from 6.x to 7.x
Convert modules from 6.x to 7.xConvert modules from 6.x to 7.x
Convert modules from 6.x to 7.x
 
Automating Drupal Development: Makefiles, features and beyond
Automating Drupal Development: Makefiles, features and beyondAutomating Drupal Development: Makefiles, features and beyond
Automating Drupal Development: Makefiles, features and beyond
 
Drupal 8 simple page: Mi primer proyecto en Drupal 8.
Drupal 8 simple page: Mi primer proyecto en Drupal 8.Drupal 8 simple page: Mi primer proyecto en Drupal 8.
Drupal 8 simple page: Mi primer proyecto en Drupal 8.
 

Recently uploaded

Maximizing Efficiency and Profitability with OnePlan’s Professional Service A...
Maximizing Efficiency and Profitability with OnePlan’s Professional Service A...Maximizing Efficiency and Profitability with OnePlan’s Professional Service A...
Maximizing Efficiency and Profitability with OnePlan’s Professional Service A...OnePlan Solutions
 
Alluxio Monthly Webinar | Cloud-Native Model Training on Distributed Data
Alluxio Monthly Webinar | Cloud-Native Model Training on Distributed DataAlluxio Monthly Webinar | Cloud-Native Model Training on Distributed Data
Alluxio Monthly Webinar | Cloud-Native Model Training on Distributed DataAlluxio, Inc.
 
Advancing Engineering with AI through the Next Generation of Strategic Projec...
Advancing Engineering with AI through the Next Generation of Strategic Projec...Advancing Engineering with AI through the Next Generation of Strategic Projec...
Advancing Engineering with AI through the Next Generation of Strategic Projec...OnePlan Solutions
 
Adobe Marketo Engage Deep Dives: Using Webhooks to Transfer Data
Adobe Marketo Engage Deep Dives: Using Webhooks to Transfer DataAdobe Marketo Engage Deep Dives: Using Webhooks to Transfer Data
Adobe Marketo Engage Deep Dives: Using Webhooks to Transfer DataBradBedford3
 
Salesforce Certified Field Service Consultant
Salesforce Certified Field Service ConsultantSalesforce Certified Field Service Consultant
Salesforce Certified Field Service ConsultantAxelRicardoTrocheRiq
 
Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...
Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...
Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...stazi3110
 
Russian Call Girls in Karol Bagh Aasnvi ➡️ 8264348440 💋📞 Independent Escort S...
Russian Call Girls in Karol Bagh Aasnvi ➡️ 8264348440 💋📞 Independent Escort S...Russian Call Girls in Karol Bagh Aasnvi ➡️ 8264348440 💋📞 Independent Escort S...
Russian Call Girls in Karol Bagh Aasnvi ➡️ 8264348440 💋📞 Independent Escort S...soniya singh
 
Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024
Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024
Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024StefanoLambiase
 
Der Spagat zwischen BIAS und FAIRNESS (2024)
Der Spagat zwischen BIAS und FAIRNESS (2024)Der Spagat zwischen BIAS und FAIRNESS (2024)
Der Spagat zwischen BIAS und FAIRNESS (2024)OPEN KNOWLEDGE GmbH
 
(Genuine) Escort Service Lucknow | Starting ₹,5K To @25k with A/C 🧑🏽‍❤️‍🧑🏻 89...
(Genuine) Escort Service Lucknow | Starting ₹,5K To @25k with A/C 🧑🏽‍❤️‍🧑🏻 89...(Genuine) Escort Service Lucknow | Starting ₹,5K To @25k with A/C 🧑🏽‍❤️‍🧑🏻 89...
(Genuine) Escort Service Lucknow | Starting ₹,5K To @25k with A/C 🧑🏽‍❤️‍🧑🏻 89...gurkirankumar98700
 
Cloud Management Software Platforms: OpenStack
Cloud Management Software Platforms: OpenStackCloud Management Software Platforms: OpenStack
Cloud Management Software Platforms: OpenStackVICTOR MAESTRE RAMIREZ
 
Professional Resume Template for Software Developers
Professional Resume Template for Software DevelopersProfessional Resume Template for Software Developers
Professional Resume Template for Software DevelopersVinodh Ram
 
The Evolution of Karaoke From Analog to App.pdf
The Evolution of Karaoke From Analog to App.pdfThe Evolution of Karaoke From Analog to App.pdf
The Evolution of Karaoke From Analog to App.pdfPower Karaoke
 
EY_Graph Database Powered Sustainability
EY_Graph Database Powered SustainabilityEY_Graph Database Powered Sustainability
EY_Graph Database Powered SustainabilityNeo4j
 
ODSC - Batch to Stream workshop - integration of Apache Spark, Cassandra, Pos...
ODSC - Batch to Stream workshop - integration of Apache Spark, Cassandra, Pos...ODSC - Batch to Stream workshop - integration of Apache Spark, Cassandra, Pos...
ODSC - Batch to Stream workshop - integration of Apache Spark, Cassandra, Pos...Christina Lin
 
What are the key points to focus on before starting to learn ETL Development....
What are the key points to focus on before starting to learn ETL Development....What are the key points to focus on before starting to learn ETL Development....
What are the key points to focus on before starting to learn ETL Development....kzayra69
 
Intelligent Home Wi-Fi Solutions | ThinkPalm
Intelligent Home Wi-Fi Solutions | ThinkPalmIntelligent Home Wi-Fi Solutions | ThinkPalm
Intelligent Home Wi-Fi Solutions | ThinkPalmSujith Sukumaran
 
Recruitment Management Software Benefits (Infographic)
Recruitment Management Software Benefits (Infographic)Recruitment Management Software Benefits (Infographic)
Recruitment Management Software Benefits (Infographic)Hr365.us smith
 
React Server Component in Next.js by Hanief Utama
React Server Component in Next.js by Hanief UtamaReact Server Component in Next.js by Hanief Utama
React Server Component in Next.js by Hanief UtamaHanief Utama
 

Recently uploaded (20)

Maximizing Efficiency and Profitability with OnePlan’s Professional Service A...
Maximizing Efficiency and Profitability with OnePlan’s Professional Service A...Maximizing Efficiency and Profitability with OnePlan’s Professional Service A...
Maximizing Efficiency and Profitability with OnePlan’s Professional Service A...
 
Alluxio Monthly Webinar | Cloud-Native Model Training on Distributed Data
Alluxio Monthly Webinar | Cloud-Native Model Training on Distributed DataAlluxio Monthly Webinar | Cloud-Native Model Training on Distributed Data
Alluxio Monthly Webinar | Cloud-Native Model Training on Distributed Data
 
Advancing Engineering with AI through the Next Generation of Strategic Projec...
Advancing Engineering with AI through the Next Generation of Strategic Projec...Advancing Engineering with AI through the Next Generation of Strategic Projec...
Advancing Engineering with AI through the Next Generation of Strategic Projec...
 
Adobe Marketo Engage Deep Dives: Using Webhooks to Transfer Data
Adobe Marketo Engage Deep Dives: Using Webhooks to Transfer DataAdobe Marketo Engage Deep Dives: Using Webhooks to Transfer Data
Adobe Marketo Engage Deep Dives: Using Webhooks to Transfer Data
 
Salesforce Certified Field Service Consultant
Salesforce Certified Field Service ConsultantSalesforce Certified Field Service Consultant
Salesforce Certified Field Service Consultant
 
Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...
Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...
Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...
 
Russian Call Girls in Karol Bagh Aasnvi ➡️ 8264348440 💋📞 Independent Escort S...
Russian Call Girls in Karol Bagh Aasnvi ➡️ 8264348440 💋📞 Independent Escort S...Russian Call Girls in Karol Bagh Aasnvi ➡️ 8264348440 💋📞 Independent Escort S...
Russian Call Girls in Karol Bagh Aasnvi ➡️ 8264348440 💋📞 Independent Escort S...
 
Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024
Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024
Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024
 
Der Spagat zwischen BIAS und FAIRNESS (2024)
Der Spagat zwischen BIAS und FAIRNESS (2024)Der Spagat zwischen BIAS und FAIRNESS (2024)
Der Spagat zwischen BIAS und FAIRNESS (2024)
 
(Genuine) Escort Service Lucknow | Starting ₹,5K To @25k with A/C 🧑🏽‍❤️‍🧑🏻 89...
(Genuine) Escort Service Lucknow | Starting ₹,5K To @25k with A/C 🧑🏽‍❤️‍🧑🏻 89...(Genuine) Escort Service Lucknow | Starting ₹,5K To @25k with A/C 🧑🏽‍❤️‍🧑🏻 89...
(Genuine) Escort Service Lucknow | Starting ₹,5K To @25k with A/C 🧑🏽‍❤️‍🧑🏻 89...
 
Cloud Management Software Platforms: OpenStack
Cloud Management Software Platforms: OpenStackCloud Management Software Platforms: OpenStack
Cloud Management Software Platforms: OpenStack
 
Professional Resume Template for Software Developers
Professional Resume Template for Software DevelopersProfessional Resume Template for Software Developers
Professional Resume Template for Software Developers
 
The Evolution of Karaoke From Analog to App.pdf
The Evolution of Karaoke From Analog to App.pdfThe Evolution of Karaoke From Analog to App.pdf
The Evolution of Karaoke From Analog to App.pdf
 
EY_Graph Database Powered Sustainability
EY_Graph Database Powered SustainabilityEY_Graph Database Powered Sustainability
EY_Graph Database Powered Sustainability
 
ODSC - Batch to Stream workshop - integration of Apache Spark, Cassandra, Pos...
ODSC - Batch to Stream workshop - integration of Apache Spark, Cassandra, Pos...ODSC - Batch to Stream workshop - integration of Apache Spark, Cassandra, Pos...
ODSC - Batch to Stream workshop - integration of Apache Spark, Cassandra, Pos...
 
Hot Sexy call girls in Patel Nagar🔝 9953056974 🔝 escort Service
Hot Sexy call girls in Patel Nagar🔝 9953056974 🔝 escort ServiceHot Sexy call girls in Patel Nagar🔝 9953056974 🔝 escort Service
Hot Sexy call girls in Patel Nagar🔝 9953056974 🔝 escort Service
 
What are the key points to focus on before starting to learn ETL Development....
What are the key points to focus on before starting to learn ETL Development....What are the key points to focus on before starting to learn ETL Development....
What are the key points to focus on before starting to learn ETL Development....
 
Intelligent Home Wi-Fi Solutions | ThinkPalm
Intelligent Home Wi-Fi Solutions | ThinkPalmIntelligent Home Wi-Fi Solutions | ThinkPalm
Intelligent Home Wi-Fi Solutions | ThinkPalm
 
Recruitment Management Software Benefits (Infographic)
Recruitment Management Software Benefits (Infographic)Recruitment Management Software Benefits (Infographic)
Recruitment Management Software Benefits (Infographic)
 
React Server Component in Next.js by Hanief Utama
React Server Component in Next.js by Hanief UtamaReact Server Component in Next.js by Hanief Utama
React Server Component in Next.js by Hanief Utama
 

Drupalcon 2023 - How Drupal builds your pages.pdf

  • 1.
  • 2. lussoluca How Drupal builds your pages D10 edition
  • 3. Luca Lusso Drupal / PHP / Go developer @ SparkFabrik Drupal contributor (WebProfiler, Monolog, Symfony Messenger, …) and speaker Drupal.org: www.drupal.org/u/lussoluca Twitter: www.twitter.com/lussoluca LinkedIn: www.linkedin.com/in/lussoluca drupal.slack.com: lussoluca @lussoluca
  • 4. We are a tech company of engineers, developers and designers, capable of accompanying customers step by step in the CLOUD NATIVE era, with an agile and pragmatic approach. We are committed to OPEN SOURCE and we embrace its philosophy in our internal practices. TECHNOLOGY, STRATEGY AND METHOD 4
  • 5. 5 All Drupal pages are built in the same way: A Request is received and a Response is produced In this session we’ll see how Drupal turns an HTTP Request into an HTML Response
  • 6. 6 GET /en/forecast/lille HTTP/2 <!DOCTYPE html > <html lang="en" dir="ltr"> <head> <meta charset="utf-8" /> <meta name ="Generator" content ="Drupal 10 (https://www.drupal.org) " /> ... </html>
  • 7. 7 ➔ Custom module (machine name: weather) ➔ Custom page ➔ Not build using the Node system (even if the flow is the same, the Node system is too complex to be analyzed in a short time) ➔ There is a custom Entity called “City” used to store a description and some geographic coordinates ➔ On this page we retrieve the city, call an external service to get weather forecasts and build the output ➔ Demo module repository: https://github.com/lussoluca/weather /en/forecast/lille
  • 8. 8
  • 9. 9 In the context of computer programming, instrumentation refers to the measure of a product's performance, in order to diagnose errors and to write trace information. ➔ Profiling ➔ Tracing ➔ Logging Instrumentation
  • 10. 10 ➔ New settings page available from Drupal 10.1 ➔ /admin/config/development/settings ➔ Useful during inspection and development ➔ Disable optimizations
  • 11. Profiling: WebProfiler 11 WebProfiler adds a toolbar at the bottom of every page and shows you all sorts of stats, such as the amount of database queries loaded on the page, which services are used, and much more. Depends on: ➔ Devel ➔ Tracer https://www.drupal.org/project/webprofiler/
  • 12. 12
  • 13. index.php 13 ➔ Require the Composer autoload file ➔ Create a new Kernel ➔ Handle the request to build a response ➔ Return the response ➔ Terminate the Kernel ➔ Front controller pattern use DrupalCoreDrupalKernel; use SymfonyComponentHttpFoundationRequest; $autoloader = require_once 'autoload.php'; $kernel = new DrupalKernel('prod', $autoloader); $request = Request::createFromGlobals(); $response = $kernel->handle($request); $response->send(); $kernel->terminate($request, $response);
  • 14. ➔ https://stackphp.com/ ➔ DrupalKernel is decorated by a set of middlewares Stack middleware 14 DrupalKernel
  • 15. ➔ Ordered by priority desc on request and by priority asc on response Stack middleware 15
  • 16. 16 After passing through all the middlewares, the Request is handled by a router that finds the code responsible for converting the Request into a Response. In this case the Request is managed by a Controller: ForecastController. Request collector
  • 18. ➔ weather.routing.yml ➔ Route name: weather.forecast ➔ {city} placeholder ➔ _controller ➔ _title ➔ Requirements ➔ Param converters Routing weather.forecast: path: '/forecast/{city}' defaults: _controller: 'DrupalweatherControllerForecastController::page' _title_callback: 'DrupalweatherControllerForecastController::title' requirements: _permission: 'access content' options: parameters: city: type: 'weather:city' 18
  • 20. Param converters weather.forecast: path: '/forecast/{city}' defaults: _controller: 'DrupalweatherControllerForecastController::page' _title_callback: 'DrupalweatherControllerForecastController::title' requirements: _permission: 'access content' options: parameters: city: type: 'weather:city' The Node module uses the same technique to upcast the nid to full Node objects. 20
  • 21. Param converters public function applies( $definition , $name, Route $route):bool { if (!empty($definition ['type']) && $definition ['type'] === 'weather:city' ) { return TRUE; } return FALSE; } public function convert( $value, $definition , $name, array $defaults ):?CityInterface { $cities = $this -> entityTypeManager ->getStorage( 'city') ->loadByProperties([ 'label' => $value]); if (count( $cities) == 0) { return NULL; } return reset($cities); } ➔ applies is used to check if this param converter should be used for this route ➔ convert will takes the value from the url (lille) and convert it to something more structured (typically an object). If convert return NULL, Drupal will return a 404 error page. 21
  • 24. Title callback weather.forecast: path: '/forecast/{city}' defaults: _controller: 'DrupalweatherControllerForecastController::page' _title_callback: 'DrupalweatherControllerForecastController::title' requirements: _permission: 'access content' options: parameters: city: type: 'weather:city' Method used by Drupal to retrieve the title of a route 24
  • 25. Title callback public function title(CityInterface $city): string { return $this->t('Weather forecast for @city', [ '@city' => $city->label(), ]); } ➔ Returns a string ➔ Can use the parameters (upcasted) from the URL 25
  • 26. Controller callback weather.forecast: path: '/forecast/{city}' defaults: _controller: 'DrupalweatherControllerForecastController::page' _title_callback: 'DrupalweatherControllerForecastController::title' requirements: _permission: 'access content' options: parameters: city: type: 'weather:city' Method used by Drupal to retrieve the main content of a route 26
  • 27. Controller callback public function page(CityInterface $city): array { $forecast = $this->weatherClient ->getForecastData( $city->label()); $build['content' ] = [ '#theme' => 'weather_forecast' , '#forecast' => $forecast , '#units' => $this->config( 'weather.settings' )->get('units'), '#description' => $city->getDescription(), '#coordinates' => $city->getCoordinates(), '#cache' => [ 'max-age' => 10800, // 3 hours. 'tags' => [ 'forecast:' . strtolower( $city->label()), ], 'contexts' => [ 'url', ], ], ]; return $build; } 27
  • 28. Services public function page(CityInterface $city): array { $forecast = $this->weatherClient ->getForecastData( $city->label()); $build['content'] = [ '#theme' => 'weather_forecast', '#forecast' => $forecast, '#units' => $this->config('weather.settings')->get('units'), '#description' => $city->getDescription(), '#coordinates' => $city->getCoordinates(), '#cache' => [ 'max-age' => 10800, // 3 hours. 'tags' => [ 'forecast:' . strtolower($city->label()), ], 'contexts' => [ 'url', ], ], ]; return $build; } ➔ PHP classes to perform some useful task ◆ Sending email ◆ Authenticate users ◆ Call external services ◆ … ➔ Drupal core has more than 500 services ➔ We’ve seen a couple of them already: ◆ Middlewares are services ◆ Param converters are services 28
  • 31. 31 ➔ Well done! We found that the ForecastController has the piece of code that render this route! ➔ But wait… ➔ ForecastController returns the title of the page and a simple array… ◆ Where all this markup comes from? ◆ Where are loaded and placed the blocks (like the header and the footer)? ◆ How CSS and JavaScript assets are managed? Entering the Drupal render pipeline /en/forecast/lille
  • 33. Render arrays public function page(CityInterface $city): array { $forecast = $this->weatherClient->getForecastData($city->label()); $build['content' ] = [ '#theme' => 'weather_forecast' , '#forecast' => $forecast , '#units' => $this->config( 'weather.settings' )->get('units'), '#description' => $city->getDescription(), '#coordinates' => $city->getCoordinates(), '#cache' => [ 'max-age' => 10800, // 3 hours. 'tags' => [ 'forecast:' . strtolower( $city->label()), ], 'contexts' => [ 'url', ], ], ]; return $build; } ➔ weather_forecast: theme hook ➔ Keys that starts with ‘#’ are the properties ➔ Keys that doesn’t start with ‘#’ are nested render arrays ➔ Must declare ‘#cache’ information 33 ➔ Where I can find the whole list of available theme hooks? ➔ Which arguments are available?
  • 34. Theme registry "weather_details" => array:6 [ ▶] "weather_forecast" => array:6 [▼ "variables" => array:4 [▼ "forecast" => [] "units" => "metric" "description" => "" "coordinates" => [] ] "type" => "module" "theme path" => "modules/custom/weather" "template" => "weather-forecast" "path" => "modules/custom/weather/templates" "preprocess functions" => array:2 [▼ 0 => "template_preprocess" 1 => "contextual_preprocess" ] ] "weather_forecast_single" => array:6 [ ▶] ➔ Provided by Devel module (on /devel/theme/registry) ➔ For each theme hook ◆ List of variables (with default values) ◆ Path on the filesystem ◆ Template ◆ Proprocess functions 34
  • 35. Defining a theme hook function weather_theme(): array { return [ 'weather_forecast' => [ 'variables' => [ 'forecast' => [], 'units' => 'metric', 'description' => '', 'coordinates' => [], ], ], ]; } ➔ weather.module ➔ List of theme hooks defined by a module, with a machine name and a list of accepted variables (and their default values) 35
  • 36. weather-forecast.html.twig {{ attach_library(' weather/map ') }} {{ attach_library(' weather/base ') }} <div class="forecast-list "> {% for item in forecast.list %} <div class="forecast-element "> <h3 class="forecast-element__date ">{{ item.dt_txt|date(" d/m/Y H:i") }}</h3> <p class="forecast-element__temp ">{{ item.main.temp }} °{{ units == ' metric' ? 'C' : 'F' }}</p> <p class="forecast-element__description ">{{ item.weather[ 0].description|title }}</ p> <a href="{{ path('weather.details ', {city:forecast.city.name, date:item.dt_txt}) }}" class="use-ajax" data-dialog-type ="dialog" data-dialog-options ='{"width":700,"title":"{{ 'Details'|t }}"}'>More info</ a> </div> {% endfor %} </div> <div class="city-wrapper "> <div class="city-description "> {{ description }} </div> <div class="city-map"> <div id="map" data-lat="{{ coordinates .0 }}" data-lng="{{ coordinates .1 }}"></div> </div> </div> 36
  • 37. Controller output public function page(CityInterface $city): array { $forecast = $this->weatherClient->getForecastData($city->label()); $build['content'] = [ '#theme' => 'weather_forecast', '#forecast' => $forecast, '#units' => $this->config('weather.settings')->get('units'), '#description' => $city->getDescription(), '#coordinates' => $city->getCoordinates(), '#cache' => [ 'max-age' => 10800, // 3 hours. 'tags' => [ 'forecast:' . strtolower($city->label()), ], 'contexts' => [ 'url', ], ], ]; return $build; } ➔ Controllers return a render array most of the time ➔ This is still not a Response 37
  • 38. Drupal uses the render array returned from a controller to fill the main page content. We now need to understand how Drupal builds the render array for the whole page and how it turns it into an HTML response. But at this point, even if you follow the source code, it’s challenging to understand where the conversion happens. Controller output A lot of systems in Drupal are loosely coupled and the communications between them happens through the event system. When a controller returns something different from a Response object, the Drupal Kernel takes the render array and dispatches a kernel.view event. 38 How we discover that? By tracing our page!
  • 39. Tracing: o11y 39 ➔ Observability suite ➔ Uses data collected by the Tracer module ➔ https://www.drupal.org/project/o11y/ ➔ https://www.slideshare.net/sparkfabrik/do-you-kn ow-what-your-drupal-is-doing-observe-it-drupalco n-prague-2022
  • 42. $request = $event->getRequest(); $result = $event->getControllerResult(); // Render the controller result into a response if it's a render array. if ( is_array($result) && ($request->query->has(static::WRAPPER_FORMAT) || $request->getRequestFormat() == 'html')) { $wrapper = $request->query->get(static::WRAPPER_FORMAT, 'html'); ... $renderer = $this->classResolver->getInstanceFromDefinition($this->mainContentRenderers[$wrapper]); $response = $renderer->renderResponse($result, $request, $this->routeMatch); ... $event->setResponse($response); } 42 MainContentViewSubscriber
  • 44. foreach ( $this->blockRepository ->getVisibleBlocksPerRegion( $cacheable_metadata_list ) as $region => $blocks) { /** @var DrupalblockBlockInterface [] $blocks */ foreach ($blocks as $key => $block) { $block_plugin = $block->getPlugin(); if ($block_plugin instanceof MainContentBlockPluginInterface ) { $block_plugin ->setMainContent( $this->mainContent ); $main_content_block_displayed = TRUE; } elseif ($block_plugin instanceof TitleBlockPluginInterface ) { $block_plugin ->setTitle( $this->title); } elseif ($block_plugin instanceof MessagesBlockPluginInterface ) { $messages_block_displayed = TRUE; } $build[$region][$key] = $this->blockViewBuilder ->view($block); ... 44 ➔ Builds a render array with all the visible blocks BlockPageVariant
  • 46. index.php 46 Finally, the full HTML has been built. The latest steps are to send the response back to the browser and to terminate the kernel. use DrupalCoreDrupalKernel; use SymfonyComponentHttpFoundationRequest; $autoloader = require_once 'autoload.php'; $kernel = new DrupalKernel('prod', $autoloader); $request = Request::createFromGlobals(); $response = $kernel->handle($request); $response->send(); $kernel->terminate($request, $response);
  • 47. 47 Theme collector - Rendering Call Graph
  • 48. 48 Theme collector - Twig filters
  • 49. 49 Asset collector - Libraries
  • 50. 50 ➔ Theme collector lists SDC components ➔ Frontend collector shows Core Web Vitals information (on Chrome) ➔ Ajax collector lists ajax calls made from a page ➔ Some pages are forms or views, you can inspect them too ➔ WebProfiler collects redirects and forwards ➔ WebProfiler collects sub-requests made by BigPipe https://tech.sparkfabrik.com/en/blog/drupal-sdc/ https://tech.sparkfabrik.com/en/blog/webprofiler_updates/ Discover more
  • 51. 51 Chapter 1 - Setting Up a Local Environment … Chapter 3 - How Drupal Renders an HTML Page Chapter 4 - Mapping the Design to Drupal Components … Chapter 11 - Single Directory Components … Chapter 15 - Building a Decoupled Frontend Learn more
  • 52. Join us for contribution opportunities 17-20 October, 2023 Room 4.1 & 4.2 Mentored Contribution First Time Contributor Workshop General Contribution #DrupalContributions 17 - 20 October: 9:00 - 18:00 Room 4.1 17 October: 17:15 - 18:00 Room 2.4 18 October : 10:30 - 11:15 Room 2.4 20 October : 09:00 - 12:30 Room 4.2 20 October : 09:00 – 18:00 Room 4.2
  • 53. What did you think? Please fill in this session survey directly from the Mobile App.
  • 54. We appreciate your feedback! Please take a moment to fill out: the Individual session surveys (in the Mobile App or QR code at the entrance of each room) 1 2 the general conference survey Flash the QR code OR It will be sent by email