How To Fix A Bug In Drupal 8.Dev

Similar documents
Configuration Management in Drupal 8. Andrea Pescetti Nuvole

Entites in Drupal 8. Sascha Grossenbacher Christophe Galli

Everything you ever wanted to know about Drupal 8*

Features-Based Deployment

The Search API in Drupal 8. Thomas Seidl (drunken monkey)

DRUPAL CONTINUOUS INTEGRATION. Part I - Introduction

Wednesday, November 7, 12 THE LEADER IN DRUPAL PLATFORM DESIGN AND DEVELOPMENT

Drupal CMS for marketing sites

Drupal Drush Guide. Drupal.org

Drupal 8. Core and API Changes Shabir Ahmad MS Software Engg. NUST Principal Software Engineser PHP/Drupal

Multilingual content in Drupal 8: a highly evolved permutated API. DrupalCamp Vienna 2013 Francesco Placella

AVOIDING THE GIT OF DESPAIR

Module developer s tutorial

Drupal 8 The site builder's release

Things Made Easy: One Click CMS Integration with Solr & Drupal

(Don t Fear) the Features Now with more cowbell. Aimee Degnan / aimee@hook42.com

Auditing Drupal sites for performance, content and optimal configuration

Git - Working with Remote Repositories

Managing Projects Using Drupal 8 s Configuration Management System

Simple and powerful site deployment with capistrano

Migrating into Drupal 8

Drupal Node Overview. Attendee Guide. Prepared for: EDT502, Fall 2007, Dr. Savenye Prepared by: Jeff Beeman. November 26, 2007 EDT502 Final Project

Commerce Services Documentation

Drupal for Designers

Symfony2 and Drupal. Why to talk about Symfony2 framework?

Creating a Drupal 8 theme from scratch

Streamline your drupal development workflow in a 3-tier-environment - A story about drush make and drush aliases

Faichi Solutions. The Changing Face of Drupal with Drupal 8

Drupal Module Development

Getting Content into Drupal Using Migrate

BUILDING MULTILINGUAL WEBSITES WITH DRUPAL 7

Working with Indicee Elements

Improving your Drupal Development workflow with Continuous Integration

D7 Panels From Zero to Hero Tutorial

Magento OpenERP Integration Documentation

Certified PHP/MySQL Web Developer Course

c360 to Case Installation and Configuration Guide

The following is a comparison between CiviCRM, RedHen and CRM Core which are the leading option for CRM in the Drupal Community.

A (Web) Face for Radio. NPR and Drupal7 David Moore

Easy configuration of NETCONF devices

EVALUATION. WA1844 WebSphere Process Server 7.0 Programming Using WebSphere Integration COPY. Developer

Dry Dock Documentation

List Service Customizing a List. Introduction. Adding an Owner or Moderator. Process Summary Introduction. Adding an Owner or Moderator

LifeSize UVC Video Center Deployment Guide

EXT:Booking Extension

Introduction to Module Development

Migrating into Drupal 8 Migrando a Drupal 8

How does Drupal 7 Work? Tess Flynn, KDØPQK

NS DISCOVER 4.0 ADMINISTRATOR S GUIDE. July, Version 4.0

Version USER GUIDE

Novell Identity Manager

Report Writer's Guide Release 14.1

Apache Sentry. Prasad Mujumdar

Achieving Continuous Integration with Drupal

Web Publisher Administration Guide

MANAGE AND DEPLOY YOUR SITES WITH DRUSH

Listeners. Formats. Free Form. Formatted

Data Management Applications with Drupal as Your Framework

Magento module Documentation

Manual Password Depot Server 8

MASTER DRUPAL 7 MODULE DEVELOPMENT

Beginning Oracle. Application Express 4. Doug Gault. Timothy St. Hilaire. Karen Cannell. Martin D'Souza. Patrick Cimolini

System Walkthrough & Test Cases

Drupal and ArcGIS Yes, it can be done. Frank McLean Developer

CommonSpot Content Server Version 6.2 Release Notes

Nintex Workflow 2013 Help

Configuring Custom Fields in JEvents Club Addon

a paradigm for reusable drupal features Ian Ward Robert Soden

DEPLOYMENT GUIDE Version 1.2. Deploying F5 with Oracle E-Business Suite 12

Configuring. Moodle. Chapter 82

DEPLOYING DRUPAL USING CAPISTRANO

GP REPORTS VIEWER USER GUIDE

Integrating SurveyMethods With Freshdesk Using Zapier. Copyright 2015 SurveyMethods, Inc. All rights reserved.

Version Control Your Jenkins Jobs with Jenkins Job Builder

Develop a Native App (ios and Android) for a Drupal Website without Learning Objective-C or Java. Drupaldelphia 2014 By Joe Roberts

vsphere Host Profiles

IBM InfoSphere MDM Server v9.0. Version: Demo. Page <<1/11>>

Paul Boisvert. Director Product Management, Magento

Shop by Manufacturer Custom Module for Magento

Google Universal Analytics Enhanced E-commerce Tracking - Installation/Set-up Guide

c360 Portal Installation Guide

Exam Name: IBM InfoSphere MDM Server v9.0

Configuring the JEvents Component

LP Express Installation and User Manual

Programming Autodesk PLM 360 Using REST. Doug Redmond Software Engineer, Autodesk

Filter NEW IN FIRSTCLASS CLIENT WHAT S NEW IN FIRSTCLASS 9.0. New Look. Login screen. List View Sort Order. Filtering Containers.

Flexible Virtuemart 2 Template CleanMart (for VM2.0.x only) TUTORIAL. INSTALLATION CleanMart VM 2 Template (in 3 steps):

Mailchimp Integration Addon

My IC Customizer: Descriptors of Skins and Webapps for third party User Guide

NotePad No More: - A Personal Survey of HTML5 Developer Toolsets. Stewart Christie - Tizen and HTML5 Community Manager.

The truth about Drupal

Drupal 6 Web Application Development Tutorial

Knowledge Spaces. v9.1 Feature Review. Bob Peery, Director, Product Management

J j enterpririse. Oracle Application Express 3. Develop Native Oracle database-centric web applications quickly and easily with Oracle APEX

Web services with WebSphere Studio: Deploy and publish

Workflow Automation Support and troubleshooting guide

Localizing dynamic websites created from open source content management systems

HP A-IMC Firewall Manager

Transcription:

Drupal 8 Configuration system for coders and site builders

who am I? Kristof De Jaeger @swentel co-founder of eps & kaas co-maintainer of Field API Original creator of Display Suite

Outline What s the problem How did we solve it Simple static settings Configuration entities Deployment - with demo Configuration schema Context, events and overrides

What problems are we trying to solve? Dev admin/config/foo Setting 1 Setting 2 text label node/4 TEST test test test test test test test test test test test test test test Variable soup Save Live admin/config/foo Setting 1 old text Setting 2 label Save node/4 Welcome This is real content on the live site that end users are viewing Database Database

What problems are we trying to solve? Dev Live admin/config/foo node/4 admin/config/foo node/4 Setting 1 Setting 2 text label Save TEST test test test test test test test test test test test test test test Setting 1 Setting 2 old text label Save Welcome This is real content on the live site that end users are viewing Database Database Danger! Want to bring over configuration changes from dev, but not overwrite live content!

What problems are we trying to solve? variable_set()/variable_get() napkins db_select()/db_update()/ db_delete() hook_update_n() drush fu $conf[...]; ctools_export_object()/ ctools_export_load_object() http://www.flickr.com/photos/bean/322616749

The solution Files using the YAML specification Active and staging directory Cached in the database using a standard cache interface Config directory changed via settings.php This is all pluggable

The anatomy of a configuration file

system.site.yml

system.site.yml

system.site.yml

system.site.yml name: 'Configuration management' mail: admin@example.com slogan: 'makes Drupal 8 cex -y' page: 403: '' 404: '' front: node

The API Drupal::config() ->get() ->set() ->save()

Accessing data

$site_name = Drupal::config('system.site')->get('name'); name: 'Configuration management' mail: admin@example.com slogan: 'makes Drupal 8 cex -y' page: 403: '' 404: '' front: node

$page_data = Drupal::config('system.site')->get('page'); name: 'Configuration management' mail: admin@example.com slogan: 'makes Drupal 8 cex -y' page: 403: '' 404: '' front: node

$frontpage = Drupal::config('system.site')- >get('page.front'); name: 'Configuration management' mail: admin@example.com slogan: 'makes Drupal 8 cex -y' page: 403: '' 404: '' front: node

$all_the_data = Drupal::config('system.site')->get(); name: 'Configuration management' mail: admin@example.com slogan: 'makes Drupal 8 cex -y' page: 403: '' 404: '' front: node

Saving data

Drupal::config('system.site') ->set('name', 'CMI is good') ->save(); name: 'CMI is good' mail: admin@example.com slogan: 'makes Drupal 8 cex -y' page: 403: '' 404: '' front: node

Drupal::config('system.site') ->set('name', 'CMI is great') ->set('page', array( 403 => 'access-denied', 404 => 'not-found', front => 'user', )) ->save(); name: 'CMI is great' mail: admin@example.com slogan: 'makes Drupal 8 cex -y' page: 403: access-denied 404: not-found front: user

simple settings system_settings_form is dead create your own submit callback you are responsible for saving configuration ship with default configuration file

{language} {field_config} {date_format_type} {filter_format} {field_config_instance} {date_format_locale} {node_type} {role_permission} {role} {date_formats} {system} {variable} {filter}

Config all the things!

Config entities

/** Saturday 16 * November The 13category ID. 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 {

/** Saturday 16 * November The 13category ID. 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 {

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.

/** Saturday 16 * November The 13category ID. 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 {

*/ 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;

contact.category.feedback.yml id: feedback uuid: de77e4f3-f94b-41a5-ad05-5c32fa08444f label: 'Website feedback' recipients: - '' reply: '' weight: '0' langcode: und

(config) entity API entity_load entity_save $object->any_method()

Deployment

Development environment 1 Database Active Directory

Development environment 1 Database Active Directory

Development environment 1 Database 2 Active Directory

Production environment admin/config/development/sync Database 3 Staging Directory Active Directory

Production environment 4 admin/config/development/sync Database 3 Staging Directory Active Directory

Demo time Full import / export Single import / export No partial imports supported on CLI!

Drush integration

Advanced workflows https://drupal.org/sandbox/dereine/2057465 use git pre-commit hooks with defined config directories in settings.php

Don t hack core

Don t hack active config

State API Only useful for this environment? Use state(). Drupal::state()->set('update.last_check', $now); //... $last_check = Drupal::state()->get('update.last_check')?: 0;

Configuration schema

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

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"

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'

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'

Simple extended data types # Human readable string that must be plain text and editable with a text field. label: type: string label: 'Label' translatable: true # Internal Drupal path path: type: string label: 'Path' # Human readable string that can contain multiple lines of text or HTML. text: type: string label: 'Text' translatable: true

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"

Config inspector module

Context system, Events & Overrides

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

Global overrides 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()]); }

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();

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 = Drupal::config('user.mail'); // Do stuff... config_context_leave();

Language overrides block.block.bartik.login.yml id: bartik.login uuid: 7012ebfd-7083-47ef-b... weight: '0' status: '1' langcode: en region: sidebar_first plugin: user_login_block settings: 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'

recap and advice key names/properties should have meaning Use config entities instead of tables Use getters/setters/methods on entities Include config schema (translation!) Upgrade functions available in update.inc

Please try it out! #drupal-cmi - Dedicated IRC channel docs - https://drupal.org/node/1667894 help along - http://drupal.org/core-mentoring-hours

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

Questions?

Thanks @heyrocker @webchick @moshe_weitzman @GaborHojtsy @alexpott