The future of
Drupal Theming

By Mathieu Spillebeen

API-first edition

Mathieu Spillebeen

@MathieuSpil

mathieu.spillebeen@gmail.com

Frontend United.org

Compony.io

Freelance Drupal Frontend developer

Making myself unpopular

Hopefully fixing it again

Contents

Time

Expectations

New technology

Peak of expectations

Disillusionment

Slow enlightenment

Plateau of productivity

Time

Expectations

Mobile-first

Mobile-only 

Expensive, complex,

only edge cases

Responsive!

Mobile-focus

Time

Expectations

API-first?

API-only! Headless! 

Expensive, complex drupalisms

Data-structure mangling,

=> Only edge cases

Progressive decoup!ing

API-powered components

Decouple

interactive

Decouple

Decouple

Decouple

Independent, reusable

themed, functional,

cutting edge,

Drupal Front-end

components

that YOU can decouple

That's the dream

New theme structure

Platform
to share

 compony.io

{

{

The compony theme

Tooling workflow

The new theme structure

How?

_sass-essentials

my-theme

components

my-theme.info.yml

my-theme.libraries.yml

my-theme.theme

How?

_sass-essentials

my-theme

components

my-theme.info.yml

my-theme.libraries.yml

my-theme.theme

_global

node

status-messages

How?

_sass-essentials

my-theme

components

my-theme.info.yml

my-theme.libraries.yml

my-theme.theme

_mixins.scss

_variables.scss

sass-essentials.scss

How?

status-messages

dist

libraries.yml

smile.svg

status-messages.html.twig

smile.svg

status-messages.css

status-messages.js

status-messages.js

status-messages.scss

How?

status-messages:
  version: VERSION
  css:
    component:
      dist/status-messages.css: {}
  js:
    dist/status-messages.js: {}

libraries.yml

libraries.yml

How?

{#
/**
 * Theme override for status messages.
 * ...
 */
#}

{{ attach_library('my-theme/status-messages') }}

<div role="alert" class="message message--error">  
  <h2>{{ status_headings[type] }}</h2>
  {{ messages }}
</div>

status-messages.html.twig

status-messages.html.twig

How?

How?

status-messages

dist

libraries.yml

smile.svg

status-messages.html.twig

smile.svg

status-messages.css

status-messages.js

status-messages.js

status-messages.scss

The new theme structure

Advantages

Conditional loading

Advantages

Views Infinite Scroll

components

_global

views-infinite-scroll-pager

page

views-infinite-scroll-pager.html.twig

libraries.yml

views-infinite-scroll-pager.css

Advantages

Maintainability

Advantages

/node/article/1

node--article.html.twig

node--article.js

/taxonomy-term/1

libraries.yml

node--article

Performance

Advantages

/node/1

/taxonomy-term/1

node

libraries.yml

node.css

node.html.twig

/node/1

/taxonomy-term/1

page

libraries.yml

page.css

page.html.twig

{

/any-page

1 in 10 of your CSS/JS

Flexibility

Advantages

brick:
  version: VERSION
  css:
    component:
      brick.css: {}

brick

libraries.yml

.brick {
  width: 100%;
  padding: 2rem;
}

CSS-only

brick.css

Advantages

{{ attach_library('my-theme/brick') }}
<div class="brick">

  {{ attach_library('my-theme/messages') }}
  <div class="messages">
    {{ content }}
  </div>

</div>

node--article

node--article.html.twig

HTML-only

Advantages

modal:
  version: VERSION
  js:
    modal.js: {}
(function () {
  Drupal.behaviors.submitFormLoader = {
    attach: function (context, settings) {...}
  };
})();

JS-only

libraries

libraries.yml

modal.js

Advantages

... and loads more

Advantages

Advantages

Never start over again

Readable to non-Drupal people

Experiment on tiny parts, not on everything

New theme structure

Tooling workflow

New tooling workflow

How?

_sass-essentials

my-theme

components

my-theme.info.yml

my-theme.libraries.yml

my-theme.theme

gulpfile.js

How?

_sass-essentials

my-theme

components

my-theme.info.yml

my-theme.libraries.yml

my-theme.theme

gulpfile.js

How?

.nvmrc

package.json

package-lock.json

yarn.lock

Configurable

How?

  • project-specific
  • environment-specific

 

module.exports = {
  gulpthemes: [
    {
      path: 'web/themes/compony',
      with_styleguide: false
    },
  ],
  features: {
    autoprefixer: {
      enable: true,
      options: {
        browsers: ['last 2 versions', 'ie 9', '> 0.2%'],
        cascade: false
      },
    },
    browserify: {
      enable: true,
      debug_mode: false,
    },
    clean_css: {
      enable: false,
    },
    css_mapping: {
      enable: false,
    },
    image_optimise: {
      enable: true,
      gifsicle: {
        interlaced: true,
        optimizationLevel: 3
      },
      optipng: {
        optimizationLevel: 5
      },
      jpegtran: {
        progressive: true
      },
      svgo: {
        plugins: [
          {
            removeViewBox: false
          },
          {
            removeDimensions: true
          }
        ]
      }
    },
    sass_includes: {
      bourbon: false,
      bourbonNeat: false,
      breakpoint: false
    },
    // Deprecated
    kss: {
      enable: false,
    },
  },
};

project.config.js

How?

module.exports = {
  features: {
    auto_rebuild_drupal_cache: {
      enable: false,
      cache_rebuild_command: 'drush cr'
    },
    browsersync: {
      enable: false,
      localhost_url: "https://local.dev/"
    },
    validate_yml: {
      enable: true,
    },
    lint_php: {
      enable: true,
    },
    lint_html: {
      enable: false,
    }
  },
  notifications: {
    html: {
      linting_errors: false,
    },
    css: {
      sass_errors: true
    },
    javascript: {
      browserify_errors: true,
      uglify_errors: true,
    },
    yml: {
      validation_errors: true,
    },
    php: {
      linting_errors: true,
    },
    internal: {
      cache_rebuilding_status: true,
      cache_rebuild_error: true,
    }
  }
};

local.config.js

How?

New tooling workflow

Advantages

Easy setup

Advantages

$ npm install

$ gulp

core

gulpfile.js

config.js

index.js

local.config.js

project.config.js

Command line

Advantages

Sass compiling

Advantages

.message {
  background: url('smile.svg');
}
.message {
  background: url('../../../images/smile.svg');
}

status-messages

dist

libraries.yml

smile.svg

smile.svg

status-messages.css

status-messages.scss

Advantages

Autoprefixer

Advantages

Advantages

Lossless image optimisation

Advantages

Advantages

Browsersync

Advantages

Linting

Advantages

Advantages

JS uglification

Advantages

Uglification

Aggregation

+

Advantages

Babelify & Browserify

Advantages

Treeshaking

Advantages

Component-based,
multi-theme compiling

Advantages

node

libraries.yml

node.css

node.html.twig

page

libraries.yml

page.css

page.html.twig

components

Advantages

_sass-essentials

my-theme

components

my-theme.info.yml

my-theme.libraries.yml

my-theme.theme

gulpfile.js

Advantages

module.exports = {
  options: {
    ...
    gulpthemes: [
      {
        path: 'themes/custom/my-first-theme',
      },
      {
        path: 'themes/custom/my-second-theme',
      },
    ]
  },
};

project.config.js

Advantages

Advantages

partials

_partial-a.js

_partial-b.js

dist

example.js

example

libraries.yml

example.js

Advantages

dist

example.js

example

libraries.yml

example.js

some-library.min.js

Advantages

_scss-partials

_regions.scss

_utilities.scss

dist

style.css

_global

libraries.yml

style.scss

Advantages

dist

menu.css

menu

libraries.yml

menu.scss

menu__toggles.scss

menu__toggles.css

Rebuilding Drupal's Cache

Advantages

Advantages

Refactor friendly

Advantages

Advantages

Abstract only

when needed

Advantages

node

_global

node.html.twig

node.css

libraries.yml

node--article

node--article.html.twig

components

node

_global

node.html.twig

node.css

libraries.yml

node--article

node--article.html.twig

components

node

Advantages

node

_global

components

node

node--article

node--article-full

node--article--teaser

node--blog

node--blog--full

node--blog--teaser

... and loads more

Advantages

Browsersyncing,

Sass globbing,

Source mapping,

Cross-component variables & mixins

Auto-cleaning up empty directories,

Features as options.

Advantages

New theme structure

Platform
to share

Tooling workflow

New platform
to share

How?

Downloading

How?

Compony.io

Download theme-structure + tools

Download contributed components

How?

Drupal.org

Download Drupal core

Download contributed modules

How?

New platform
to share

Advantages

cross-projects

Drag and drop
 

-developers

-companies

Advantages

Project-agnostic components

Advantages

Strip project specific content

Strip color, fonts & variables

page

libraries.yml

my-component.scss

my-component.html.twig

components

Advantages

Share information
on components

Advantages

/node/article/1

compony.io/components/status-messages

Collaborate
on components

Advantages

Advantages

Advantages

Invent component variations

Advantages

Advantages

Advantages

(Still in development)

Component collections

Advantages

Advantages

Advantages

Community based enhancements

Advantages

Proud Drupal Frontend developer

Advantages

What is your node version.

Advantages

And lots more

Advantages

Component naming & nesting convention

Twig and hook extending conventions

Documentation on the 4 PHP functions

Version control of components

Advantages

it

Putting

together

Mathieu Spillebeen

@MathieuSpil

mathieu.spillebeen@gmail.com

frontendunited.org/get-involved

compony.io/social

Freelance Drupal Frontend developer

Thank you for listening

The future of Drupal theming: Decoupled focus

By Mathieu Spillebeen

The future of Drupal theming: Decoupled focus

Recording can be found here: https://www.youtube.com/watch?v=UrDcQUd_wL8&t=3s

  • 943