Rethinking Drupal Configuration

MidCamp 2015

Scott Reynen

@scottr

aten.io

What I Did

  1. groups.drupal.org
  2. @font-your-face

What I Do Now

  1. Config in Code
  2. (Parenting)

Opinions are Cool!

1. Config is ... Everything

Saved Decisions

2. Config is not Interface

Fields are not Fields UI

Views are not Views UI

3. Interface is Important

Laziness is a Virtue

The Dark Ages

(Before Features)

Create
Read
Update
Delete
Browser UI
Create
Read
Update
Delete
Manage
Browser UI

1. Config is ... Everything

Features is

Good

Manage
Browser UI
Features
Create
Read
Update
Delete
Manage
Browser UI
Features

Features is

Not

Good

Enough

2. Config is not Interface

Create
Read
Update
Delete
Manage
Browser UI
Features

Drupal 8 Config is

Better

langcode: en
status: true
dependencies: {  }
name: 'Basic page'
type: page
description: 'Use basic pages for your static content, such as an ''About us'' page.'
help: ''
title_label: Title
settings:
  node:
    options:
      status: true
      promote: false
      sticky: false
      revision: false
    preview: 1
    submitted: false
Manage
Browser UI
Features
Drupal 8
Create
Read
Update
Delete
Manage
Browser UI
Features
Drupal 8

Drupal 8 Config is

Not

Better

Enough

3. Interface is Important

Core Interfaces are for Everyone

You're not Everyone

Custom Interfaces are Hard, Right?

No, Not Anymore

\Drupal::service('config.factory')->getEditable('node.type.page')
  ->set('type', 'page')
  ->set('name', 'Basic page')
  ->set('description', 'Use basic pages for your static content, such as an ''About us'' page.')
  ->save();

Easy!

Config in Code

(CINC)

drupal.org/project/cinc

CINC::init(‘ContentType’)->machine_name('page')
  ->set('name', 'Basic page')
  ->set('description', 'Use basic pages for your static content, such as an ''About us'' page.')
  ->create();

Easier!

$text_field = CINC::init('TextField')->machine_name('field_text')
  ->create();
CINC::init(‘ContentType’)->machine_name('page')
  ->add_field($text_field);

Easiest!

            uuid: b071f334-ec2e-40e3-a809-9d436780386e
langcode: en
status: true
dependencies:
  module:
    - node
    - user
id: content
label: Content
module: node
description: 'Find and manage content.'
tag: default
base_table: node
base_field: nid
core: 8.x
display:
  default:
    display_options:
      access:
        type: perm
        options:
          perm: 'access content overview'
      cache:
        type: none
      query:
        type: views_query
      exposed_form:
        type: basic
        options:
          submit_button: Filter
          reset_button: true
          reset_button_label: Reset
          exposed_sorts_label: 'Sort by'
          expose_sort_order: true
          sort_asc_label: Asc
          sort_desc_label: Desc
      pager:
        type: full
        options:
          items_per_page: 50
      style:
        type: table
        options:
          grouping: {  }
          row_class: ''
          default_row_class: true
          override: true
          sticky: true
          caption: ''
          summary: ''
          description: ''
          columns:
            node_bulk_form: node_bulk_form
            title: title
            type: type
            name: name
            status: status
            changed: changed
            edit_node: edit_node
            delete_node: delete_node
            dropbutton: dropbutton
            timestamp: title
          info:
            node_bulk_form:
              align: ''
              separator: ''
              empty_column: false
              responsive: ''
            title:
              sortable: true
              default_sort_order: asc
              align: ''
              separator: ''
              empty_column: false
              responsive: ''
            type:
              sortable: true
              default_sort_order: asc
              align: ''
              separator: ''
              empty_column: false
              responsive: ''
            name:
              sortable: false
              default_sort_order: asc
              align: ''
              separator: ''
              empty_column: false
              responsive: priority-low
            status:
              sortable: true
              default_sort_order: asc
              align: ''
              separator: ''
              empty_column: false
              responsive: ''
            changed:
              sortable: true
              default_sort_order: desc
              align: ''
              separator: ''
              empty_column: false
              responsive: priority-low
            edit_node:
              sortable: false
              default_sort_order: asc
              align: ''
              separator: ''
              empty_column: false
              responsive: ''
            delete_node:
              sortable: false
              default_sort_order: asc
              align: ''
              separator: ''
              empty_column: false
              responsive: ''
            dropbutton:
              sortable: false
              default_sort_order: asc
              align: ''
              separator: ''
              empty_column: false
              responsive: ''
            timestamp:
              sortable: false
              default_sort_order: asc
              align: ''
              separator: ''
              empty_column: false
              responsive: ''
          default: changed
          empty_table: true
      row:
        type: fields
      fields:
        node_bulk_form:
          id: node_bulk_form
          table: node
          field: node_bulk_form
          label: ''
          exclude: false
          alter:
            alter_text: false
          element_class: ''
          element_default_classes: true
          empty: ''
          hide_empty: false
          empty_zero: false
          hide_alter_empty: true
          plugin_id: node_bulk_form
          entity_type: node
        title:
          id: title
          table: node_field_data
          field: title
          label: Title
          exclude: false
          alter:
            alter_text: false
          element_class: ''
          element_default_classes: true
          empty: ''
          hide_empty: false
          empty_zero: false
          hide_alter_empty: true
          link_to_node: true
          plugin_id: node
          entity_type: node
          entity_field: title
        type:
          id: type
          table: node_field_data
          field: type
          label: 'Content Type'
          exclude: false
          alter:
            alter_text: false
          element_class: ''
          element_default_classes: true
          empty: ''
          hide_empty: false
          empty_zero: false
          hide_alter_empty: true
          link_to_node: false
          machine_name: ''
          plugin_id: node_type
          entity_type: node
          entity_field: type
        name:
          id: name
          table: users_field_data
          field: name
          relationship: uid
          label: Author
          exclude: false
          alter:
            alter_text: false
          element_class: ''
          element_default_classes: true
          empty: ''
          hide_empty: false
          empty_zero: false
          hide_alter_empty: true
          link_to_user: true
          overwrite_anonymous: false
          anonymous_text: ''
          format_username: true
          plugin_id: user_name
          entity_type: user
          entity_field: name
        status:
          id: status
          table: node_field_data
          field: status
          label: Status
          exclude: false
          alter:
            alter_text: false
          element_class: ''
          element_default_classes: true
          empty: ''
          hide_empty: false
          empty_zero: false
          hide_alter_empty: true
          type: published-notpublished
          type_custom_true: ''
          type_custom_false: ''
          not: false
          plugin_id: boolean
          entity_type: node
          entity_field: status
        changed:
          id: changed
          table: node_field_data
          field: changed
          label: Updated
          exclude: false
          alter:
            alter_text: false
          element_class: ''
          element_default_classes: true
          empty: ''
          hide_empty: false
          empty_zero: false
          hide_alter_empty: true
          date_format: short
          custom_date_format: ''
          timezone: ''
          plugin_id: date
          entity_type: node
          entity_field: changed
        operations:
          id: operations
          table: node
          field: operations
          relationship: none
          group_type: group
          admin_label: ''
          label: Operations
          exclude: false
          alter:
            alter_text: false
            text: ''
            make_link: false
            path: ''
            absolute: false
            external: false
            replace_spaces: false
            path_case: none
            trim_whitespace: false
            alt: ''
            rel: ''
            link_class: ''
            prefix: ''
            suffix: ''
            target: ''
            nl2br: false
            max_length: 0
            word_boundary: true
            ellipsis: true
            more_link: false
            more_link_text: ''
            more_link_path: ''
            strip_tags: false
            trim: false
            preserve_tags: ''
            html: false
          element_type: ''
          element_class: ''
          element_label_type: ''
          element_label_class: ''
          element_label_colon: true
          element_wrapper_type: ''
          element_wrapper_class: ''
          element_default_classes: true
          empty: ''
          hide_empty: false
          empty_zero: false
          hide_alter_empty: true
          destination: true
          plugin_id: entity_operations
      filters:
        status_extra:
          id: status_extra
          table: node_field_data
          field: status_extra
          operator: '='
          value: false
          plugin_id: node_status
          group: 1
          entity_type: node
        status:
          id: status
          table: node_field_data
          field: status
          relationship: none
          group_type: group
          admin_label: ''
          operator: '='
          value: true
          group: 1
          exposed: true
          expose:
            operator_id: ''
            label: Status
            description: ''
            use_operator: false
            operator: status_op
            identifier: status
            required: false
            remember: false
            multiple: false
            remember_roles:
              authenticated: authenticated
          is_grouped: true
          group_info:
            label: 'Published status'
            description: ''
            identifier: status
            optional: true
            widget: select
            multiple: false
            remember: false
            default_group: All
            default_group_multiple: {  }
            group_items:
              1:
                title: Published
                operator: '='
                value: '1'
              2:
                title: Unpublished
                operator: '='
                value: '0'
          plugin_id: boolean
          entity_type: node
          entity_field: status
        type:
          id: type
          table: node_field_data
          field: type
          relationship: none
          group_type: group
          admin_label: ''
          operator: in
          value: {  }
          group: 1
          exposed: true
          expose:
            operator_id: type_op
            label: Type
            description: ''
            use_operator: false
            operator: type_op
            identifier: type
            required: false
            remember: false
            multiple: false
            remember_roles:
              authenticated: authenticated
              anonymous: '0'
              administrator: '0'
            reduce: false
          is_grouped: false
          group_info:
            label: ''
            description: ''
            identifier: ''
            optional: true
            widget: select
            multiple: false
            remember: false
            default_group: All
            default_group_multiple: {  }
            group_items: {  }
          plugin_id: bundle
          entity_type: node
          entity_field: type
        title:
          id: title
          table: node_field_data
          field: title
          relationship: none
          group_type: group
          admin_label: ''
          operator: contains
          value: ''
          group: 1
          exposed: true
          expose:
            operator_id: title_op
            label: Title
            description: ''
            use_operator: false
            operator: title_op
            identifier: title
            required: false
            remember: false
            multiple: false
            remember_roles:
              authenticated: authenticated
              anonymous: '0'
              administrator: '0'
          is_grouped: false
          group_info:
            label: ''
            description: ''
            identifier: ''
            optional: true
            widget: select
            multiple: false
            remember: false
            default_group: All
            default_group_multiple: {  }
            group_items: {  }
          plugin_id: string
          entity_type: node
          entity_field: title
        langcode:
          id: langcode
          table: node_field_data
          field: langcode
          relationship: none
          group_type: group
          admin_label: ''
          operator: in
          value: {  }
          group: 1
          exposed: true
          expose:
            operator_id: langcode_op
            label: Language
            description: ''
            use_operator: false
            operator: langcode_op
            identifier: langcode
            required: false
            remember: false
            multiple: false
            remember_roles:
              authenticated: authenticated
              anonymous: '0'
              administrator: '0'
            reduce: false
          is_grouped: false
          group_info:
            label: ''
            description: ''
            identifier: ''
            optional: true
            widget: select
            multiple: false
            remember: false
            default_group: All
            default_group_multiple: {  }
            group_items: {  }
          plugin_id: language
          entity_type: node
          entity_field: langcode
      sorts: {  }
      title: Content
      empty:
        area_text_custom:
          id: area_text_custom
          table: views
          field: area_text_custom
          empty: true
          content: 'No content available.'
          plugin_id: text_custom
      arguments: {  }
      relationships:
        uid:
          id: uid
          table: node_field_data
          field: uid
          admin_label: author
          required: true
          plugin_id: standard
      show_admin_links: false
      filter_groups:
        operator: AND
        groups:
          1: AND
      display_extenders: {  }
    display_plugin: default
    display_title: Master
    id: default
    position: 0
  page_1:
    display_options:
      path: admin/content/node
      menu:
        type: 'default tab'
        title: Content
        description: ''
        menu_name: admin
        weight: -10
        context: ''
      tab_options:
        type: normal
        title: Content
        description: 'Find and manage content'
        menu_name: admin
        weight: -10
      display_extenders: {  }
    display_plugin: page
    display_title: Page
    id: page_1
    position: 1
          

YAML Views

So Easy!

CINC::init('View')->machine_name('random_instructor')
    ->set('human_name', 'Random Instructor')
    ->add_block_display()
    ->set_row_style('node')
    ->set_view_mode('teaser')
    ->add_filter('published')
    ->add_node_type_filter('instructor')
    ->limit_items(1)
    ->add_sort('random')
    ->create();

CINC Views

Sheet2Module

cinc.io

80% Less Time

on Content Types

Fast Content Type UI

1. Config is ... Everything

2. Config is not Interface

3. Interface is Important

Roll Your Own is

Best

Create
Read
Update
Delete
Manage
Browser UI
Features
Drupal 8
Roll Your Own

Feedback!

joind.in/13821

Twitter: @scottr

#MidCamp