Drupal 8 configuration system for coders and site builders - Drupalaton 2013

67
Drupal 8 Configuration system for coders and site builders Friday 16 August 13

description

Session given at Drupalaton 2013. Overview of the configuration management system in Drupal 8. Covers the api, config entities, context system.

Transcript of Drupal 8 configuration system for coders and site builders - Drupalaton 2013

Page 1: Drupal 8 configuration system for coders and site builders - Drupalaton 2013

Drupal 8 Configuration system for coders and site builders

Friday 16 August 13

Page 2: Drupal 8 configuration system for coders and site builders - Drupalaton 2013

who are we?

Kristof De Jaeger@swentel

co-maintainer of Field APILead maintainer of Display Suite

Developer @ Wunderkraut

Friday 16 August 13

Page 3: Drupal 8 configuration system for coders and site builders - Drupalaton 2013

who are we?

Gábor Hojtsy@gaborhojtsy

Multilingual Initiative ownerLong time Drupal Core contributor

Number one employee @ Acquia

Friday 16 August 13

Page 4: Drupal 8 configuration system for coders and site builders - Drupalaton 2013

Stop serving me Palinka

Friday 16 August 13

Page 5: Drupal 8 configuration system for coders and site builders - Drupalaton 2013

Ok, maybe one ...

Friday 16 August 13

Page 6: Drupal 8 configuration system for coders and site builders - Drupalaton 2013

What problems are we trying to solve?

• Variable soup

Live

Save

textSetting 1Setting 2 label

Database Database

Dev

TESTtest test test test test test test test test test test test test test

node/4admin/config/foo

WelcomeThis is real content on the live site that end users are viewing

node/4

Save

old textSetting 1Setting 2 label

admin/config/foo

Friday 16 August 13

Page 7: Drupal 8 configuration system for coders and site builders - Drupalaton 2013

Live

Save

textSetting 1Setting 2 label

Database Database

Dev

TESTtest test test test test test test test test test test test test test

node/4admin/config/foo

WelcomeThis is real content on the live site that end users are viewing

node/4

Save

old textSetting 1Setting 2 label

admin/config/foo

Danger!Want to bring over configuration

changes from dev, but not overwrite live content!

What problems are we trying to solve?

Friday 16 August 13

Page 8: Drupal 8 configuration system for coders and site builders - Drupalaton 2013

What problems are we trying to solve?

variable_set()/variable_get()

ctools_export_object()/ctools_export_load_object()

db_select()/db_update()/db_delete()

$conf[...];hook_update_N()

drush fu

http://www.flickr.com/photos/bean/322616749

napkins

Friday 16 August 13

Page 9: Drupal 8 configuration system for coders and site builders - Drupalaton 2013

Friday 16 August 13

Page 10: Drupal 8 configuration system for coders and site builders - Drupalaton 2013

The solution

• Files using the YAML specification

• Active and staging directory

• Cached in the database using a standard cache interface

Friday 16 August 13

Page 11: Drupal 8 configuration system for coders and site builders - Drupalaton 2013

The anatomy of a configuration file

Friday 16 August 13

Page 12: Drupal 8 configuration system for coders and site builders - Drupalaton 2013

system.site.yml

Friday 16 August 13

Page 13: Drupal 8 configuration system for coders and site builders - Drupalaton 2013

system.site.yml

Friday 16 August 13

Page 14: Drupal 8 configuration system for coders and site builders - Drupalaton 2013

system.site.yml

Friday 16 August 13

Page 15: Drupal 8 configuration system for coders and site builders - Drupalaton 2013

name: 'Configuration management'mail: [email protected]: 'makes Drupal 8 cex -y'page: 403: '' 404: '' front: node

system.site.yml

Friday 16 August 13

Page 16: Drupal 8 configuration system for coders and site builders - Drupalaton 2013

The API

Drupal::config()

->get()

->set()

->save()

Friday 16 August 13

Page 17: Drupal 8 configuration system for coders and site builders - Drupalaton 2013

Accessing data

Friday 16 August 13

Page 18: Drupal 8 configuration system for coders and site builders - Drupalaton 2013

name: 'Configuration management'mail: [email protected]: 'makes Drupal 8 cex -y'page: 403: '' 404: '' front: node

$site_name = Drupal::config('system.site')->get('name');

Friday 16 August 13

Page 19: Drupal 8 configuration system for coders and site builders - Drupalaton 2013

$page_data = Drupal::config('system.site')->get('page');

name: 'Configuration management'mail: [email protected]: 'makes Drupal 8 cex -y'page: 403: '' 404: '' front: node

Friday 16 August 13

Page 20: Drupal 8 configuration system for coders and site builders - Drupalaton 2013

$frontpage = Drupal::config('system.site')->get('page.front');

name: 'Configuration management'mail: [email protected]: 'makes Drupal 8 cex -y'page: 403: '' 404: '' front: node

Friday 16 August 13

Page 21: Drupal 8 configuration system for coders and site builders - Drupalaton 2013

$all_the_data = Drupal::config('system.site')->get();

name: 'Configuration management'mail: [email protected]: 'makes Drupal 8 cex -y'page: 403: '' 404: '' front: node

Friday 16 August 13

Page 22: Drupal 8 configuration system for coders and site builders - Drupalaton 2013

Saving data

Friday 16 August 13

Page 23: Drupal 8 configuration system for coders and site builders - Drupalaton 2013

name: 'CMI is good'mail: [email protected]: 'makes Drupal 8 cex -y'page: 403: '' 404: '' front: node

Drupal::config('system.site') ->set('name', 'CMI is good') ->save();

Friday 16 August 13

Page 24: Drupal 8 configuration system for coders and site builders - Drupalaton 2013

name: 'CMI is great'mail: [email protected]: 'makes Drupal 8 cex -y'page: 403: access-denied 404: not-found front: user

Drupal::config('system.site') ->set('name', 'CMI is great') ->set('page', array( 403 => 'access-denied', 404 => 'not-found', front => 'user', )) ->save();

Friday 16 August 13

Page 25: Drupal 8 configuration system for coders and site builders - Drupalaton 2013

Friday 16 August 13

Page 26: Drupal 8 configuration system for coders and site builders - Drupalaton 2013

• system_settings_form is dead

• add your own submit callback

• you are responsible for saving configuration

• ship with default configuration file

simple settings

Friday 16 August 13

Page 27: Drupal 8 configuration system for coders and site builders - Drupalaton 2013

{system}

{date_format_locale}

{date_formats}

{date_format_type}

{field_config}

{field_config_instance}

{filter}

{filter_format}

{node_type} {role}{role_permission}

{variable}

{language}

Friday 16 August 13

Page 28: Drupal 8 configuration system for coders and site builders - Drupalaton 2013

Config all the things!

Friday 16 August 13

Page 29: Drupal 8 configuration system for coders and site builders - Drupalaton 2013

Config entities

Friday 16 August 13

Page 30: Drupal 8 configuration system for coders and site builders - Drupalaton 2013

<?php

/** * @file * Definition of Drupal\contact\Plugin\Core\Entity\Category. */

namespace Drupal\contact\Plugin\Core\Entity;

use Drupal\Core\Config\Entity\ConfigEntityBase;use Drupal\Core\Annotation\Plugin;use Drupal\Core\Annotation\Translation;

/** * Defines the contact category entity. * * @EntityType( * id = "contact_category", * label = @Translation("Category"), * module = "contact", * controllers = { * controller_class = "Drupal\contact\CategoryStorageController", * list = "Drupal\contact\CategoryListController", * form = { * "add" = "Drupal\contact\CategoryFormController" * "edit" = "Drupal\contact\CategoryFormController" * } * } * uri_callback = "contact_category_uri", * config_prefix = "contact.category", * entity_keys = { * "id" = "id", * "label" = "label", * "uuid" = "uuid" * } * ) */class Category extends ConfigEntityBase implements CategoryInterface {

/** * The category ID. * * @var string */ public $id;

/** * The category UUID. * * @var string */ public $uuid;

/** * The category label. * * @var string */ public $label;

/** * List of recipient e-mail addresses. * * @var array */ public $recipients = array();

/** * An auto-reply message to send to the message author. * * @var string */ public $reply = '';

/** * Weight of this category (used for sorting). * * @var int */ public $weight = 0;

}

Friday 16 August 13

Page 31: Drupal 8 configuration system for coders and site builders - Drupalaton 2013

<?php

/** * @file * Definition of Drupal\contact\Plugin\Core\Entity\Category. */

namespace Drupal\contact\Plugin\Core\Entity;

use Drupal\Core\Config\Entity\ConfigEntityBase;use Drupal\Core\Annotation\Plugin;use Drupal\Core\Annotation\Translation;

/** * Defines the contact category entity. * * @EntityType( * id = "contact_category", * label = @Translation("Category"), * module = "contact", * controllers = { * controller_class = "Drupal\contact\CategoryStorageController", * list = "Drupal\contact\CategoryListController", * form = { * "add" = "Drupal\contact\CategoryFormController" * "edit" = "Drupal\contact\CategoryFormController" * } * } * uri_callback = "contact_category_uri", * config_prefix = "contact.category", * entity_keys = { * "id" = "id", * "label" = "label", * "uuid" = "uuid" * } * ) */class Category extends ConfigEntityBase implements CategoryInterface {

/** * The category ID. * * @var string */ public $id;

/** * The category UUID. * * @var string */ public $uuid;

/** * The category label. * * @var string */ public $label;

/** * List of recipient e-mail addresses. * * @var array */ public $recipients = array();

/** * An auto-reply message to send to the message author. * * @var string */ public $reply = '';

/** * Weight of this category (used for sorting). * * @var int */ public $weight = 0;

}

Friday 16 August 13

Page 32: Drupal 8 configuration system for coders and site builders - Drupalaton 2013

<?php

/** * @file * Definition of Drupal\contact\Plugin\Core\Entity\Category. */

namespace Drupal\contact\Plugin\Core\Entity;

use Drupal\Core\Config\Entity\ConfigEntityBase;use Drupal\Core\Annotation\Plugin;use Drupal\Core\Annotation\Translation;

/** * Defines the contact category entity. * * @Plugin( * id = "contact_category", * label = @Translation("Category"), * module = "contact", * controllers = { * controller_class = "Drupal\Core\Config\Entity\ConfigStorageController", * list = "Drupal\contact\CategoryListController", * form = { * "add" = "Drupal\contact\CategoryFormController" * } * }, * uri_callback = "contact_category_uri", * config_prefix = "contact.category", * entity_keys = { * "id" = "id", * "label" = "label", * "uuid" = "uuid" * } * ) */class Category extends ConfigEntityBase implements ContactInterface {

/** * The category ID. * * @var string */ public $id;

/** * The category UUID. * * @var string */ public $uuid;

/** * The category label. * * @var string */ public $label;

/** * List of recipient e-mail addresses. * * @var array */ public $recipients = array();

/** * An auto-reply message to send to the message author. * * @var string */ public $reply = '';

/** * Weight of this category (used for sorting). * * @var int */ public $weight = 0;

}

Friday 16 August 13

Page 33: Drupal 8 configuration system for coders and site builders - Drupalaton 2013

<?php

/** * @file * Definition of Drupal\contact\Plugin\Core\Entity\Category. */

namespace Drupal\contact\Plugin\Core\Entity;

use Drupal\Core\Config\Entity\ConfigEntityBase;use Drupal\Core\Annotation\Plugin;use Drupal\Core\Annotation\Translation;

/** * Defines the contact category entity. * * @EntityType( * id = "contact_category", * label = @Translation("Category"), * module = "contact", * controllers = { * controller_class = "Drupal\Core\Config\Entity\ConfigStorageController", * list = "Drupal\contact\CategoryListController", * form = { * "add" = "Drupal\contact\CategoryFormController" * "edit" = "Drupal\contact\CategoryFormController" * } * } * uri_callback = "contact_category_uri", * config_prefix = "contact.category", * entity_keys = { * "id" = "id", * "label" = "label", * "uuid" = "uuid" * } * ) */class Category extends ConfigEntityBase implements ContactInterface {

/** * The category ID. * * @var string */ public $id;

/** * The category UUID. * * @var string */ public $uuid;

/** * The category label. * * @var string */ public $label;

/** * List of recipient e-mail addresses. * * @var array */ public $recipients = array();

/** * An auto-reply message to send to the message author. * * @var string */ public $reply = '';

/** * Weight of this category (used for sorting). * * @var int */ public $weight = 0;

}

Friday 16 August 13

Page 34: Drupal 8 configuration system for coders and site builders - Drupalaton 2013

<?php

/** * @file * Definition of Drupal\contact\Plugin\Core\Entity\Category. */

namespace Drupal\contact\Plugin\Core\Entity;

use Drupal\Core\Config\Entity\ConfigEntityBase;use Drupal\Core\Annotation\Plugin;use Drupal\Core\Annotation\Translation;

/** * Defines the contact category entity. * * @Plugin( * id = "contact_category", * label = @Translation("Category"), * module = "contact", * controller_class = "Drupal\Core\Config\Entity\ConfigStorageController", * list_controller_class = "Drupal\contact\CategoryListController", * form_controller_class = { * "default" = "Drupal\contact\CategoryFormController" * }, * uri_callback = "contact_category_uri", * config_prefix = "contact.category", * entity_keys = { * "id" = "id", * "label" = "label", * "uuid" = "uuid" * } * ) */class Category extends ConfigEntityBase {

/** * The category ID. */ public $id;

/** * The category UUID. */ public $uuid;

/** * The category label. */ public $label;

/** * List of recipient e-mail addresses. */ public $recipients = array();

/** * An auto-reply message to send to the message author. */ public $reply = '';

/** * Weight of this category (used for sorting). */ public $weight = 0;

}

Friday 16 August 13

Page 35: Drupal 8 configuration system for coders and site builders - Drupalaton 2013

id: feedbackuuid: de77e4f3-f94b-41a5-ad05-5c32fa08444flabel: 'Website feedback'recipients: - ''reply: ''weight: '0'langcode: und

contact.category.feedback.yml

Friday 16 August 13

Page 36: Drupal 8 configuration system for coders and site builders - Drupalaton 2013

(config) entity API

• entity_load

• entity_save

• $object->any_method()

Friday 16 August 13

Page 37: Drupal 8 configuration system for coders and site builders - Drupalaton 2013

Deployment

Friday 16 August 13

Page 38: Drupal 8 configuration system for coders and site builders - Drupalaton 2013

Database

Development environment

ActiveDirectory

1

Friday 16 August 13

Page 39: Drupal 8 configuration system for coders and site builders - Drupalaton 2013

Database

Development environment

ActiveDirectory

1

Friday 16 August 13

Page 40: Drupal 8 configuration system for coders and site builders - Drupalaton 2013

Database

Development environment

ActiveDirectory

1

2

Friday 16 August 13

Page 41: Drupal 8 configuration system for coders and site builders - Drupalaton 2013

Database

Production environment

StagingDirectory

ActiveDirectory

3

admin/config/development/sync

Friday 16 August 13

Page 42: Drupal 8 configuration system for coders and site builders - Drupalaton 2013

Database

Production environment

StagingDirectory

ActiveDirectory

3

4admin/config/development/sync

Friday 16 August 13

Page 43: Drupal 8 configuration system for coders and site builders - Drupalaton 2013

Demo time

• No partial imports !

Friday 16 August 13

Page 44: Drupal 8 configuration system for coders and site builders - Drupalaton 2013

Advanced workflows

• https://drupal.org/sandbox/dereine/2057465

Friday 16 August 13

Page 45: Drupal 8 configuration system for coders and site builders - Drupalaton 2013

Don’t hack core

Friday 16 August 13

Page 46: Drupal 8 configuration system for coders and site builders - Drupalaton 2013

Don’t hack active config

Friday 16 August 13

Page 47: Drupal 8 configuration system for coders and site builders - Drupalaton 2013

State API

Drupal::state()->set('update.last_check', $now);//...$last_check = state()->get('update.last_check') ?: 0;

Only useful for this environment? Use state().

Friday 16 August 13

Page 48: Drupal 8 configuration system for coders and site builders - Drupalaton 2013

Drush integration

Friday 16 August 13

Page 49: Drupal 8 configuration system for coders and site builders - Drupalaton 2013

Context system,Events & Overrides

Friday 16 August 13

Page 50: Drupal 8 configuration system for coders and site builders - Drupalaton 2013

global $conf;

$conf['system.maintenance']['message'] = 'Sorry, our site is down now.';

Global overrides

Friday 16 August 13

Page 51: Drupal 8 configuration system for coders and site builders - Drupalaton 2013

class ConfigGlobalOverrideSubscriber implements EventSubscriberInterface {

static function getSubscribedEvents() { $events['config.init'][] = array('configInit', 30); return $events; }

public function configInit(ConfigEvent $event) { global $conf;

$config = $event->getConfig(); if (isset($conf[$config->getName()])) { $config->setOverride($conf[$config->getName()]); } }}

Global overrides

Friday 16 August 13

Page 52: Drupal 8 configuration system for coders and site builders - Drupalaton 2013

Break out of contexts

// Enter the override-free context, so we can ensure no overrides are applied.config_context_enter('config.context.free');

// Get system site maintenance message text from the original config.$message = config('system.maintenance')->get('message');

// Leave the override-free context.config_context_leave();

Friday 16 August 13

Page 53: Drupal 8 configuration system for coders and site builders - Drupalaton 2013

Get into contexts

// Enter a user specific context.$context = config_context_enter("Drupal\\user\\UserConfigContext");// Set the account to use on the context.$context->setAccount($account);

$mail_config = config('user.mail');

// Do stuff...

config_context_leave();

Friday 16 August 13

Page 54: Drupal 8 configuration system for coders and site builders - Drupalaton 2013

Language overridesblock.block.bartik.login.yml

id: bartik.loginuuid: 7012ebfd-7083-47ef-b...weight: '0'status: '1'langcode: enregion: sidebar_firstplugin: user_login_blocksettings: label: 'User login' module: user label_display: visible cache: '-1'......

locale.hu.block.block.bartik.login.yml

settings: label: 'Belépés'

locale.nl.block.block.bartik.login.yml

settings: label: 'Inloggen'

Friday 16 August 13

Page 55: Drupal 8 configuration system for coders and site builders - Drupalaton 2013

Configuration schema

Friday 16 August 13

Page 56: Drupal 8 configuration system for coders and site builders - Drupalaton 2013

system.maintenance.yml

enabled: '0'message: '@site is currently under maintenance. We should be back shortly. Thank you for your patience.'

Friday 16 August 13

Page 57: Drupal 8 configuration system for coders and site builders - Drupalaton 2013

system.schema.yml

system.maintenance: type: mapping label: 'Maintenance mode' mapping: "enabled": type: boolean label: "Put site into maintenance mode" "message": type: text label: "Message to display when in maintenance mode"

Friday 16 August 13

Page 58: Drupal 8 configuration system for coders and site builders - Drupalaton 2013

Basic scalar types from typed data

boolean: label: 'Boolean' class: '\Drupal\Core\TypedData\Type\Boolean'email: label: 'Email' class: '\Drupal\Core\TypedData\Type\Email'integer: label: 'Integer' class: '\Drupal\Core\TypedData\Type\Integer'string: label: 'String' class: '\Drupal\Core\TypedData\Type\String'uri: label: 'Uri' class: '\Drupal\Core\TypedData\Type\Uri'

Friday 16 August 13

Page 59: Drupal 8 configuration system for coders and site builders - Drupalaton 2013

Basic data types for configuration

undefined: label: 'Undefined' class: '\Drupal\Core\Config\Schema\Property'mapping: label: Mapping class: '\Drupal\Core\Config\Schema\Mapping'sequence: label: Sequence class: '\Drupal\Core\Config\Schema\Sequence'

Friday 16 August 13

Page 60: Drupal 8 configuration system for coders and site builders - Drupalaton 2013

Simple extended data types

# Human readable string that must be plain text and editable with a text field.label: type: string label: 'Label'

# Internal Drupal pathpath: type: string label: 'Path'

# Human readable string that can contain multiple lines of text or HTML.text: type: string label: 'Text'

Friday 16 August 13

Page 61: Drupal 8 configuration system for coders and site builders - Drupalaton 2013

Complex extended data type

# Mail text with subject and body parts.mail: type: mapping label: "Mail" mapping: "subject": type: text label: "Subject" "body": type: text label: "Body"

Friday 16 August 13

Page 62: Drupal 8 configuration system for coders and site builders - Drupalaton 2013

system.schema.yml

system.maintenance: type: mapping label: 'Maintenance mode' mapping: "enabled": type: boolean label: "Put site into maintenance mode" "message": type: text label: "Message to display when in maintenance mode"

Friday 16 August 13

Page 63: Drupal 8 configuration system for coders and site builders - Drupalaton 2013

What does all this add up to?$definition = Drupal::typedData()->getDefinition('system.maintenance');

array( 'label' => "Maintenance mode", 'class' => "\\Drupal\\Core\\Config\\Schema\\Mapping", 'mapping' => array( 'enabled' => array( 'type' => "boolean", 'label' => "Put site into maintenance mode", ), 'message' => array( 'type' => "text", 'label' => "Message to display when in maintenance mode", ), ),);

Friday 16 August 13

Page 64: Drupal 8 configuration system for coders and site builders - Drupalaton 2013

Config inspector module

Friday 16 August 13

Page 65: Drupal 8 configuration system for coders and site builders - Drupalaton 2013

Advice for module developers

• Config key names should have meaning

• Use config entities instead of tables

• Include config schema

Friday 16 August 13

Page 66: Drupal 8 configuration system for coders and site builders - Drupalaton 2013

• http://groups.drupal.org/cmi - Discussion

• http://v.gd/cmi_issues - Issues

• http://groups.drupal.org/core - Core announcements

• #drupal-cmi - Dedicated IRC channel

• http://drupal.org/core-mentoring-hours

Friday 16 August 13

Page 67: Drupal 8 configuration system for coders and site builders - Drupalaton 2013

Thanks@heyrocker

@webchick

@moshe_weitzman

@GaborHojtsy

@alexpott

Friday 16 August 13