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

1,348 views

Published on

Session given at Drupalaton 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
1,348
On SlideShare
0
From Embeds
0
Number of Embeds
33
Actions
Shares
0
Downloads
25
Comments
0
Likes
4
Embeds 0
No embeds

No notes for slide

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

  1. 1. Drupal 8 Configuration system for coders and site builders Friday 16 August 13
  2. 2. who are we? Kristof De Jaeger @swentel co-maintainer of Field API Lead maintainer of Display Suite Developer @ Wunderkraut Friday 16 August 13
  3. 3. who are we? Gábor Hojtsy @gaborhojtsy Multilingual Initiative owner Long time Drupal Core contributor Number one employee @ Acquia Friday 16 August 13
  4. 4. Stop serving me Palinka Friday 16 August 13
  5. 5. Ok, maybe one ... Friday 16 August 13
  6. 6. 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 16 August 13
  7. 7. 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 16 August 13
  8. 8. 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
  9. 9. Friday 16 August 13
  10. 10. The solution • Files using theYAML specification • Active and staging directory • Cached in the database using a standard cache interface Friday 16 August 13
  11. 11. The anatomy of a configuration file Friday 16 August 13
  12. 12. system.site.yml Friday 16 August 13
  13. 13. system.site.yml Friday 16 August 13
  14. 14. system.site.yml Friday 16 August 13
  15. 15. name: 'Configuration management' mail: admin@example.com slogan: 'makes Drupal 8 cex -y' page: 403: '' 404: '' front: node system.site.yml Friday 16 August 13
  16. 16. The API Drupal::config() ->get() ->set() ->save() Friday 16 August 13
  17. 17. Accessing data Friday 16 August 13
  18. 18. 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 16 August 13
  19. 19. $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 16 August 13
  20. 20. $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 16 August 13
  21. 21. $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 16 August 13
  22. 22. Saving data Friday 16 August 13
  23. 23. 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 16 August 13
  24. 24. 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 16 August 13
  25. 25. Friday 16 August 13
  26. 26. • 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
  27. 27. {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
  28. 28. Config all the things! Friday 16 August 13
  29. 29. Config entities Friday 16 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 = "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 16 August 13
  31. 31. 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 16 August 13
  32. 32. 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 16 August 13
  33. 33. 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 16 August 13
  34. 34. */ 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
  35. 35. id: feedback uuid: de77e4f3-f94b-41a5-ad05-5c32fa08444f label: 'Website feedback' recipients: - '' reply: '' weight: '0' langcode: und contact.category.feedback.yml Friday 16 August 13
  36. 36. (config) entity API • entity_load • entity_save • $object->any_method() Friday 16 August 13
  37. 37. Deployment Friday 16 August 13
  38. 38. Database Development environment Active Directory 1 Friday 16 August 13
  39. 39. Database Development environment Active Directory 1 Friday 16 August 13
  40. 40. Database Development environment Active Directory 1 2 Friday 16 August 13
  41. 41. Database Production environment Staging Directory Active Directory 3 admin/config/development/sync Friday 16 August 13
  42. 42. Database Production environment Staging Directory Active Directory 3 4 admin/config/development/sync Friday 16 August 13
  43. 43. Demo time • No partial imports ! Friday 16 August 13
  44. 44. Advanced workflows • https://drupal.org/sandbox/dereine/2057465 Friday 16 August 13
  45. 45. Don’t hack core Friday 16 August 13
  46. 46. Don’t hack active config Friday 16 August 13
  47. 47. 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
  48. 48. Drush integration Friday 16 August 13
  49. 49. Context system, Events & Overrides Friday 16 August 13
  50. 50. global $conf; $conf['system.maintenance']['message'] = 'Sorry, our site is down now.'; Global overrides Friday 16 August 13
  51. 51. 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
  52. 52. 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
  53. 53. 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 = config('user.mail'); // Do stuff... config_context_leave(); Friday 16 August 13
  54. 54. 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 16 August 13
  55. 55. Configuration schema Friday 16 August 13
  56. 56. 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
  57. 57. 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
  58. 58. 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 16 August 13
  59. 59. Basic data types for configuration undefined: label: 'Undefined' class: 'DrupalCoreConfigSchemaProperty' mapping: label: Mapping class: 'DrupalCoreConfigSchemaMapping' sequence: label: Sequence class: 'DrupalCoreConfigSchemaSequence' Friday 16 August 13
  60. 60. 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 path path: 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
  61. 61. 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
  62. 62. 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
  63. 63. What does all this add up to? $definition = Drupal::typedData()->getDefinition('system.maintenance'); array( 'label' => "Maintenance mode", 'class' => "DrupalCoreConfigSchemaMapping", '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
  64. 64. Config inspector module Friday 16 August 13
  65. 65. Advice for module developers • Config key names should have meaning • Use config entities instead of tables • Include config schema Friday 16 August 13
  66. 66. • 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
  67. 67. Thanks @heyrocker @webchick @moshe_weitzman @GaborHojtsy @alexpott Friday 16 August 13

×