SlideShare a Scribd company logo
2023 - Drupalcon - How Drupal builds your pages
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
Ad

More Related Content

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

Perl web frameworks
Perl web frameworksPerl web frameworks
Perl web frameworks
diego_k
 
CodeIgniter PHP MVC Framework
CodeIgniter PHP MVC FrameworkCodeIgniter PHP MVC Framework
CodeIgniter PHP MVC Framework
Bo-Yi Wu
 
What's New In Laravel 5
What's New In Laravel 5What's New In Laravel 5
What's New In Laravel 5
Darren Craig
 
Lviv 2013 d7 vs d8
Lviv 2013   d7 vs d8Lviv 2013   d7 vs d8
Lviv 2013 d7 vs d8
Andy Postnikov
 
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-friends
Michael Peacock
 
Drupal 8 Services
Drupal 8 ServicesDrupal 8 Services
Drupal 8 Services
Philip Norton
 
Auto-loading of Drupal CCK Nodes
Auto-loading of Drupal CCK NodesAuto-loading of Drupal CCK Nodes
Auto-loading of Drupal CCK Nodes
nihiliad
 
Introduction to angular js
Introduction to angular jsIntroduction to angular js
Introduction to angular js
Marco Vito Moscaritolo
 
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
Nuvole
 
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
 
Cache metadata
Cache metadataCache metadata
Cache metadata
Joris Vercammen
 
Silex Cheat Sheet
Silex Cheat SheetSilex Cheat Sheet
Silex Cheat Sheet
Andréia Bohner
 
Silex Cheat Sheet
Silex Cheat SheetSilex Cheat Sheet
Silex Cheat Sheet
Andréia Bohner
 
Lviv 2013 d7 vs d8
Lviv 2013 d7 vs d8Lviv 2013 d7 vs d8
Lviv 2013 d7 vs d8
Skilld
 
Михаил Крайнюк - Form API + Drupal 8: Form and AJAX
Михаил Крайнюк - Form API + Drupal 8: Form and AJAXМихаил Крайнюк - Form API + Drupal 8: Form and AJAX
Михаил Крайнюк - Form API + Drupal 8: Form and AJAX
DrupalSib
 
Drupal 8 migrate!
Drupal 8 migrate!Drupal 8 migrate!
Drupal 8 migrate!
Pavel Makhrinsky
 
Getting Started with Capistrano
Getting Started with CapistranoGetting Started with Capistrano
Getting Started with Capistrano
LaunchAny
 
What's new in the Drupal 7 API?
What's new in the Drupal 7 API?What's new in the Drupal 7 API?
What's new in the Drupal 7 API?
Alexandru Badiu
 
Symfony console: build awesome command line scripts with ease
Symfony console: build awesome command line scripts with easeSymfony console: build awesome command line scripts with ease
Symfony console: build awesome command line scripts with ease
Oscar Merida
 
Perl web frameworks
Perl web frameworksPerl web frameworks
Perl web frameworks
diego_k
 
CodeIgniter PHP MVC Framework
CodeIgniter PHP MVC FrameworkCodeIgniter PHP MVC Framework
CodeIgniter PHP MVC Framework
Bo-Yi Wu
 
What's New In Laravel 5
What's New In Laravel 5What's New In Laravel 5
What's New In Laravel 5
Darren 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-friends
Michael Peacock
 
Auto-loading of Drupal CCK Nodes
Auto-loading of Drupal CCK NodesAuto-loading of Drupal CCK Nodes
Auto-loading of Drupal CCK Nodes
nihiliad
 
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
Nuvole
 
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
 
Lviv 2013 d7 vs d8
Lviv 2013 d7 vs d8Lviv 2013 d7 vs d8
Lviv 2013 d7 vs d8
Skilld
 
Михаил Крайнюк - Form API + Drupal 8: Form and AJAX
Михаил Крайнюк - Form API + Drupal 8: Form and AJAXМихаил Крайнюк - Form API + Drupal 8: Form and AJAX
Михаил Крайнюк - Form API + Drupal 8: Form and AJAX
DrupalSib
 
Getting Started with Capistrano
Getting Started with CapistranoGetting Started with Capistrano
Getting Started with Capistrano
LaunchAny
 
What's new in the Drupal 7 API?
What's new in the Drupal 7 API?What's new in the Drupal 7 API?
What's new in the Drupal 7 API?
Alexandru Badiu
 
Symfony console: build awesome command line scripts with ease
Symfony console: build awesome command line scripts with easeSymfony console: build awesome command line scripts with ease
Symfony console: build awesome command line scripts with ease
Oscar Merida
 

More from sparkfabrik (20)

Talks on my machine: Drupal, Storybook e SDC
Talks on my machine: Drupal, Storybook e SDCTalks on my machine: Drupal, Storybook e SDC
Talks on my machine: Drupal, Storybook e SDC
sparkfabrik
 
Talks on my machine: Drupal CMS versus The Cool Kids
Talks on my machine: Drupal CMS versus The Cool KidsTalks on my machine: Drupal CMS versus The Cool Kids
Talks on my machine: Drupal CMS versus The Cool Kids
sparkfabrik
 
Talks on my machine: Drupal: AI e Typesense come integrare la ricerca semantica
Talks on my machine:  Drupal: AI e Typesense come integrare la ricerca semanticaTalks on my machine:  Drupal: AI e Typesense come integrare la ricerca semantica
Talks on my machine: Drupal: AI e Typesense come integrare la ricerca semantica
sparkfabrik
 
KCD Italy 2023 - Secure Software Supply chain for OCI Artifact on Kubernetes
KCD Italy 2023 - Secure Software Supply chain for OCI Artifact on KubernetesKCD Italy 2023 - Secure Software Supply chain for OCI Artifact on Kubernetes
KCD Italy 2023 - Secure Software Supply chain for OCI Artifact on Kubernetes
sparkfabrik
 
20231129 - Platform @ localhost 2023 - Application-driven infrastructure with...
20231129 - Platform @ localhost 2023 - Application-driven infrastructure with...20231129 - Platform @ localhost 2023 - Application-driven infrastructure with...
20231129 - Platform @ localhost 2023 - Application-driven infrastructure with...
sparkfabrik
 
IAD 2023 - 22 Years of Agile and all I got is this lousy t-shirt
IAD 2023 - 22 Years of Agile and all I got is this lousy t-shirtIAD 2023 - 22 Years of Agile and all I got is this lousy t-shirt
IAD 2023 - 22 Years of Agile and all I got is this lousy t-shirt
sparkfabrik
 
2023 - TAC23 - Agile HR - Racconti dal fronte
2023 - TAC23 - Agile HR - Racconti dal fronte2023 - TAC23 - Agile HR - Racconti dal fronte
2023 - TAC23 - Agile HR - Racconti dal fronte
sparkfabrik
 
CodeMotion 2023 - Deep dive nella supply chain della nostra infrastruttura cl...
CodeMotion 2023 - Deep dive nella supply chain della nostra infrastruttura cl...CodeMotion 2023 - Deep dive nella supply chain della nostra infrastruttura cl...
CodeMotion 2023 - Deep dive nella supply chain della nostra infrastruttura cl...
sparkfabrik
 
What is the Secure Supply Chain and the Current State of the PHP Ecosystem
What is the Secure Supply Chain and the Current State of the PHP EcosystemWhat is the Secure Supply Chain and the Current State of the PHP Ecosystem
What is the Secure Supply Chain and the Current State of the PHP Ecosystem
sparkfabrik
 
UX e Web sostenibile (UXday 2023).pdf
UX e Web sostenibile (UXday 2023).pdfUX e Web sostenibile (UXday 2023).pdf
UX e Web sostenibile (UXday 2023).pdf
sparkfabrik
 
Drupal Dev Days Vienna 2023 - What is the secure software supply chain and th...
Drupal Dev Days Vienna 2023 - What is the secure software supply chain and th...Drupal Dev Days Vienna 2023 - What is the secure software supply chain and th...
Drupal Dev Days Vienna 2023 - What is the secure software supply chain and th...
sparkfabrik
 
Deep dive nella supply chain della nostra infrastruttura cloud
Deep dive nella supply chain della nostra infrastruttura cloudDeep dive nella supply chain della nostra infrastruttura cloud
Deep dive nella supply chain della nostra infrastruttura cloud
sparkfabrik
 
KCD Italy 2022 - Application driven infrastructure with Crossplane
KCD Italy 2022 - Application driven infrastructure with CrossplaneKCD Italy 2022 - Application driven infrastructure with Crossplane
KCD Italy 2022 - Application driven infrastructure with Crossplane
sparkfabrik
 
Come Drupal costruisce le tue pagine
Come Drupal costruisce le tue pagineCome Drupal costruisce le tue pagine
Come Drupal costruisce le tue pagine
sparkfabrik
 
Drupal 10: un framework PHP di sviluppo Cloud Native moderno
Drupal 10: un framework PHP di sviluppo Cloud Native modernoDrupal 10: un framework PHP di sviluppo Cloud Native moderno
Drupal 10: un framework PHP di sviluppo Cloud Native moderno
sparkfabrik
 
Do you know what your Drupal is doing Observe it! (DrupalCon Prague 2022)
Do you know what your Drupal is doing Observe it! (DrupalCon Prague 2022)Do you know what your Drupal is doing Observe it! (DrupalCon Prague 2022)
Do you know what your Drupal is doing Observe it! (DrupalCon Prague 2022)
sparkfabrik
 
Do you know what your Drupal is doing_ Observe it!
Do you know what your Drupal is doing_ Observe it!Do you know what your Drupal is doing_ Observe it!
Do you know what your Drupal is doing_ Observe it!
sparkfabrik
 
Progettare e sviluppare soluzioni serverless con AWS
Progettare e sviluppare soluzioni serverless con AWSProgettare e sviluppare soluzioni serverless con AWS
Progettare e sviluppare soluzioni serverless con AWS
sparkfabrik
 
From React to React Native - Things I wish I knew when I started
From React to React Native - Things I wish I knew when I startedFrom React to React Native - Things I wish I knew when I started
From React to React Native - Things I wish I knew when I started
sparkfabrik
 
Headless Drupal: A modern approach to (micro)services and APIs
Headless Drupal: A modern approach to (micro)services and APIsHeadless Drupal: A modern approach to (micro)services and APIs
Headless Drupal: A modern approach to (micro)services and APIs
sparkfabrik
 
Talks on my machine: Drupal, Storybook e SDC
Talks on my machine: Drupal, Storybook e SDCTalks on my machine: Drupal, Storybook e SDC
Talks on my machine: Drupal, Storybook e SDC
sparkfabrik
 
Talks on my machine: Drupal CMS versus The Cool Kids
Talks on my machine: Drupal CMS versus The Cool KidsTalks on my machine: Drupal CMS versus The Cool Kids
Talks on my machine: Drupal CMS versus The Cool Kids
sparkfabrik
 
Talks on my machine: Drupal: AI e Typesense come integrare la ricerca semantica
Talks on my machine:  Drupal: AI e Typesense come integrare la ricerca semanticaTalks on my machine:  Drupal: AI e Typesense come integrare la ricerca semantica
Talks on my machine: Drupal: AI e Typesense come integrare la ricerca semantica
sparkfabrik
 
KCD Italy 2023 - Secure Software Supply chain for OCI Artifact on Kubernetes
KCD Italy 2023 - Secure Software Supply chain for OCI Artifact on KubernetesKCD Italy 2023 - Secure Software Supply chain for OCI Artifact on Kubernetes
KCD Italy 2023 - Secure Software Supply chain for OCI Artifact on Kubernetes
sparkfabrik
 
20231129 - Platform @ localhost 2023 - Application-driven infrastructure with...
20231129 - Platform @ localhost 2023 - Application-driven infrastructure with...20231129 - Platform @ localhost 2023 - Application-driven infrastructure with...
20231129 - Platform @ localhost 2023 - Application-driven infrastructure with...
sparkfabrik
 
IAD 2023 - 22 Years of Agile and all I got is this lousy t-shirt
IAD 2023 - 22 Years of Agile and all I got is this lousy t-shirtIAD 2023 - 22 Years of Agile and all I got is this lousy t-shirt
IAD 2023 - 22 Years of Agile and all I got is this lousy t-shirt
sparkfabrik
 
2023 - TAC23 - Agile HR - Racconti dal fronte
2023 - TAC23 - Agile HR - Racconti dal fronte2023 - TAC23 - Agile HR - Racconti dal fronte
2023 - TAC23 - Agile HR - Racconti dal fronte
sparkfabrik
 
CodeMotion 2023 - Deep dive nella supply chain della nostra infrastruttura cl...
CodeMotion 2023 - Deep dive nella supply chain della nostra infrastruttura cl...CodeMotion 2023 - Deep dive nella supply chain della nostra infrastruttura cl...
CodeMotion 2023 - Deep dive nella supply chain della nostra infrastruttura cl...
sparkfabrik
 
What is the Secure Supply Chain and the Current State of the PHP Ecosystem
What is the Secure Supply Chain and the Current State of the PHP EcosystemWhat is the Secure Supply Chain and the Current State of the PHP Ecosystem
What is the Secure Supply Chain and the Current State of the PHP Ecosystem
sparkfabrik
 
UX e Web sostenibile (UXday 2023).pdf
UX e Web sostenibile (UXday 2023).pdfUX e Web sostenibile (UXday 2023).pdf
UX e Web sostenibile (UXday 2023).pdf
sparkfabrik
 
Drupal Dev Days Vienna 2023 - What is the secure software supply chain and th...
Drupal Dev Days Vienna 2023 - What is the secure software supply chain and th...Drupal Dev Days Vienna 2023 - What is the secure software supply chain and th...
Drupal Dev Days Vienna 2023 - What is the secure software supply chain and th...
sparkfabrik
 
Deep dive nella supply chain della nostra infrastruttura cloud
Deep dive nella supply chain della nostra infrastruttura cloudDeep dive nella supply chain della nostra infrastruttura cloud
Deep dive nella supply chain della nostra infrastruttura cloud
sparkfabrik
 
KCD Italy 2022 - Application driven infrastructure with Crossplane
KCD Italy 2022 - Application driven infrastructure with CrossplaneKCD Italy 2022 - Application driven infrastructure with Crossplane
KCD Italy 2022 - Application driven infrastructure with Crossplane
sparkfabrik
 
Come Drupal costruisce le tue pagine
Come Drupal costruisce le tue pagineCome Drupal costruisce le tue pagine
Come Drupal costruisce le tue pagine
sparkfabrik
 
Drupal 10: un framework PHP di sviluppo Cloud Native moderno
Drupal 10: un framework PHP di sviluppo Cloud Native modernoDrupal 10: un framework PHP di sviluppo Cloud Native moderno
Drupal 10: un framework PHP di sviluppo Cloud Native moderno
sparkfabrik
 
Do you know what your Drupal is doing Observe it! (DrupalCon Prague 2022)
Do you know what your Drupal is doing Observe it! (DrupalCon Prague 2022)Do you know what your Drupal is doing Observe it! (DrupalCon Prague 2022)
Do you know what your Drupal is doing Observe it! (DrupalCon Prague 2022)
sparkfabrik
 
Do you know what your Drupal is doing_ Observe it!
Do you know what your Drupal is doing_ Observe it!Do you know what your Drupal is doing_ Observe it!
Do you know what your Drupal is doing_ Observe it!
sparkfabrik
 
Progettare e sviluppare soluzioni serverless con AWS
Progettare e sviluppare soluzioni serverless con AWSProgettare e sviluppare soluzioni serverless con AWS
Progettare e sviluppare soluzioni serverless con AWS
sparkfabrik
 
From React to React Native - Things I wish I knew when I started
From React to React Native - Things I wish I knew when I startedFrom React to React Native - Things I wish I knew when I started
From React to React Native - Things I wish I knew when I started
sparkfabrik
 
Headless Drupal: A modern approach to (micro)services and APIs
Headless Drupal: A modern approach to (micro)services and APIsHeadless Drupal: A modern approach to (micro)services and APIs
Headless Drupal: A modern approach to (micro)services and APIs
sparkfabrik
 
Ad

Recently uploaded (20)

Big Data Analytics Quick Research Guide by Arthur Morgan
Big Data Analytics Quick Research Guide by Arthur MorganBig Data Analytics Quick Research Guide by Arthur Morgan
Big Data Analytics Quick Research Guide by Arthur Morgan
Arthur Morgan
 
Mobile App Development Company in Saudi Arabia
Mobile App Development Company in Saudi ArabiaMobile App Development Company in Saudi Arabia
Mobile App Development Company in Saudi Arabia
Steve Jonas
 
HCL Nomad Web – Best Practices und Verwaltung von Multiuser-Umgebungen
HCL Nomad Web – Best Practices und Verwaltung von Multiuser-UmgebungenHCL Nomad Web – Best Practices und Verwaltung von Multiuser-Umgebungen
HCL Nomad Web – Best Practices und Verwaltung von Multiuser-Umgebungen
panagenda
 
Greenhouse_Monitoring_Presentation.pptx.
Greenhouse_Monitoring_Presentation.pptx.Greenhouse_Monitoring_Presentation.pptx.
Greenhouse_Monitoring_Presentation.pptx.
hpbmnnxrvb
 
Splunk Security Update | Public Sector Summit Germany 2025
Splunk Security Update | Public Sector Summit Germany 2025Splunk Security Update | Public Sector Summit Germany 2025
Splunk Security Update | Public Sector Summit Germany 2025
Splunk
 
2025-05-Q4-2024-Investor-Presentation.pptx
2025-05-Q4-2024-Investor-Presentation.pptx2025-05-Q4-2024-Investor-Presentation.pptx
2025-05-Q4-2024-Investor-Presentation.pptx
Samuele Fogagnolo
 
Massive Power Outage Hits Spain, Portugal, and France: Causes, Impact, and On...
Massive Power Outage Hits Spain, Portugal, and France: Causes, Impact, and On...Massive Power Outage Hits Spain, Portugal, and France: Causes, Impact, and On...
Massive Power Outage Hits Spain, Portugal, and France: Causes, Impact, and On...
Aqusag Technologies
 
IEDM 2024 Tutorial2_Advances in CMOS Technologies and Future Directions for C...
IEDM 2024 Tutorial2_Advances in CMOS Technologies and Future Directions for C...IEDM 2024 Tutorial2_Advances in CMOS Technologies and Future Directions for C...
IEDM 2024 Tutorial2_Advances in CMOS Technologies and Future Directions for C...
organizerofv
 
Quantum Computing Quick Research Guide by Arthur Morgan
Quantum Computing Quick Research Guide by Arthur MorganQuantum Computing Quick Research Guide by Arthur Morgan
Quantum Computing Quick Research Guide by Arthur Morgan
Arthur Morgan
 
Linux Support for SMARC: How Toradex Empowers Embedded Developers
Linux Support for SMARC: How Toradex Empowers Embedded DevelopersLinux Support for SMARC: How Toradex Empowers Embedded Developers
Linux Support for SMARC: How Toradex Empowers Embedded Developers
Toradex
 
Special Meetup Edition - TDX Bengaluru Meetup #52.pptx
Special Meetup Edition - TDX Bengaluru Meetup #52.pptxSpecial Meetup Edition - TDX Bengaluru Meetup #52.pptx
Special Meetup Edition - TDX Bengaluru Meetup #52.pptx
shyamraj55
 
HCL Nomad Web – Best Practices and Managing Multiuser Environments
HCL Nomad Web – Best Practices and Managing Multiuser EnvironmentsHCL Nomad Web – Best Practices and Managing Multiuser Environments
HCL Nomad Web – Best Practices and Managing Multiuser Environments
panagenda
 
AI EngineHost Review: Revolutionary USA Datacenter-Based Hosting with NVIDIA ...
AI EngineHost Review: Revolutionary USA Datacenter-Based Hosting with NVIDIA ...AI EngineHost Review: Revolutionary USA Datacenter-Based Hosting with NVIDIA ...
AI EngineHost Review: Revolutionary USA Datacenter-Based Hosting with NVIDIA ...
SOFTTECHHUB
 
Increasing Retail Store Efficiency How can Planograms Save Time and Money.pptx
Increasing Retail Store Efficiency How can Planograms Save Time and Money.pptxIncreasing Retail Store Efficiency How can Planograms Save Time and Money.pptx
Increasing Retail Store Efficiency How can Planograms Save Time and Money.pptx
Anoop Ashok
 
The Evolution of Meme Coins A New Era for Digital Currency ppt.pdf
The Evolution of Meme Coins A New Era for Digital Currency ppt.pdfThe Evolution of Meme Coins A New Era for Digital Currency ppt.pdf
The Evolution of Meme Coins A New Era for Digital Currency ppt.pdf
Abi john
 
Cyber Awareness overview for 2025 month of security
Cyber Awareness overview for 2025 month of securityCyber Awareness overview for 2025 month of security
Cyber Awareness overview for 2025 month of security
riccardosl1
 
Procurement Insights Cost To Value Guide.pptx
Procurement Insights Cost To Value Guide.pptxProcurement Insights Cost To Value Guide.pptx
Procurement Insights Cost To Value Guide.pptx
Jon Hansen
 
Cybersecurity Identity and Access Solutions using Azure AD
Cybersecurity Identity and Access Solutions using Azure ADCybersecurity Identity and Access Solutions using Azure AD
Cybersecurity Identity and Access Solutions using Azure AD
VICTOR MAESTRE RAMIREZ
 
Electronic_Mail_Attacks-1-35.pdf by xploit
Electronic_Mail_Attacks-1-35.pdf by xploitElectronic_Mail_Attacks-1-35.pdf by xploit
Electronic_Mail_Attacks-1-35.pdf by xploit
niftliyevhuseyn
 
Designing Low-Latency Systems with Rust and ScyllaDB: An Architectural Deep Dive
Designing Low-Latency Systems with Rust and ScyllaDB: An Architectural Deep DiveDesigning Low-Latency Systems with Rust and ScyllaDB: An Architectural Deep Dive
Designing Low-Latency Systems with Rust and ScyllaDB: An Architectural Deep Dive
ScyllaDB
 
Big Data Analytics Quick Research Guide by Arthur Morgan
Big Data Analytics Quick Research Guide by Arthur MorganBig Data Analytics Quick Research Guide by Arthur Morgan
Big Data Analytics Quick Research Guide by Arthur Morgan
Arthur Morgan
 
Mobile App Development Company in Saudi Arabia
Mobile App Development Company in Saudi ArabiaMobile App Development Company in Saudi Arabia
Mobile App Development Company in Saudi Arabia
Steve Jonas
 
HCL Nomad Web – Best Practices und Verwaltung von Multiuser-Umgebungen
HCL Nomad Web – Best Practices und Verwaltung von Multiuser-UmgebungenHCL Nomad Web – Best Practices und Verwaltung von Multiuser-Umgebungen
HCL Nomad Web – Best Practices und Verwaltung von Multiuser-Umgebungen
panagenda
 
Greenhouse_Monitoring_Presentation.pptx.
Greenhouse_Monitoring_Presentation.pptx.Greenhouse_Monitoring_Presentation.pptx.
Greenhouse_Monitoring_Presentation.pptx.
hpbmnnxrvb
 
Splunk Security Update | Public Sector Summit Germany 2025
Splunk Security Update | Public Sector Summit Germany 2025Splunk Security Update | Public Sector Summit Germany 2025
Splunk Security Update | Public Sector Summit Germany 2025
Splunk
 
2025-05-Q4-2024-Investor-Presentation.pptx
2025-05-Q4-2024-Investor-Presentation.pptx2025-05-Q4-2024-Investor-Presentation.pptx
2025-05-Q4-2024-Investor-Presentation.pptx
Samuele Fogagnolo
 
Massive Power Outage Hits Spain, Portugal, and France: Causes, Impact, and On...
Massive Power Outage Hits Spain, Portugal, and France: Causes, Impact, and On...Massive Power Outage Hits Spain, Portugal, and France: Causes, Impact, and On...
Massive Power Outage Hits Spain, Portugal, and France: Causes, Impact, and On...
Aqusag Technologies
 
IEDM 2024 Tutorial2_Advances in CMOS Technologies and Future Directions for C...
IEDM 2024 Tutorial2_Advances in CMOS Technologies and Future Directions for C...IEDM 2024 Tutorial2_Advances in CMOS Technologies and Future Directions for C...
IEDM 2024 Tutorial2_Advances in CMOS Technologies and Future Directions for C...
organizerofv
 
Quantum Computing Quick Research Guide by Arthur Morgan
Quantum Computing Quick Research Guide by Arthur MorganQuantum Computing Quick Research Guide by Arthur Morgan
Quantum Computing Quick Research Guide by Arthur Morgan
Arthur Morgan
 
Linux Support for SMARC: How Toradex Empowers Embedded Developers
Linux Support for SMARC: How Toradex Empowers Embedded DevelopersLinux Support for SMARC: How Toradex Empowers Embedded Developers
Linux Support for SMARC: How Toradex Empowers Embedded Developers
Toradex
 
Special Meetup Edition - TDX Bengaluru Meetup #52.pptx
Special Meetup Edition - TDX Bengaluru Meetup #52.pptxSpecial Meetup Edition - TDX Bengaluru Meetup #52.pptx
Special Meetup Edition - TDX Bengaluru Meetup #52.pptx
shyamraj55
 
HCL Nomad Web – Best Practices and Managing Multiuser Environments
HCL Nomad Web – Best Practices and Managing Multiuser EnvironmentsHCL Nomad Web – Best Practices and Managing Multiuser Environments
HCL Nomad Web – Best Practices and Managing Multiuser Environments
panagenda
 
AI EngineHost Review: Revolutionary USA Datacenter-Based Hosting with NVIDIA ...
AI EngineHost Review: Revolutionary USA Datacenter-Based Hosting with NVIDIA ...AI EngineHost Review: Revolutionary USA Datacenter-Based Hosting with NVIDIA ...
AI EngineHost Review: Revolutionary USA Datacenter-Based Hosting with NVIDIA ...
SOFTTECHHUB
 
Increasing Retail Store Efficiency How can Planograms Save Time and Money.pptx
Increasing Retail Store Efficiency How can Planograms Save Time and Money.pptxIncreasing Retail Store Efficiency How can Planograms Save Time and Money.pptx
Increasing Retail Store Efficiency How can Planograms Save Time and Money.pptx
Anoop Ashok
 
The Evolution of Meme Coins A New Era for Digital Currency ppt.pdf
The Evolution of Meme Coins A New Era for Digital Currency ppt.pdfThe Evolution of Meme Coins A New Era for Digital Currency ppt.pdf
The Evolution of Meme Coins A New Era for Digital Currency ppt.pdf
Abi john
 
Cyber Awareness overview for 2025 month of security
Cyber Awareness overview for 2025 month of securityCyber Awareness overview for 2025 month of security
Cyber Awareness overview for 2025 month of security
riccardosl1
 
Procurement Insights Cost To Value Guide.pptx
Procurement Insights Cost To Value Guide.pptxProcurement Insights Cost To Value Guide.pptx
Procurement Insights Cost To Value Guide.pptx
Jon Hansen
 
Cybersecurity Identity and Access Solutions using Azure AD
Cybersecurity Identity and Access Solutions using Azure ADCybersecurity Identity and Access Solutions using Azure AD
Cybersecurity Identity and Access Solutions using Azure AD
VICTOR MAESTRE RAMIREZ
 
Electronic_Mail_Attacks-1-35.pdf by xploit
Electronic_Mail_Attacks-1-35.pdf by xploitElectronic_Mail_Attacks-1-35.pdf by xploit
Electronic_Mail_Attacks-1-35.pdf by xploit
niftliyevhuseyn
 
Designing Low-Latency Systems with Rust and ScyllaDB: An Architectural Deep Dive
Designing Low-Latency Systems with Rust and ScyllaDB: An Architectural Deep DiveDesigning Low-Latency Systems with Rust and ScyllaDB: An Architectural Deep Dive
Designing Low-Latency Systems with Rust and ScyllaDB: An Architectural Deep Dive
ScyllaDB
 
Ad

2023 - Drupalcon - How Drupal builds your pages

  • 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