drupal 8 configuration system for coders and site builders - drupalaton 2013

Post on 08-May-2015

1.069 Views

Category:

Technology

1 Downloads

Preview:

Click to see full reader

DESCRIPTION

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

TRANSCRIPT

Drupal 8 Configuration system for coders and site builders

Friday 16 August 13

who are we?

Kristof De Jaeger@swentel

co-maintainer of Field APILead maintainer of Display Suite

Developer @ Wunderkraut

Friday 16 August 13

who are we?

Gábor Hojtsy@gaborhojtsy

Multilingual Initiative ownerLong time Drupal Core contributor

Number one employee @ Acquia

Friday 16 August 13

Stop serving me Palinka

Friday 16 August 13

Ok, maybe one ...

Friday 16 August 13

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

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

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

Friday 16 August 13

The solution

• Files using the YAML specification

• Active and staging directory

• Cached in the database using a standard cache interface

Friday 16 August 13

The anatomy of a configuration file

Friday 16 August 13

system.site.yml

Friday 16 August 13

system.site.yml

Friday 16 August 13

system.site.yml

Friday 16 August 13

name: 'Configuration management'mail: admin@example.comslogan: 'makes Drupal 8 cex -y'page: 403: '' 404: '' front: node

system.site.yml

Friday 16 August 13

The API

Drupal::config()

->get()

->set()

->save()

Friday 16 August 13

Accessing data

Friday 16 August 13

name: 'Configuration management'mail: admin@example.comslogan: 'makes Drupal 8 cex -y'page: 403: '' 404: '' front: node

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

Friday 16 August 13

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

name: 'Configuration management'mail: admin@example.comslogan: 'makes Drupal 8 cex -y'page: 403: '' 404: '' front: node

Friday 16 August 13

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

name: 'Configuration management'mail: admin@example.comslogan: 'makes Drupal 8 cex -y'page: 403: '' 404: '' front: node

Friday 16 August 13

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

name: 'Configuration management'mail: admin@example.comslogan: 'makes Drupal 8 cex -y'page: 403: '' 404: '' front: node

Friday 16 August 13

Saving data

Friday 16 August 13

name: 'CMI is good'mail: admin@example.comslogan: 'makes Drupal 8 cex -y'page: 403: '' 404: '' front: node

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

Friday 16 August 13

name: 'CMI is great'mail: admin@example.comslogan: '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

Friday 16 August 13

• 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

{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

Config all the things!

Friday 16 August 13

Config entities

Friday 16 August 13

<?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

<?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

<?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

<?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

<?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

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

contact.category.feedback.yml

Friday 16 August 13

(config) entity API

• entity_load

• entity_save

• $object->any_method()

Friday 16 August 13

Deployment

Friday 16 August 13

Database

Development environment

ActiveDirectory

1

Friday 16 August 13

Database

Development environment

ActiveDirectory

1

Friday 16 August 13

Database

Development environment

ActiveDirectory

1

2

Friday 16 August 13

Database

Production environment

StagingDirectory

ActiveDirectory

3

admin/config/development/sync

Friday 16 August 13

Database

Production environment

StagingDirectory

ActiveDirectory

3

4admin/config/development/sync

Friday 16 August 13

Demo time

• No partial imports !

Friday 16 August 13

Advanced workflows

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

Friday 16 August 13

Don’t hack core

Friday 16 August 13

Don’t hack active config

Friday 16 August 13

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

Drush integration

Friday 16 August 13

Context system,Events & Overrides

Friday 16 August 13

global $conf;

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

Global overrides

Friday 16 August 13

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

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

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

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

Configuration schema

Friday 16 August 13

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

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

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

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

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

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

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

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

Config inspector module

Friday 16 August 13

Advice for module developers

• Config key names should have meaning

• Use config entities instead of tables

• Include config schema

Friday 16 August 13

• 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

Thanks@heyrocker

@webchick

@moshe_weitzman

@GaborHojtsy

@alexpott

Friday 16 August 13

top related