The future of
Drupal Theming

By yours truly

Yours truly

Job: Being fabulous

Analysis

The problem

The dream

 

Contents

Backend analysis

How does one measure complexity?

34580 files in total

Drupal Core

Libraries

Custom code

Vendor

Contrib modules

12282

350

842

14556

6550

How do we backend?

Drupal Core

Libraries

Custom code

Vendor

Contrib modules

5%

Frontend analysis

How do we frontend?

Content (HTML)

Appearance (CSS)

Behaviour (JS)

How do we frontend?

Content (HTML)

Appearance (CSS)

Behaviour (JS)

96%

Drupal-supplied

Frontend

often not frontend performance-tuned,

limited scalability,

questionable readability,

always project-specific,

often poorly accessible,

hardly share-able

code that only one person knows about

Independent,

themed, functional,

cutting edge,

Drupal Front-end

components

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

Thank you for listening

Open-sourced: The future of Drupal theming

By Mathieu Spillebeen