Posted on

Evolving Web: How to Have Your Drupal 7 Theme Ready for Drupal 9

If you develop for Drupal 9, you probably noticed that theming has improved a lot. And if you’re upgrading your theme to D9, given Drupal 7’s upcoming end of life in November 2022, you’ll find the job considerably easier if you follow some basic but crucial steps.

Let’s look at the main theming features on Drupal 9 and how to have your Drupal 7 theme ready for this latest version of Drupal.

👩‍💻 Want to dig deeper into themes? Enroll in our Advanced Drupal Theming training!

Drupal 9’s Main Theming Features

Drupal 9 has many features that make life easier for anyone who wants to upgrade their theme. Here are some of them:

Semantic HTML5 markup by default
Improved out-of-the-box accessibility features
Use of Twig as the theme engine instead of PHPTemplate
Previous theme_* functions and *.tpl.php files replaced by *.html.twig files
Default performance-enhancing features (like CSS and JS aggregation)
Responsive features OOB 
Attachment of JS and CSS assets by using libraries (instead of drupal_add_css and drupal_add_js)
CSS file structure based on SMACSS & BEM
CSS3 pseudo selectors
Classy as base theme

Of all those changes, the most important is probably the theme engine moving to Twig. Twig is a PHP-based compiled templating language, which means that when your web page is rendered, the Twig engine takes the template and converts it into a compiled PHP template stored in a protected directory in sites/default/files/php/twig. Once the compilation is done, the template files are cached for reuse and are recompiled when the Twig cache is cleared.

Your Drupal 9 Theme Migration Checklist

As for the migration of Drupal 7 themes to Drupal 9, there’s no tool to do it automatically or to flag what needs changing. So when we do it, we’re facing a whole theme rebuild—which can be overwhelming since we’ll create a theme from scratch and replicate items manually from our D7 theme. However, having a migration checklist can help smooth the process, so these are the steps we follow for rebuilding our themes:

Create the folder structure
Create the necessary files
Define regions
Create and load your libraries
Move theme settings
Create breakpoints if needed 
Convert templates to Twig

Let’s go through each one of them!

Step 1: Create the folder structure

You should locate themes in Drupal 9 in the themes folder of the root Drupal installation. It’s recommended to classify them whether they are contri or custom themes, so your structure should look something like:

 

drupal9
/core
/modules
/themes
/contrib
/custom
/theme_name

 

Step 2: Create the necessary files

The only file Drupal needs to recognize your theme is the .info.yml file: the old .info file is not needed anymore as it was replaced by .info.yml. This file follows yaml syntax, so remember to set the indentation to spaces instead of tabs, and respect that indentation. Here’s an example, assuming we’re creating a theme called simple:

name: Simple
type: theme
description: Drupal 9 version of the D7 Simple theme.
core_version_requirement: ^8 || ^9
base theme: false

The base theme key introduction is essential here. By using it, you can define the name of another theme you want to inherit from, but if you don’t want your theme to be a subtheme, you still need to add the key but with a “false” value.

Step 3: Define your regions

The regions for Drupal 9 themes are defined in the theme_name.info.yml file under the key “regions”:

regions:
header: ‘Header’
navigation: ‘Navigation bar’
highlighted: ‘Highlighted’
help: ‘Help’
content: ‘Content’
sidebar_first: ‘First sidebar’
sidebar_second: ‘Second sidebar’
footer: ‘Footer’

Step 4: Create and load your libraries

Instead of using the old drupal_add_js to add Javascript assets or drupal_add_css to add CSS files, you should create and load libraries. To create them, you’ll need to add a new theme_name.libraries.yml file and define the libraries in it:

global_styles:
version: 3.0.1
css:
theme:
dist/css/styles.min.css: { minified: true }
js:
dist/js/jquery.visible.min.js: { minified: true }
dist/js/theme.min.js: { minified: true }
dependencies:
– core/jquery
– core/drupal

To load the libraries, you have many options:

Load libraries everywhere: add the library name in the theme_name.info.yml file under the libraries key:

libraries:
– theme_name/global_styles

Load libraries conditionally in the template file: you can use the function attach_library in the template file that you want to load the library in:

{{ attach_library(‘theme_name/font-awesome’) }}
Load libraries conditionally in a pre-process function: you will use the ‘#attached’ key in the variables received as argument:

$variables[‘#attached’][‘library’][] = ‘theme_name/lib’;

You can find more information about how to override libraries and the differences between D7 and D9 here.

Step 5: Move your theme settings

Theme settings management didn’t change, so you can move your theme-settings.php and it should work. Just be careful of dependencies and services you might need.

Step 6: Create breakpoints if needed

If you were using breakpoints in your theme’s Drupal 7 version, you had to install the contributed module breakpoints. In Drupal 9, however, you won’t need it since this functionality is now part of core. All you need is to create a new theme_name.breakpoints.yml file and add your breakpoints there. For example:

bearskin.small-width:
label: small
mediaQuery: ‘(min-width: 0px)’
weight: 2
multipliers:
– 1x
bearskin.medium-width:
label: medium
mediaQuery: ‘all and (min-width: 400px) and (max-width: 800px)’
weight: 1
multipliers:
– 1x
bearskin.large-width:
label: large
mediaQuery: ‘all and (min-width: 1000px)’
weight: 0
multipliers:
– 1x
view raw

Step 7: Convert your templates

With the theme engine moving from PHPTemplate to Twig, there are some significant changes in the templates. Some online tools can help you ease this process, such as https://php2twig.com/, but in general, in the following table, you have a list of old vs. new way of writing templates:

 

PHPTemplate

Twig

Comments

<?php  

/** 

 * @file

 * File description

 */

?>

{# 

/** 

 * @file

 * File description

 */

#}

File names

html.tpl.php

page.tpl.php

node–[content-type].tpl.php

html.html.twig

page.html.twig

node–[content-type].html.twig

Function names

THEME_node_links()

node-links.html.twig

Templates and pre-process

node–event-teaser.tpl.php

hook_preprocess_node__event_teaser()

node–event-teaser.html.twig

hook_preprocess_node()

Assigning variables

tags; ?>

 

$author, ‘@date’ => $created); ?>

{% set tags = content.tags %}

 

{% set args = {‘@author’: author, ‘@date’: created} %}

Printing variables

 

 

{{ tags }}

 

{{ content }}

 

{{ item[‘#item’].alt }}

Conditionals

tags): ?> 

 

0): ?>

{% if content.tags %}

{% endif %}

 

{% if count > 0 %}

{% endif %}

Check if variables are empty or defined

tags)): ?>

 

tags)): ?>

{% if content.tags is not empty %}

{% endif %}

 

{% if content.tags is defined %}

{% endif %}

Loops

{% for user in users %}

{% endfor %}

Filters

 

{{ title|striptags }}

 

{{ title|raw }}

Translations

 

$user->name)); ?>

{{ ‘Home’|t }}

 

{{ ‘Welcome, @username’|t({ ‘@username’: user.name }) }}

 

{% set username = user.name %}

{% trans %}

  Welcome, {{ username }}

{% endtrans %}

Imploding lists

{{ usernames | join(‘, ‘) }}

 

{{ usernames | safe_join(‘, ‘) }}

A Note About Templates and Pre-Processes

In Drupal 9, only the base hook of a pre-processing function exists. For example, in D7, you can have a “node–event-teaser.tpl.php” and subsequently a “hook_preprocess_node__event__teaser” pre-processing function available for you in your template.php file. In D8, you can still have the template file for your event teaser, but you only get the base hook, “hook_preprocess_node.”, Instead, you’d need to do logic within the base to operate on your event teaser specifically.

You can find more information about the differences between PHPTemplate and Twig here.

For now, you’re ready to go and start rebuilding your themes! If you need any more help, here are some extra resources:

Port your Drupal 7 theme to Drupal 8: https://www.zivtech.com/blog/port-your-drupal-7-theme-drupal-8 
Comparison PHPTemplate to Twig: https://www.drupal.org/node/1918824  
Twigify: https://www.drupal.org/project/twigify  
Port theme: https://www.zivtech.com/blog/port-your-drupal-7-theme-drupal-8  
Conversion instructions: https://www.drupal.org/docs/theming-drupal/drupal-twig-conversion-instructions-tplphp-to-htmltwig  
PHP to Twig: https://phptotwig.com/  

 

>> Need help with your migration?

Our team is ready to help! Get in touch

+ more awesome articles by Evolving Web

Leave a Reply

Your email address will not be published. Required fields are marked *