Moving from theming in Drupal 7 to Drupal 8? Overview of key changes

Drupal 8 represents some major changes to the way we work with themes. There is now Twig, asset libraries, component based CSS, to name a few of the changes. If you are used to working with themes in Drupal 7, all these changes can be overwhelming. But it is well worth the effort - building themes in Drupal 8 is a much improved experience.

Over the course of the coming weeks and months, I’ll be sharing tutorials specifically on Drupal 8 theming to help you get over the learning curve. In this first post, I’m exploring some of the key changes in Drupal 8.

Theme location

You can store your theme in three different locations in your code base in Drupal 8:

  • themes
  • sites/all/themes
  • sites/(site name)/themes

If you are running a multi-site, you’d create your theme in sites/(site name)/themes , with (site name) being the name of the site. Otherwise, the recommended approach is to put your theme in the themes folder.

Compared to Drupal 7

In Drupal 7, the themes folder was reserved for core themes. As such, custom and contributed themes should not be stored there. In Drupal 8, core themes have been moved to the /core folder.

THEMENAME.info.yml

This is where you keep meta-data and settings for the theme. The name of this file should match the name of the theme. This is the only required file in a theme in Drupal 8 and a theme cannot exist without this file.

Here is an example of a simple .info.yml file:

name: Responsive Skeleton
type: theme
description: 'Responsive, mobile friendly base theme based on Skeleton'
package: Core
core: 8.x
libraries:
  - responsive_skeleton/global-styling
regions:
  header: Header
  highlighted: Highlighted
  help:  Help
  content: Content
  sidebar_first: 'Left sidebar'
  sidebar_second: 'Right sidebar'
  footer: Footer

If you’d like to learn more about YAML files, check out my introduction to YAML in Drupal 8.

Compared to Drupal 7

In Drupal 7, this file would be called THEMENAME.info. A lot of the information would be the same but it would be in the INI format rather than YAML. If you have done any Drupal 7 development, the information will look familiar to the above snippet. One of the key differences between Drupal 7 and 8 is that the key value pair are separated with an equals sign (“=“) in the INI format used in Drupal 7, and colon (“:”) in the YAML format used in Drupal 8. There needs to be a space after the colon.

THEMENAME.theme

This is a PHP file used for additional logic (that should not be in template files) and preprocessing variables for templates.

Compared to Drupal 7

In Drupal 7, this file would be called template.php. A lot of the hooks, such as hook_preprocess, are the same (and some have been removed). The change of name from template.php to THEMENAME.theme brings it inline with the naming of module files (MODULENAME.module).

Templates

Templates provide the HTML structure for the site. Drupal 8 uses the Twig theme engine.

Example template files:

  • block.html.twig
  • comment.html.twig
  • node.html.twig
  • page.html.twig

Example twig file (block.html.twig):

{%
  set classes = [
    'block',
    'block-' ~ configuration.provider|clean_class,
    'block-' ~ plugin_id|clean_class,
  ]
%}
<div{{ attributes.addClass(classes) }}>
  {{ title_prefix }}
  {% if label %}
    <h2{{ title_attributes }}>{{ label }}</h2>
  {% endif %}
  {{ title_suffix }}
  {% block content %}
    <div{{ content_attributes.addClass('content') }}>
      {{ content }}
    </div>
  {% endblock %}
</div>

Compared to Drupal 7

The default theme engine in Drupal 7 is PHPTemplate. The templates in Drupal 7 included PHP code. There is no PHP code in the Twig templates in Drupal 8. Twig brings many advantages over PHPTemplate including enhanced security and inheritance.

/css/

This folder contains your theme’s CSS files. In Drupal 8 there is a recommended best practice for how you architect your CSS files that should be followed, which is based on SMACSS and BEM. This helps to create CSS that is reusable (components that can be reused multiple times), maintainable and scalable.

Here is an example for a really simple theme:

css
|- base/
|—- elements.css
|- components/
|—- block.css
|—- breadcrumb.css
|—- buttons.css
|—- header.css
|—- node.css
|—- table.css
|—- views.css
|— colors.css
|- layout.css
|- print.css

The files in the components are small self-contained chunks.

In order for your Drupal site to use the CSS files, they should be listed in THEMENAME.libraries.yml (see below).

THEMENAME.libraries.yml

This file contains a list of CSS and JS libraries to use in your theme.

Here is an example of adding CSS files in a theme’s .libraries.yml file:

libraryname:
  css:
    theme:
      css/style.css: {}
      css/print.css: { media: print }

You can also load CSS files only when needed, rather than for every page in the site. In the following example, node.css is loaded on node pages only.

libraryname:
  css:
    theme:
      css/style.css: {}
      css/print.css: { media: print }

node:
  css:
    theme:
      css/node.css: {}

THEMENAME.breakpoints.yml

Used to define responsive breakpoints for your theme.

Wrapping up

Moving from PHPTemplate to Twig, INI format to YAML, new CSS architecture and managing CSS and Javascript as library assets are some of the main changes in theming in Drupal 8. These changes have improved security and inheritance and made theming more elegant. I’ll be sharing a lot more about each of these in the coming weeks and months! If you’d like to be first to get them, jump on my newsletter list.

Add new comment