Drupal 8 Configuration system for
coders and site builders
Friday 23 August 13
who am I?
Kristof De Jaeger
@swentel
Co-maintainer of Field API
Lead maintainer of Display Suite
Developer @ Wunderkraut
F...
Outline
• What’s the problem
• How did we solve it
• Simple static settings
• Configuration entities
• Deployment - with de...
What problems are we
trying to solve?
• Variable soup
Live
Save
textSetting 1
Setting 2 label
Database Database
Dev
TEST
t...
Live
Save
textSetting 1
Setting 2 label
Database Database
Dev
TEST
test test test test
test test test test
test test test ...
What problems are we
trying to solve?
variable_set()/variable_get()
ctools_export_object()/
ctools_export_load_object()
db...
The solution
• Files using theYAML specification
• Active and staging directory
• Cached in the database using a standard
c...
The anatomy of a
configuration file
Friday 23 August 13
system.site.yml
Friday 23 August 13
system.site.yml
Friday 23 August 13
system.site.yml
Friday 23 August 13
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()
Friday 23 August 13
Accessing data
Friday 23 August 13
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: ...
$frontpage = Drupal::config('system.site')-
>get('page.front');
name: 'Configuration management'
mail: admin@example.com
s...
$all_the_data = Drupal::config('system.site')->get();
name: 'Configuration management'
mail: admin@example.com
slogan: 'ma...
Saving data
Friday 23 August 13
name: 'CMI is good'
mail: admin@example.com
slogan: 'makes Drupal 8 cex -y'
page:
403: ''
404: ''
front: node
Drupal::conf...
name: 'CMI is great'
mail: admin@example.com
slogan: 'makes Drupal 8 cex -y'
page:
403: access-denied
404: not-found
front...
Friday 23 August 13
• system_settings_form is dead
• add your own submit callback
• you are responsible for saving configuration
• ship with de...
{system}
{date_format_locale}
{date_formats}
{date_format_type}
{field_config}
{field_config_instance}
{filter}
{filter_format}
...
Config all the things!
Friday 23 August 13
Config entities
Friday 23 August 13
use DrupalCoreConfigEntityConfigEntityBase;
use DrupalCoreAnnotationPlugin;
use DrupalCoreAnnotationTranslation;
/**
* Def...
use DrupalCoreConfigEntityConfigEntityBase;
use DrupalCoreAnnotationPlugin;
use DrupalCoreAnnotationTranslation;
/**
* Def...
namespace DrupalcontactPluginCoreEntity;
use DrupalCoreConfigEntityConfigEntityBase;
use DrupalCoreAnnotationPlugin;
use D...
use DrupalCoreConfigEntityConfigEntityBase;
use DrupalCoreAnnotationPlugin;
use DrupalCoreAnnotationTranslation;
/**
* Def...
*/
class Category extends ConfigEntityBase {
/**
* The category ID.
*/
public $id;
/**
* The category UUID.
*/
public $uui...
id: feedback
uuid: de77e4f3-f94b-41a5-ad05-5c32fa08444f
label: 'Website feedback'
recipients:
- ''
reply: ''
weight: '0'
l...
(config) entity API
• entity_load
• entity_save
• $object->any_method()
Friday 23 August 13
Deployment
Friday 23 August 13
Database
Development environment
Active
Directory
1
Friday 23 August 13
Database
Development environment
Active
Directory
1
Friday 23 August 13
Database
Development environment
Active
Directory
1
2
Friday 23 August 13
Database
Production environment
Staging
Directory
Active
Directory
3
admin/config/development/sync
Friday 23 August 13
Database
Production environment
Staging
Directory
Active
Directory
3
4
admin/config/development/sync
Friday 23 August 13
Demo time
• No partial imports !
Friday 23 August 13
Drush integration
Friday 23 August 13
Advanced workflows
• https://drupal.org/sandbox/dereine/2057465
Friday 23 August 13
Don’t hack core
Friday 23 August 13
Don’t hack active config
Friday 23 August 13
State API
Drupal::state()->set('update.last_check', $now);
//...
$last_check = Drupal::state()->get('update.last_check') ?...
Configuration schema
Friday 23 August 13
system.maintenance.yml
enabled: '0'
message: '@site is currently under maintenance. We
should be back shortly. Thank you f...
system.schema.yml
system.maintenance:
type: mapping
label: 'Maintenance mode'
mapping:
"enabled":
type: boolean
label: "Pu...
Basic scalar types from typed data
boolean:
label: 'Boolean'
class: 'DrupalCoreTypedDataTypeBoolean'
email:
label: 'Email'...
Basic data types for configuration
undefined:
label: 'Undefined'
class: 'DrupalCoreConfigSchemaProperty'
mapping:
label: Ma...
Simple extended data types
# Human readable string that must be plain text and editable
with a text field.
label:
type: st...
Complex extended data type
# Mail text with subject and body parts.
mail:
type: mapping
label: "Mail"
mapping:
"subject":
...
Config inspector module
Friday 23 August 13
Context system,
Events & Overrides
Friday 23 August 13
global $conf;
$conf['system.maintenance']['message'] =
'Sorry, our site is down now.';
Global overrides
Friday 23 August 13
class ConfigGlobalOverrideSubscriber implements
EventSubscriberInterface {
static function getSubscribedEvents() {
$events...
Break out of contexts
// Enter the override-free context, so we can ensure no
overrides are applied.
config_context_enter(...
Get into contexts
// Enter a user specific context.
$context = config_context_enter("DrupaluserUserConfigContext");
// Set...
Language overrides
block.block.bartik.login.yml
id: bartik.login
uuid: 7012ebfd-7083-47ef-b...
weight: '0'
status: '1'
lan...
recap and advice
• key names/properties should have meaning
• Use config entities instead of tables
• Use getters/setters/m...
Please try it out!
• #drupal-cmi - Dedicated IRC channel
• docs - https://drupal.org/node/1667894
• help along - http://dr...
• http://groups.drupal.org/cmi - Discussion
• http://v.gd/cmi_issues - Issues
• http://groups.drupal.org/core - Core annou...
Questions ?
Friday 23 August 13
Thanks
@heyrocker
@webchick
@moshe_weitzman
@GaborHojtsy
@alexpott
Friday 23 August 13
Upcoming SlideShare
Loading in...5
×

Drupal 8 configuration system for coders and site builders - DrupalCamp Baltics 2013

4,401

Published on

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

Published in: Technology
0 Comments
4 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total Views
4,401
On Slideshare
0
From Embeds
0
Number of Embeds
2
Actions
Shares
0
Downloads
23
Comments
0
Likes
4
Embeds 0
No embeds

No notes for slide

Drupal 8 configuration system for coders and site builders - DrupalCamp Baltics 2013

  1. 1. Drupal 8 Configuration system for coders and site builders Friday 23 August 13
  2. 2. who am I? Kristof De Jaeger @swentel Co-maintainer of Field API Lead maintainer of Display Suite Developer @ Wunderkraut Friday 23 August 13
  3. 3. Outline • What’s the problem • How did we solve it • Simple static settings • Configuration entities • Deployment - with demo • Configuration schema • Context, events and overrides Friday 23 August 13
  4. 4. What problems are we trying to solve? • Variable soup Live Save textSetting 1 Setting 2 label Database Database Dev TEST test test test test test test test test test test test test test test node/4admin/config/foo Welcome This is real content on the live site that end users are viewing node/4 Save old textSetting 1 Setting 2 label admin/config/foo Friday 23 August 13
  5. 5. Live Save textSetting 1 Setting 2 label Database Database Dev TEST test test test test test test test test test test test test test test node/4admin/config/foo Welcome This is real content on the live site that end users are viewing node/4 Save old textSetting 1 Setting 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 23 August 13
  6. 6. 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 23 August 13
  7. 7. The solution • Files using theYAML specification • Active and staging directory • Cached in the database using a standard cache interface • Config directory changed via settings.php Friday 23 August 13
  8. 8. The anatomy of a configuration file Friday 23 August 13
  9. 9. system.site.yml Friday 23 August 13
  10. 10. system.site.yml Friday 23 August 13
  11. 11. system.site.yml Friday 23 August 13
  12. 12. name: 'Configuration management' mail: admin@example.com slogan: 'makes Drupal 8 cex -y' page: 403: '' 404: '' front: node system.site.yml Friday 23 August 13
  13. 13. The API Drupal::config() ->get() ->set() ->save() Friday 23 August 13
  14. 14. Accessing data Friday 23 August 13
  15. 15. name: 'Configuration management' mail: admin@example.com slogan: 'makes Drupal 8 cex -y' page: 403: '' 404: '' front: node $site_name = Drupal::config('system.site')->get('name'); Friday 23 August 13
  16. 16. $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 Friday 23 August 13
  17. 17. $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 Friday 23 August 13
  18. 18. $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 Friday 23 August 13
  19. 19. Saving data Friday 23 August 13
  20. 20. 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 good') ->save(); Friday 23 August 13
  21. 21. name: 'CMI is great' mail: admin@example.com slogan: '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 23 August 13
  22. 22. Friday 23 August 13
  23. 23. • system_settings_form is dead • add your own submit callback • you are responsible for saving configuration • ship with default configuration file simple settings Friday 23 August 13
  24. 24. {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 23 August 13
  25. 25. Config all the things! Friday 23 August 13
  26. 26. Config entities Friday 23 August 13
  27. 27. use DrupalCoreConfigEntityConfigEntityBase; use DrupalCoreAnnotationPlugin; use DrupalCoreAnnotationTranslation; /** * Defines the contact category entity. * * @EntityType( * id = "contact_category", * label = @Translation("Category"), * module = "contact", * controllers = { * controller_class = "DrupalcontactCategoryStorageController", * list = "DrupalcontactCategoryListController", * form = { * "add" = "DrupalcontactCategoryFormController" * "edit" = "DrupalcontactCategoryFormController" * } * } * 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.Friday 23 August 13
  28. 28. use DrupalCoreConfigEntityConfigEntityBase; use DrupalCoreAnnotationPlugin; use DrupalCoreAnnotationTranslation; /** * Defines the contact category entity. * * @EntityType( * id = "contact_category", * label = @Translation("Category"), * module = "contact", * controllers = { * controller_class = "DrupalcontactCategoryStorageController", * list = "DrupalcontactCategoryListController", * form = { * "add" = "DrupalcontactCategoryFormController" * "edit" = "DrupalcontactCategoryFormController" * } * } * 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.Friday 23 August 13
  29. 29. namespace DrupalcontactPluginCoreEntity; use DrupalCoreConfigEntityConfigEntityBase; use DrupalCoreAnnotationPlugin; use DrupalCoreAnnotationTranslation; /** * Defines the contact category entity. * * @Plugin( * id = "contact_category", * label = @Translation("Category"), * module = "contact", * controllers = { * controller_class = "DrupalCoreConfigEntityConfigStorageController", * list = "DrupalcontactCategoryListController", * form = { * "add" = "DrupalcontactCategoryFormController" * } * }, * 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. Friday 23 August 13
  30. 30. use DrupalCoreConfigEntityConfigEntityBase; use DrupalCoreAnnotationPlugin; use DrupalCoreAnnotationTranslation; /** * Defines the contact category entity. * * @EntityType( * id = "contact_category", * label = @Translation("Category"), * module = "contact", * controllers = { * controller_class = "DrupalCoreConfigEntityConfigStorageController", * list = "DrupalcontactCategoryListController", * form = { * "add" = "DrupalcontactCategoryFormController" * "edit" = "DrupalcontactCategoryFormController" * } * } * 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.Friday 23 August 13
  31. 31. */ 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 23 August 13
  32. 32. id: feedback uuid: de77e4f3-f94b-41a5-ad05-5c32fa08444f label: 'Website feedback' recipients: - '' reply: '' weight: '0' langcode: und contact.category.feedback.yml Friday 23 August 13
  33. 33. (config) entity API • entity_load • entity_save • $object->any_method() Friday 23 August 13
  34. 34. Deployment Friday 23 August 13
  35. 35. Database Development environment Active Directory 1 Friday 23 August 13
  36. 36. Database Development environment Active Directory 1 Friday 23 August 13
  37. 37. Database Development environment Active Directory 1 2 Friday 23 August 13
  38. 38. Database Production environment Staging Directory Active Directory 3 admin/config/development/sync Friday 23 August 13
  39. 39. Database Production environment Staging Directory Active Directory 3 4 admin/config/development/sync Friday 23 August 13
  40. 40. Demo time • No partial imports ! Friday 23 August 13
  41. 41. Drush integration Friday 23 August 13
  42. 42. Advanced workflows • https://drupal.org/sandbox/dereine/2057465 Friday 23 August 13
  43. 43. Don’t hack core Friday 23 August 13
  44. 44. Don’t hack active config Friday 23 August 13
  45. 45. State API Drupal::state()->set('update.last_check', $now); //... $last_check = Drupal::state()->get('update.last_check') ?: 0; Only useful for this environment? Use state(). Friday 23 August 13
  46. 46. Configuration schema Friday 23 August 13
  47. 47. system.maintenance.yml enabled: '0' message: '@site is currently under maintenance. We should be back shortly. Thank you for your patience.' Friday 23 August 13
  48. 48. 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 23 August 13
  49. 49. Basic scalar types from typed data boolean: label: 'Boolean' class: 'DrupalCoreTypedDataTypeBoolean' email: label: 'Email' class: 'DrupalCoreTypedDataTypeEmail' integer: label: 'Integer' class: 'DrupalCoreTypedDataTypeInteger' string: label: 'String' class: 'DrupalCoreTypedDataTypeString' uri: label: 'Uri' class: 'DrupalCoreTypedDataTypeUri' Friday 23 August 13
  50. 50. Basic data types for configuration undefined: label: 'Undefined' class: 'DrupalCoreConfigSchemaProperty' mapping: label: Mapping class: 'DrupalCoreConfigSchemaMapping' sequence: label: Sequence class: 'DrupalCoreConfigSchemaSequence' Friday 23 August 13
  51. 51. 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 Friday 23 August 13
  52. 52. 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 23 August 13
  53. 53. Config inspector module Friday 23 August 13
  54. 54. Context system, Events & Overrides Friday 23 August 13
  55. 55. global $conf; $conf['system.maintenance']['message'] = 'Sorry, our site is down now.'; Global overrides Friday 23 August 13
  56. 56. 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 23 August 13
  57. 57. 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 23 August 13
  58. 58. Get into contexts // Enter a user specific context. $context = config_context_enter("DrupaluserUserConfigContext"); // Set the account to use on the context. $context->setAccount($account); $mail_config = Drupal::config('user.mail'); // Do stuff... config_context_leave(); Friday 23 August 13
  59. 59. 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' Friday 23 August 13
  60. 60. 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 Friday 23 August 13
  61. 61. Please try it out! • #drupal-cmi - Dedicated IRC channel • docs - https://drupal.org/node/1667894 • help along - http://drupal.org/core-mentoring-hours Friday 23 August 13
  62. 62. • 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 23 August 13
  63. 63. Questions ? Friday 23 August 13
  64. 64. Thanks @heyrocker @webchick @moshe_weitzman @GaborHojtsy @alexpott Friday 23 August 13
  1. ¿Le ha llamado la atención una diapositiva en particular?

    Recortar diapositivas es una manera útil de recopilar información importante para consultarla más tarde.

×