Special offer: Maintainable Software Worksheet and free 30-minute consultation! Download

Maintaining your Sanity while Theming in Drupal

by Alexandra Atzl

TL;DR

Over the past several months I've spent working on Drupal projects, I've learned that theming these sites can easily become a labyrinth of function overrides, template files, stylesheets, javascripts, images—everything but the kitchen sink.

So at Singlebrook, we've come up with a simple way to organize our theming files, and created a base "template" folder for new themes, packaging up the best of SASS, Modernizr, LiveReload, and sane file organization.

Our theme is meant to be a baseline that can be renamed and built upon, rather than a base theme for sub-themes to stem from. We can simply clone the base theme template repository into our new Drupal site, rename the folder and all theme functions/files, and voila! Ready to go.

Guard/LiveReload

One of the best aspects of this template is its use of Guard and LiveReload to compile our SCSS and JavaScript and reload our pages. Because we use Guard and LiveReload JavaScript, rather than the LiveReload browser add-on, there's a little more setup involved, and our base template takes care of that. (Note: Guard requires Ruby, and the easiest way to install it is using Bundler—this theme assumes you have both installed already.)

To start, our .info file defines a new variable, called dtt_enable_livereload (would be renamed based on whatever the theme name is changed to):

setting[dtt_enable_livereload] = false 

We then add this setting to our theme's settings page using a new file: theme-settings.php. This file has a single function call, which looks like this:

Basically, it adds to the default theme settings form provided by Drupal Core, and asks the user whether to enable LiveReload or not. Our .info file, by default, sets this value to false, but users in a development environment can turn it on to signal that they want to use LiveReload.

Our template.php file then handles the theme setting like so:

So, if dtt_enable_livereload is true, Drupal will pull in the LiveReload JavaScript file necessary for it to run, and will specify the host and port to use, with some other settings, so that it can run properly. Then when you update your SCSS or JavaScript files, the page will update automatically, without needing to refresh.

SCSS Structure

To keep everything as organized as possible, we created a system of folders for everything we might need in our theme. All our templates are stored in a templates folder (clever, huh?), and all other assets are in an assets folder.

Assets is divided into fonts, icons, images, javascripts, and stylesheets folders. Of course, not all of these are necessary for all projects, but our structure provides placeholders so that if/when you need to include icons or fonts in your theme, you can easily do so.

The Stylesheets folder is where things begin to get interesting. Our compiled CSS file lives here, along with a folder containing our SCSS structure, which contains the following folders:

  • 404
  • admin
  • base
  • basic
  • common
  • home
  • page
  • vendor
Our main style manifest, style.scss, also lives here.

This is the best way we've found to organize our SCSS at Singlebrook. A breakdown of what we include in each folder is explained below:

  • 404: Placeholder folder for handling 404 error page styling.
  • admin: Placeholder folder for all styling to override Drupal admin styles is placed. This is only applicable if you are using your theme on the admin side of your site as well as the public side.
  • base: This includes a variety of files with base styles that we need in order to style anything else. We have separate files for fonts, a grid, variables, mixins, responsive mixins, etc. And finally, we've also included _reset.scss and _normalize.scss, so that you can choose which you would prefer to use (NOT both). Our default is to use reset, and comment out the line including normalize.
  • basic: All our basic styling for site-wide elements is located here: fonts, typography, forms, and helper classes.
  • common: This folder holds all the common styles that will be reused across the site; header, footer, sidebars, etc. Depending on the project, we might have a separate sidebar.scss file here, or a separate navigation or mobile navigation file. It depends on how large and complex navigation might be, and how much else needs to be styled in the header file. Basically, if our scss files aren't overly large, we will combine things (like header and nav) a little more.
  • home: All our homepage styles. We usually start out with just a single file, and any more complex homepage-specific elements (such as a carousel) will generally have separate scss files.
  • page: All styling for basic pages, including layouts, sidebar placement, etc.
  • vendor: A folder for any vendor stylesheets.

Everything is made as a partial, and all included in style.scss. We also pull in Compass here, mostly for use of the cross-browser CSS3 mixins. This can also be commented out, depending on a project's needs.

I've also found it useful, depending on the project, to create a content-types folder, where I can keep a SCSS partial for each specific content type I have and its associated styles. This would be for projects with lots of types of content, rather than a project that only uses pages and articles, for example.

Templates

Our theme includes three template files to start with: html.tpl.php, node.tpl.php, and page.tpl.php. Our html template overrides the Drupal default and adds in some custom code. We pull in Modernizr, so that we have easy access to classes determining whether or not browser support for certain techniques is available. We also add a meta viewport tag, to ensure resizing on mobile devices, and add in placeholder apple touch icons, for when users create bookmarks on their phones.

Our page template doesn't change much from the core Drupal page template, with the exception of utilizing HTML5 elements. We use header, footer, and nav tags; asides for our sidebars; sections for large content areas, etc. We also use articles in our node.tpl.php to contain the markup, so that our pages are more semantic.

You can view our template on Github here. We only used this template on a few projects so far, but it's been a great help, and we've already been able to build upon it to cover different types of projects and things that might come up. How do you tend to organize your files when theming a Drupal site?