About me

  • CEO & Drupal dreamer at Ymbra
  • Drupal community member
  • @rvilar in twitter, drupal.org, IRC and mostly everywhere else
  • ramon@ymbra.com

Very thanks to Pedro Cambra

  • Drupal dreamer at Ymbra
  • Hyperactive Drupal community member
  • @pcambra in twitter, drupal.org, IRC and mostly everywhere else
  • pedro@ymbra.com

Drupal 8 initiatives

  • New to Drupal 8
  • Focus on important topics
  • Initiative leaders appointed by Dries
  • Organise better the community/volunteers: Birds of a feather flock together
  • Better visibility and reach

Drupal 8 initiatives

What's the status?

Drupal 8 initiatives

Who's behind them?

Under the hood

WYSIWYG in core

Before Twig

block.tpl.php

<?php if (isset($block_html_id)): ?>
  <div id="<?php print $block_html_id; ?>" <?php print $attributes; ?>>
<?php else: ?>
  <div <?php print $attributes; ?>>
<?php endif; ?>
<?php print render($title_prefix); ?>
<?php if ($label): ?>
  <h2<?php print $title_attributes; ?>><?php print $label; ?></h2>
<?php endif;?>
  <?php print render($title_suffix); ?>
  <div<?php print $content_attributes; ?>>
    <?php print render($content) ?>
  </div>
</div>
   	  

After Twig

block.html.twig

<div{{ attributes }}>
  {{ title_prefix }}
  {% if label %}
    <h2{{ title_attributes }}>{{ label }}</h2>
  {% endif %}
  {{ title_suffix }}

  <div{{ content_attributes }}>
    {{ content }}
  </div>
</div>
   	  

"Disabled modules are
broken beyond repair"

Bye bye module disable

You won't be missed, will you?

  • Disabling a module means disabling the interfaces
  • Data integrity risk when data is not up to date
  • It worked well in the past, when life was simpler
  • Removed module_disable() and enable/disable hooks
  • All installed modules are always installed and loaded
  • hook_modules_preinstall() will ensure uninstall consistency
  • Oh wait: Will be a module for this? "Disable modules"

Menus as entities

  • Menus are config entities same as vocabularies
  • Menu links (items) are content entities
  • hook_menu() disappears
  • What you define in hook_menu() is stored as content entities (menu links)

Remember the 'good old times'...

When we needed to have a .module file?

  • .module & .profile files are optional now
  • No need of empty .module or .profile files anymore
  • Only procedural code goes in the .module (i.e. hooks)
  • Modules discovered just by their info.yml file

PHP filter is gone

Aren't we feeling safer?

  • It might have been handy but at a high price
  • Security & performance could be easily compromised by non savvy users
  • Upgrade between versions got harder as PHP code could have been ANYWHERE
  • For those willing to take the risk, there's a module for that!

And this fellas too

  • Profile
  • Blog
  • Trigger
  • Dashboard
  • Menu
  • OpenID
  • Poll
  • Garland
  • Overlay

Migrate in core

  • Upgrade path won't be created for Drupal 8
  • Only used for very simple use cases in the past
  • Migrations are the way to go, even for Drupal to Drupal
  • Migrate for Drupal 8 uses best practices and is testable

Migrate in core

We define everything in yaml now, baby

migrate.migration.d6_user_role.yml

id: d6_user_role
source:
  plugin: d6_user_role
process:
  id:
    -
      plugin: machine_name
      source: name
    -
      plugin: dedupe_entity
      entity_type: user_role
      field: id
    -
      plugin: user_update_8002
  label: name
(...)
destination:
  plugin: entity:user_role
      

Migrate in core

The process, source, destination & load systems are pluggable

/**
 * This plugin creates a machine name.
 *
 * @MigrateProcessPlugin(
 *   id = "machine_name"
 * )
 */
class MachineName extends ProcessPluginBase {
(...)

  public function transform($value, MigrateExecutable $migrate_executable, Row $row, $destination_property) {
    $new_value = $this->getTransliteration()->transliterate($value, Language::LANGCODE_DEFAULT, '_');
    $new_value = strtolower($new_value);
    $new_value = preg_replace('/[^a-z0-9_]+/', '_', $new_value);
    return preg_replace('/_+/', '_', $new_value);
  }
      

& many more!

  • New directory structure
  • Class autoloader: PSR-4
  • Enhanced entity support for Mongo DB
  • UX improvements on content creation
  • Style guide
  • Tour module
  • New install theme
  • Removed support for IE6-IE8 (there's a module for that too)
  • ...

Now, let's talk about fields (& friends)

New field types

Making site builders happy

  • New goodies for site builders. Out of the box
  • Simplified ports of the equivalent Drupal 7 modules.
  • New field types:
    • Entity reference
    • Date (and time)
    • Email & Telephone
    • Link

Entity reference

Date and time

Link


  • No internal URL's (e.g. node/1)
  • No attributes (so far)

Email & telephone

Simplified version of both email and telephone modules for Drupal 7

  • e-mail validation
  • no anti-spam support
  • tel:+32 123 321 123

Hidden widget


  • It is not a 'hidden' input type
  • Renders nothing
  • Preserves values when saving entity forms
  • Use cases:
    • Programmatically save a value
    • Use rules or custom PHP

Comment as a field

Drupal 7: comment settings attached to node types and stored in variables

  • Comment settings are now a field.
  • Attach comments to any entity type.
  • Several comment fields per entity type.
  • "Reuse existing field" for alike comment configurations in different bundles.
  • There will be a upgrade path! migrate path!

Configurable form modes

If you aren't happy
to see core adding form modes
then we can’t be friends

@drupalhaikus

Fields & Plugins

Widgets, formatters & field types are pluggable components

  • In Drupal 7, they are based in hooks or magic callbacks, such as hook_field_validate()
  • Field storage backends - critical to swap to entity based storage
  • Drupal 8:
    • Plugin API
    • Classes
    • Inheritance

Annotated plugins

mymodule/lib/Plugin/field/widget/MyWidget.php

/**
 * @Widget(
 *   id = "mymodule_widget",
 *   label = @Translation("My awesome widget"),
 *   field_types = {
 *     "text"
 *   },
 *   settings = {
 *     "some_setting" = "Some default value"
 *   }
 * )
 */
class MyWidget extends WidgetBase {
	  

Widgets

mymodule/lib/Plugin/field/widget/MyWidget.php

class MyWidget extends WidgetBase {

 public function settingsForm(array $form, array &$form_state);
 public function formElement(array $items, array &$form, array &$form_state);
 public function errorElement(array $element, array $error,
 								array $form, array &$form_state);
 public function massageFormValues(array $values, array $form, array &$form_state);

}
      

Formatters

mymodule/lib/Plugin/field/formatter/MyFormatter.php

class MyFormatter extends FormatterBase {

  public function settingsForm(array $form, array &$form_state);
  public function settingsSummary();
  public function prepareView(array $entities, $langcode,array &$items);
  public function view(EntityInterface $entity, $langcode, array $items);

}
      

There is even more!

Other field api improvements

  • Field placehoders for defaults/examples
  • Support for computed fields
  • Image field multiple uploads
  • Drag & drop image upload support
  • User picture is a field
  • Field translation improvements
  • More granular permissions on Field UI

In the dock!

Without these people (and many more) this wouldn't have been possible

<Thank You!>