How to Port a Drupal 7 theme to Drupal 8

THIS WAS DONE AS A TASK FOR THE ANNUAL COMPETITION CALLED GOOGLE CODE IN. THIS IS A COMPETITION IN WHICH PRE-UNIVERSITY STUDENTS AGES 13 TO 17 ARE INVITED TO TAKE PART IN GOOGLE CODE-IN, A CONTEST INTRODUCING YOUNG MINDS TO THE WORLD OF OPEN SOURCE. WITH A WIDE VARIETY OF BITE-SIZED TASKS, IT’S EASY FOR BEGINNERS TO JUMP IN AND GET STARTED NO MATTER WHAT SKILLS THEY HAVE. MENTORS FROM PARTICIPATING ORGANIZATIONS ARE AVAILABLE TO LEND A HELPING HAND AS STUDENT LEARN WHAT IT’S LIKE TO WORK ON AN OPEN SOURCE PROJECT.

In this post I will be showing how to port a Drupal 7 theme to Drupal 8. The theme which has been ported from Drupal 7 to 8 in this post is Danland.

You may want to switch to video on porting drupal 7 themes:

https://www.youtube.com/watch?v=JlqZwtxeNfA

Step 1:

Inside your old Drupal 7 theme you shall find the images folder , scripts folder , .info and .tlp.php files with other files for the theme. First create a new folder for your theme and give it any name of your choice. Inside of that folder create folders with names 'css','js', 'templates', also transfer the images folder from the Drupal 7 version. Inside of the css folder add all css files from the Drupal 7 theme, then add all js files from the old theme to the js folder. After place all 'tlp.php' files from Drupal 7 to the templates folder and rename them with the extension .html.twig. . In Drupal 8 Instead of tlp Twig is used as the engine for your theme therefore Twig code and file format is needed. More information on the new file format can be found on Drupal file stucture

Step 2:

In Drupal 8, .info files are not used anymore, instead .info.yml are used. Create a new .info.yml file inside your d8 theme folder. The info.yml  file is where the main details for your theme is placed. After changing the file name copy all information from the old .info file to the new info.yml file. Further technical information on the 'info.yml' file can be found on Drupal tutorial on info.yml file.

  • Change all '=' to ':' except for the regions, scripts or css.
  • Change the core Drupal 8.x and if necessary the version also.
  • You could change the engine to twig but it's not a necessary requirement
  • Regions now in Drupal 8 are defined under the region heading with 'regions:' being the heading and the specific regions place below it.
  • In Drupal 8 scripts and css are not defined in the info file but in library. Libraries are placed under the 'libraries:' heading  with each library below it with name, (themename/libraryname).
  • Also for Drupal 8 you should have a base theme which can be classy or stable. Stable is normally the default if not placed.
  • When you are done it should be looking like the screenshots below.

.info.yml

name: Danland
type: theme
description: Drupal Theme provided by Danetsoft developed by Danang Probo Sayekti inspired by Maksimer
base theme: classy
core: '8.x'
version: '8.x-1.0'
screenshots: screenshots.png
regions:
search_box: Search region
superfish_menu: Superfish menu
page_top: Page top
preface: Preface top
highlighted: Highlighted
preface_first: Preface first
preface_middle: Preface middle
preface_last: Preface last
sidebar_first: Left sidebar
sidebar_second: Right sidebar
content_top: Content top
help: Help
content: Main content
content_bottom: Content bottom
bottom_first: Bottom first
bottom_middle: Bottom middle
bottom_last: Bottom last
bottom_1: Bottom 1
bottom_2: Bottom 2
bottom_3: Bottom 3
bottom_4: Bottom 4
footer: Footer
page_bottom: Page bottom
libraries:
- danland/global

Step 3:

When finished with the 'info.yml' file create a (themename.libraries.yml) file. Inside the '.libraries.yml' file you put your different libraries which you already declared in the '.info.yml' file with the format libraryname:  . Assets are not loaded in your theme automatically so you need to tell Drupal to do so. Each library is used to enter the css and js files (assets). The files which you would enter are the files which would be used by your theme.The files which are entered for each library will be loaded globally for your theme unless you have an exception to load it at a specific process. Javascript can also come from external url or included css files.To enter your css and js file in a library you may follow the steps below.

  • First you will add the version which most of the time is 1.x
  • If you are adding css place the 'css:' header, below it the theme header( theme:). After place the locations of the css files which is inside your css folder, example (css/filename.css: {}). Inside your curly bracket you can now put functions( for example to print media) but if no function is needed just put an empty curly bracket.
  • For js files it is the same thing without any 'theme:' header but depending on what you are doing you may put other headers after the 'js:' header.
  • In drupal 8 j query no longer loads on every page so it has to be installed manually . To do so you will then list it under your dependencies.

The order in which you place the css and js files is the order which it will be loaded in Drupal. All assets are loaded at the footer but if it suppose to load earlier then you can set (header : true) before the defining of  it.Setting the header to true allow let the asset to  load at the beginning before the other assets. To attach javascript setting and read javascript setting  then drupalSetting can be used, but in order to use it it has to be implemented under the dependencies like the jquery(- core/drupalSettings). To get further information on how to install your js and css visit Drupal site. When you done defining all the css and js files it should be looking like this:


global:
   version: 1.x
   header: true
   js:
      js/hoverIntent.js: {}
      js/superfish.js: {}
      js/jquery.cycle.all.js: {}
      js/jquery.cycle.lite.js: {}
   css:
      theme:
          css/local_sample.css: {}
          css/maintenance.css: {}
          css/style.css: {}
          css/style.ie6.css: {}
   dependencies:
       - core/jquery
       - core/drupalSettings

step 4.

Now that your info.yml and libraries.yml file are done you now need to setup the html.twig files which you have copied and converted the code inside it so that it works well with the twig syntax. To convert it to twig you can follow a basic tutorial manually here or you can use the drush converter which i got from this tutorial . Inside the module file is a read me file, just follow it to convert the files using the converter. It didn't work so well for me so i converted the files manually .

When your are finished it should move from looking like this:

to this.


{#
/*
*@file
*Available variables:
*@see template_preprocess_block()
*@ingroup themeable
*/
#}
<div id="{{ block_html_id }}" class="{{ classes }}"{{ attributes }}>

{{ title_prefix }}
{% if block.subject %}
  <h2{{ title_attributes }} class="block-title">{{ block.subject }}</h2>
	  {% endif %}
{{ title_suffix }}

<div class="content"{{ content_attributes }}>
  {{ content }}
</div> <!-- end block content -->
</div> <!-- end block -->

Step 5.

The final thing left to be done after converting all your tlp.php files to twig is to create your 'themename.theme' file . The php code for your theme will be placed in this file. In Drupal 7 you will have the template.php file but in Drupal 8 it is the (the_theme_name.theme ). Modify and create the functions which are needed for your theme. There are also couple variable changes. For example &$variables are used as one global variable which is then used to connect to other variables. The functions which would create has name themename_preprocess_Hook. The hook is what the php code which you right would affect. Also inside this file you may allow a javascript to directly affect a specific piece of the theme. In this file there are not much changes from the drupal 7 template files, the code is almost the same with just the hook affecting the output of the function. You may understand the differences here.

template.php

[gallery ids="722" type="rectangular"]

.theme

<!--?php
/**
* Implements danland_preprocess_page for page.html.twig.
*/
function danland_preprocess_page(&$variables) {
if (!empty($variables['page']['sidebar_first']) && !empty($variables['page']['sidebar_second'])) {
$variables['danland_layout']['id'] = 'layout-type-2';
}
else if ($variables['page']['sidebar_first']) || !empty($variables['page']['sidebar_second'])) {
$variables['danland_layout']['id'] = 'layout-type-1';
}

Now that you have finished with your '.theme' file you can then carry over your logo, screenshots and icons from the Drupal 7 to the Drupal 8. When you have done place the theme inside your Drupal 8 installation and install it for testing . From there you can change some code or edit how the theme must looks. The theme might not look exactly how it should so some tweaks may be needed to the css files and more code for the twig file. When you finish all your editing to make your theme look good you can then save it and upload to Drupal.

When your are done your files should look something like this.

To get more information on more features which may be needed for your theme you can check the complete Drupal document on porting your theme to Drupal 8 here.

I also got a bit of help from this blog Post here