I want you to write…a theme.
Drupal is so highly customizable that developing a custom Drupal theme can be a challenging — and even daunting — undertaking. In response to the fairly recent release of Drupal 8, we’ve decided to write a series of posts dedicated to breaking down the changes from Drupal 7 to 8 in an easy-to-follow, step-by-step, “we’re-all-in-this-together” sort of way. We hope that you both enjoy and benefit from our research into the intricacies of Drupal 8 theming and, if you have any questions, please feel free to contact us.
With that said, kindly cue the Mortal Kombat music because:
IT HAS BEGUN!!
Quick Pointers to Remember
The use of the tab key for indentation is not allowed when writing a YAML file, so you need to use spaces instead. YAML files only require a one space indentation, but Drupal’s coding standards call for two, so definitely use two.
Every time you make a change to one of your theme files, there’s a solid chance it won’t be apparent until you’ve cleared and rebuilt your cache. To do this, you can do one of the following:
From the Admin area, go to the ‘Configuration’ page, then in the ‘Development’ section select ‘Performance’, and click the ‘Clear all caches’ button.
If you’re using Drush, you can simply type ‘drush cr’, which is short for ‘drush cache-rebuild’.
Alternately (and perhaps more sensibly), rather than spending your every waking moment rebuilding your caches, it’s advisable to disable caching during development.
The directory structure in Drupal 8 differs a little (and in my opinion is more intuitive) than that of Drupal 7. Rather than placing our custom themes in the ‘sites’ directory, they will instead live in the ‘themes’ folder found in the root of Drupal 8. But wait, there’s more! To distinguish our custom themes from contributed themes (contrib) available for download on drupal.org, we need to create a custom folder, called ‘custom’, to house our creations.
The Info File
In Drupal 8, the ‘.info.yml’ file replaces the ‘.info’ file of Drupal 7. The proper naming convention for the .info.yml file is ‘theme_name.info.yml’, so I’ll call mine ‘example.info.yml’. The .info.yml file lives in the root of your custom theme folder. The name of the file needs to correspond to the name of your theme’s folder, which is why mine is named example.info.yml. If your theme name contains spaces, use underscores to replace them.
There are four required components, or ‘mappings’, for the .info.yml file. Mappings are simply key:value pairs that provide Drupal with the necessary info to get your theme up and running.
The required mappings are ‘name’, ‘description’, ‘type’, and ‘core’.
The value of the ‘name’ key is the human-readable name of your theme, which will appear on the Theme’s settings page. Mine is ‘Example’. If your theme name includes spaces, it’s the same deal as when naming your .info.yml file–just replace the spaces with underscores.
The description key is self-explanatory. All Drupal is looking for here is a brief description of your theme that can be supplied to potential users on the ‘Appearance’ page. My description value simply states, “An example theme for learnin’ ya.”–short and sweet.
For the ‘type’ key, Drupal just wants to know what this .info.yml file is describing. In this case, we’re providing information about a theme, so the value for the type key is ‘theme’. If we were describing a module, the value for type would be ‘module’ and so forth.
Core is just asking what version of the Drupal installation we’re rocking. Since we’re hip and savvy developers, we’re using Drupal 8, and thus our ‘core’ key value should be 8.x. Magnifique.
In addition to those four required mappings, there are a number of other mapping key:value pairs we might include to give our theme a little more depth. Let’s discuss, shall we?
Setting a base theme (parent) allows your custom sub-theme (child) to inherit the base theme’s resources (styles, scripts, and templates). For a no-frills base theme, go with Stable. For a classier theme with more built-in styles, check out Drupal 8’s new theme ‘Classy’, which Bartik is now based off of.
Along with the name of your theme and the description you provide, the screenshot for your theme will be featured on the ‘Appearance’ page. Best-practices dictates that you should use a screenshot of your theme; add the screenshot to your theme’s root directory, and reference it as the value of the ‘screenshot’ key. Personally for my Example theme, I went with an illustration of some amorous cuttlefish because I enjoy a nice cephalopod.
For the ‘regions’ key, we’ve got some choices to make. If you opt not to specify regions in your sub-theme, then Drupal’s default regions will be applied. On the other hand, if you will be defining your own regions, technically the only one that requires specification is the ‘content’ region.
However, it is SO important to note that if you manually define any regions in your custom theme, then none of Drupal’s default regions will be applied and you’ll assume sole responsibility for declaring all of the regions you want. In addition, you’ll need to create your own pages.html.twig file with your regions defined in order to override your base theme’s pages.html.twig template.
Create a library
It’s important to note that when you include libraries in your .info.yml file, as we’ll be doing next, a link to the stylesheet will be added to the <head> automatically, but the css file being called will not be generated automatically. So, to avoid any issues, you need to be sure to add that file to the specified path manually.
To make use the library we’ve just created in the .libraries.yml file, we need to reference it in the .info.yml file. We do this by using the ‘libraries’ key, then on the next line we indent two spaces and add the name of the theme, a slash, and the name of the library, all of which is preceded by a dash. Observe:
The ‘libraries-extend’ key offers a way to alter library assets by adding theme-dependent library assets when a library is attached. This feature comes in handy when you want to style certain theme components of your site differently without having to alter your global CSS.
For a more detailed explanation of overriding and extending libraries, complete with multiple examples, check out the official Drupal 8 theming guide.
Specifying styles by page
The Theme File
At this juncture, I feel like the naming convention for our new file is pretty evident, but in the interest of really driving the point home we’ll be naming our .theme file after our theme. Kindly hold you applause as I dub mine ‘example.theme’.
In the .theme file, we’ll add this preprocess function indicating that we only want to attach our library to the front page
Obviously, there is a lot more that goes into fully developing a Drupal theme, but what we’ve just created is technically a theme that could be enabled on a Drupal 8 site. I’ll be covering more topics related to Drupal 8 theming in future blog posts, so check back soon or follow Bōwst on Facebook or Twitter. Better yet, maybe come to one of the Seacoast Drupal User Group meetings we host on the first Thursday of every month, and let’s discuss Drupal 8 theming in person. Worst case scenario, you get free pizza and beer.
What’s the Diff?: Key Differences in Drupal 8 in a nutshell*
Custom theme files are now located in the ‘theme’ directory within the ‘custom’ directory, rather than the ‘sites’ directory.
The ‘.info.yml’ file has replaced Drupal 7’s ‘.info’ file.
CSS structuring and class-naming is now based on SMACSS.
The Twig templating engine has replaced PHP template as the default templating engine of Drupal 7.
*I want you to know that the temptation to make a bad “No, this is Drupal in a nutshell” joke was very nearly overwhelming. For your benefit I resisted…you’re welcome.
Click here for the next post in this series.