D8: What's new?

Photo by Greg Rakozy on Unsplash

Injected!

  • IoC

  • OOP almost everywhere

  • Composer

  • TWIG

  • HttpKernel + Middlewares

Photo by Eddie Kopp on Unsplash

IoC

Inversion of control

  • programm flow (events), TUI vs GUI

 

is about getting freedom

  • responsibilities (DI), Startup vs Corporation
  • trust (interfaces),

Control... ?

...
if ($type == 'procmail') (
  new Procmail()->send();  
)
elseif(...) {
  new Postfix()->post();
}
elseif(...) {
  new Sendmail()->mail();
}
...

OOP

Why?

  • best for GUI
  • you can build loosely coupled architecture
  • handy for complex applications/frameworks

Composer

Facts:

  • improve dramaticaly DX
  • inspired by NPM
  • it's no metter where to get some package
  • r.i.p drush make
  • composer.json for dependencies definitions
    composer.lock - state of the current dependency versions

TWIG

Compiles template into
regular PHP code

No PHP code in template

// DRUPAL 7 bad practice in template detected :)
// legacy_theme/templates/form-payement.tpl.php
<div class="onef-1">
  <?php
  $term_selected=taxonomy_term_load(...);
  $terms = entity_load('taxonomy_term', ...);
  foreach ($terms as $term){
    ...
  }
  ?>
</div>
// => sites/default/files/php/twig/*.php

Sandbox mode

you can execute only predefined functions, filters, etc.

Wasn't it awesome?

// web/core/themes/bartik/templates/block.html.twig
<div{{ attributes.addClass(classes) }}>
  {{ title_prefix }}
  {% if label %}
    <h2{{ title_attributes }}>{{ label }}</h2>
  {% endif %}
  {{ title_suffix }}
  {% block content %}
    <div{{ content_attributes.addClass('content') }}>
      {{ content }}
    </div>
  {% endblock %}
</div>

OOP in templates)

{% include 'template.html' with {
  'foo': 'bar'
} only %}

{% extends "base.html" %}

{% embed "teasers_skeleton.twig" %}

HTTPKernel

GET /search?s=Drupal+8 HTTP/1.1
Host: dru.io
User-Agent: Mozilla/5.0 (Macintosh)
Accept: text/html,application/xhtml+xml
Referer: http://dru.io/
Accept-Encoding: gzip, deflate
Accept-Language: en-US,en;q=0.9
...
$request = Request::createFromGlobals();

\Symfony\Component\HttpFoundation\Request {
  ...
  public function initialize(...)  {
    $this->request = new ParameterBag($request);
    $this->query = new ParameterBag($query);
    $this->attributes = new ParameterBag($attributes);
    $this->cookies = new ParameterBag($cookies);
    $this->files = new FileBag($files);
    $this->server = new ServerBag($server);
    $this->headers = new HeaderBag(
      $this->server->getHeaders()
    );
    ...
  }
  ...
}
// $_GET['search_key'];
$request->query->get('search_key');
// $_POST['credit_card'];
$request->request->get('credit_card');
$request->get('credit_card');
// Header.
$request->get('host');
$request->getHost();

Middlewares

example

OAuth

by igorw

HttpCache

by symfony

GeoIp

by geocoder

GeoIp

by geocoder

CORS

by asm89

Turbolinks

by Helthe

Throttle

by penoonan

Whoops wrapper

by moufmouf

Logger

by h4cc

Honeypot

by CHH

CookieGuard

by laravel

encrypts outgoing cookies.

Middlewares

Middlewares

in Drupal

->step('StackedKernelPass')
    ->step('registerMiddlewares')([// <-using decorator pattern
      'http_middleware.negotiation',
      'http_middleware.reverse_proxy',
      'http_middleware.page_cache',
      'http_middleware.kernel_pre_handle',
      // -> drupalKernel->preHandle later call below steps :)
      // --> loadLegacyIncludes: 
      // comon, database, theme, menu, form...
      // --> loadAllModules
      // --> ...
      'http_middleware.session',
      'http_kernel.basic', // <- ROUTING COMES HERE
      // Request is filled up using event dispatcher system.
      // Also the whole routing process goes here

Drupal

Photo by Greg Rakozy on Unsplash

  • Views, Migrate, etc.. in core
  • Multilingual!
  • Render Arrays
  • New caching system
  • Config management
  • All is entity (almost)
  • Plugins
  • New Drush, Drupal console
  • Callable callbacks,
    or even service callbacks!

Render Arrays (RA)

$page = [
  '#type' => 'page',
  'content' => [
    'system_main' => […],
    'another_block' => […],
    '#sorted' => TRUE,
  ],
  'sidebar_first' => [
    …
  ],
];

Born to give developers a freedom for modifying content data before get passed into template engine

Very simple

property

element

sub-element

RA type

Cache system

$build = [
  '#theme' => 'page',
  '#cache' => [
    'tags' => [
      'user:1', 
      'node:2', 
      'custom_tag1'
    ],
  ],
];
$build[
  '#markup' => 'Test tags',
  '#cache' => [
    'contexts' => [
      'url.query_args:search_param',
    ],
  ],
];
$build[
  '#markup' => 'Test max-age',
  '#cache' => [
    'max-age' => Cache::PERMANENT,
  ],
];

26

CMI, Config Entity, Typed Data

Typed Data - ensures that object is type of X

CMI - Export, import, sync between app instances your config data:

config entities, config objects

Config Entity - multiple instances of Config Object 😉

Entities

Definition:
It is some object that could be:

-> loadable

-> enhanced by fields (fieldable)

-> revisionable

-> translatable

Plugins

$ drupal list | grep plugin | wc -l
21

$ drupal dpl | wc -l
53

$ drupal dpl field.formatter | wc -l
50

$ drupal dpl field.field_type | wc -l
34

$ drupal dpl field.widget | wc -l
28

$ drupal dpl block | wc -l
24

$ drupal dpl views.field | wc -l
59

$ drupal dpl views.filter | wc -l
39

...

308! (in this example)

plug & play reuseable objects

Drush, Drupal Console

automate your routine

Drush

Console

$ drupal list | grep debug
debug:event (dev)        Displays current events
debug:image:styles (dis) List image styles on the site
debug:libraries (dl)     Displays libraries available in application
debug:module (dm)        Displays current modules available for application
...
$ drupal list | grep debug | wc -l
32

$ drupal list | grep generate
generate:plugin:field (gpf)             Generate field type, widget and formatter plugins.
generate:plugin:fieldformatter (gpff)   Generate field formatter plugin.
generate:plugin:fieldtype (gpft)        Generate field type plugin.
generate:plugin:fieldwidget (gpfw)      Generate field widget plugin.
...
$ drupal list | grep generate | wc -l
45
drush rs
drush entup
drush cr/cc
drush cex/cim
drush status-report
drush config
drush scr
drush core:cli
drush pm:security
....

Drush commands (9.x)

class DevelCommands extends DrushCommands {
  ...
  
  /**
   * Uninstall, and Install modules.

   * @command devel:reinstall
   * @param $modules A comma-separated list of module names.
   * @aliases dre,devel-reinstall
   * @allow-additional-options pm-uninstall,pm-enable
   */
  public function reinstall($modules) {
    ...
    drush_invoke_process('@self', 'pm:uninstall', [$modules_str], []);
    drush_invoke_process('@self', 'pm:enable', [$modules_str], []);
  }
}

Summaries

Photo by Greg Rakozy on Unsplash

🚀

Bringing Symfony components & using intensively OOP as also as including other things like twig brings us a new level of flexibility in DX

Drupal became tests oriented that gives us stability,

great examples of "how to use.." out of the box

Use change records to see translations in code/api

Drupal 8 has a clear development vision for a new quick releases 

Links

OOP

Composer

Callable

Symfony

IoC

Midlewares

TWIG

Boost your DX

Homework

Founder @

Co- Founder @

Vladyslav Moyseenko, a.k.a vlad.dancer

&

D8 School: What's new

By Vlad Moyseenko

D8 School: What's new

  • 917