Anatomy of a (terrific) Drupal 8 theme
The Bearskin 8 theme is built for Drupal 8 to streamline front-end development and add value for clients in the process.
Because Drupal 8 is brand new to everyone, we learn as we go, and implement best practices as they’re created. We’ve covered our bases with the available resources online (drupal.org, blog posts, code forums, internal discussions and code sharing), not to mention attending and presenting sessions at Drupal events.
With new systems, and specifically open source ones, best practices generally evolve rapidly, from experiment to consensus; patch to accepted contribution and solution to standard.
New does not have to be scary. It can also be exciting, and sometimes the hurdle is more about spreading this feeling, especially to clients.
But let’s be honest, Drupal for a front-end developer is far from a joy ride. Markup is barely accessible without knowing your preprocess functions, or by adding contributed modules that will help you do that through the UI. You add more weight to the code base and often have to export settings through features. That’s just the beginning. You see where I am going with this? Configuration management clusters, database synchronisation requirements, code maintainability conflicts across teams, and so on.
The good news is that Drupal 8 enables a front-end developer to separate the theme layer in a way that makes sense, maintaining autonomy while leveraging parts of site building that a front end developer should control.
Hell, we may see the emergence of a new breed of Drupalers. We can call them the Templaters.
Site builders out there: dive into TWIG if you have not done so already! Need convincing? Here are highlights:
- Component based approach to templating though specific inheritance functions (includes, extends and embeds) Increased security (default secure HTML output) Powerful, expressive (semantic) template language; easy syntax coupled with great features
- Front-end devs in charge of markup without having to dive into PHP preprocess functions or rely on back-end devs
- Integration (Pattern Lab)
- Easy to debug (devel, kint) and well documented
- Avoids Panels; build and register your own layouts; uses TWIG for the logic and Display Suite for UI management
How can we be sure that the path to develop Bear Skin was the right one?
We developed our early version of the Bear Skin theme for D8 prior to the official release. For that first attempt, we basically just ported our existing D7 theme layer.
While it worked, we quickly realized that we were not taking advantage of the new configuration under the hood in D8. In parallel we were experiencing difficulties in streamlining our design/wireframe/prototype/development process.
A robust website is composed (or at least should be, by modern standards) of more than 70% reusable components. The code base is smaller and more flexible, because the architecture relies on elements that can be reused throughout instead of being replicated in various contexts.
We had integrated an atomic design approach to our flow and defined our comprehensive hierarchy of the web components we usually use, but we weren’t quite sure how it could effectively translate to a Drupal build. Welcome Pattern Lab! Originally written for mustache, it was quick to be adapted for TWIG and guess what, TWIG is our new friend.
We studied, asked questions, researched, stole, shared, listened and were able to narrow down our conceptions on what was right (for us, that is). Many shops/people developed this concept early on and helped confirm the proper approach, each with their own variations (phase2, Forum One, Aleksi Peebles and John Albin with Zen).
How about a living styleguide that serves as the source for our Drupal theme layer?
We built a styleguide, defined our atoms, created the templates (TWIG), wrote our styles and eventually told Drupal to use (and reuse) them. It’s not sorcery, and seeing many Drupal shops and developers working in this direction made us feel comfortable investing the time to go further.
Afraid of templates? Don’t be. D7 gave them a bad reputation, but let’s move on! The problem is in defining a solid front-end architecture so that a site does not get over-templated. And let’s remember that everything is already templated by default. So why not have these templates at hand, living comfortably in a style guide where you have access to all of them at a glance, organized within a hierarchy you or your team have defined?
This is not only an improvement in output and scalability, but it also respects that this workflow forces us to implement good practices, and Pattern Lab has become our safeguard during the front end planning and implementation.
Let’s Dive in, Shall we?
https://www.drupal.org/project/bear_skinhttps://github.com/zivtech/bear_skin/tree/8.x-2.xhttps://www.drupal.org/project/bear_skin/releases/8.x-2.x-dev
Here is what our root looks like:
/bear_skin|-- README.md|-- backstop.json|-- bear_skin.breakpoints.yml|-- bear_skin.info.yml|-- bear_skin.layouts.yml|-- bear_skin.libraries.yml|-- bear_skin.theme|-- bin|-- bower.json|-- components|-- config|-- css|-- default.gulpfile.yml|-- docs|-- favicon.ico|-- fonts|-- gulp-tasks|-- gulpfile.js|-- gulpfile.yml|-- images|-- js|-- logo.png|-- logo.svg|-- node_modules|-- out.txt|-- package.json|-- pattern-lab|-- screenshot.png|-- templates|-- theme-settings.php
For those familiar with a D8 theme, Bear Skin includes the following:
- a .info file for meta-data about your theme (bear_skin.info.yml)
- a libraries file for defining all of your asset libraries (bear_skin.libraries.yml)
- a breakpoints config file (bear_skin.breakpoints.yml)
- a .theme file for conditional logic, preprocessing, and basic theme settings (bear_skin.theme)
- a theme-settings.php file for modifying the theme settings form (theme-settings.php)
- a logo file (logo.png)
- a favicon file (favicon.ico)
- a screenshot file that is shown on the Appearance page (screenshot.png)
- a typical theme folder structure that includes directories for css, .js, templates, images, and fonts
In addition, our setup also includes:
- a bin directory for shell script on post install
- a component dir (we will go into detail about this one later in this post)
- a config dir that sets up default settings when installing the theme, such as block placement and theme settings
- a docs dir that details the steps to install and use the theme
- a gulp task dir (usually a gulp file) to componentize and separate tasks for better (re)-usability. Our gulpfile.js calls for all these submodules
- a pattern-lab dir that contains config files for pattern lab
- a .bowerrc file that contains a path for bower to install dependencies
- .sass-lint and .eslintrc contain the default settings for our javascript and sass linting tasks
- a backstop.json file that contains the config for our css regression tests
- a layouts.yml file that registers templates used by the layouts modules and display suite
- a default.gulpfile.yml file (to be copied as a gulpfile.yml) that configures the various options for browsersync, pattern-lab, paths and more
- a package.json file that contains our NPM packages dependencies
/bear_skin/components|-- _annotations|-- _data|-- _layouts|-- _macros|-- _meta|-- _patterns| |-- 0-Atomic-Design-Plan| |-- 00-utilities| |-- 01-atoms| |-- 02-molecules| | |-- banner| | |-- banner-with-page-title| | |-- blocks| | |-- comments| | |-- messages| | | |-- _messages.scss| | | |-- messages.json| | | |-- messages.twig| | | |-- messages~error.json| | | |-- messages~warning.json| | |-- navigation| |-- 03-organisms| |-- 04-layouts| |-- 05-pages|-- _twig-components|-- bear_skin.scss
What we did here is organize our components using the atomic design concept, and each of them has a directory containing a .twig, .json and .scss file. We also included a yeoman script to facilitate generating components.
The .twig file is our reusable template. It is going to be picked by pattern lab (Drupal only reads html.twig files).
The .json will add static data with either strings or includes from other patterns.
The .scss file will be the stylesheet for this component (only). Additional .yml or .md files can be added to display different types of information about the pattern.
The additional .json files with the ~ symbol are duplicating the component with different data provided by the json code. This is useful if you don’t want to create many TWIG files that have the same purpose but different data attributes, for instance.
The next step is to include, embed or extend this template on the Drupal side with a .html.twig file, which will get picked up by the Drupal twig engine system. This is also the place to add some Drupal specific data attributes (if needed) or specify which part of the twig component you wish to override.
We place these in the “templates” directory, following the same atomic structure.
/bear_skin/templates|-- 01-atoms|-- 02-molecules| |-- block--main-search.html.twig| |-- block--system-branding-block.html.twig| |-- block--system-menu-block.html.twig| |-- block.html.twig| |-- breadcrumb.html.twig| |-- details.html.twig| |-- form.html.twig| |-- menu-local-tasks.html.twig| |-- menu.html.twig| |-- pager.html.twig| |-- status-messages.html.twig|-- 03-organisms|-- 04-layouts|-- 05-pages|-- html.html.twig
This model basically follows the MVP architectural pattern, which helps separate concerns between logic and presentation. In our case the data model is Drupal, the presenter is our native twig files in Pattern Lab, and finally the passive view is the drupal templates.
Let’s discuss the massive advantages of doing things this way.
- A style guide organized with these principles essentially becomes a comprehensive map for all developers working on the project, and clients alike.
- Front end developers have much more control over the markup (structure, classes, other data attributes etc).
- The front end developer does not need to wait to be handed the site once back end devs are done with a build. Development can be conducted in a parallel process.
- Prototype: the living styleguide can easily become a way for you to prototype components or pages for your clients.
- The site is prepared for scalability: a living styleguide approach enables us (and forces us) to consider how reusable each new component may be, and where it falls in our overall front end architecture.
- We style once, we build once: CSS and templates are shared between Pattern Lab and Drupal.
- Components: when styling, separating components helps avoiding over-nesting the Sass. We just don’t dump the CSS in a large files that already have one, two, or three parent selectors. We end up with more manageable and clean code.
- We minimize the code output. One template can serve many pieces of content when reused, with or without a modifier.
Nothing is set in stone and we are likely to see this process evolve further, but these are great improvements over D7 and reasons to get excited about D8 builds. As a team it allows our vision about front end architecture and development to come to life, but also expands it as we keep discovering ways to streamline a shared development environment and offer our clients solutions that fit them best.
Get started: DOWNLOAD the theme, follow the docs and see for yourself!
Read more about Pattern Lab, Drupal, Browsersync and Regression Testing.
Special thanks to James Cole, Sean Wolfe and Stephanie Semerville for building this along with me. It’s a labor of love that accepts your contributions as well :) Found a bug? send your pull requests over here.