Porting a contrib theme to Drupal 8: Getting a Twig theme

Original author: Danny Englander
  • Transfer
In my spare time over the past few months, I have been very busy porting my Drupal theme, Gratis ( link given by me ), to Drupal 8. The process is going well, and most things already work as they are implemented in Drupal 7, but this process entailed a radical overhaul of theme architecture for two main reasons:
  1. Twig is now the basis of the theming for Drupal 8, the PHP Template handler, which has been one of the main themes for Druapl for many years, has left.
  2. As in most recent major versions of Drupal, the API for Drupal 8 has changed again and this directly affects how you do something in the context of the theme.


Theming and Twig

What does all this mean? First, you can no longer use PHP code in the theming, it's all Twig. Twig simplifies the theming and facilitates understanding. In Drupal 8, the old template.php file now becomes your theme's .theme file , which contains special PHP code that is rendered from Twig variables to a twig template. Twig syntax is easy to understand.
For example, in page.tpl.php Drupal 7 we have a base code that displays a block in a region:


With Twig and Drupal 8, in our page.html.twig template , we can do it like this:

{% if page.preface_first %}
    {{ page.preface_first }}
{% endif %}

So, as you can see, with Twig there are no more “tipple fips” ( .tpl.php files). The name .html.twig is now permanent for all theme templates. In general, Twig greatly simplifies the way variables are processed. So now where you used
print render($page['some_var'])
or
print render($content['some_var'])
now just use
{{ page.some_var }}
or simply
{{ some_var }}
depending on usage and location.
Here are the key file naming conventions that have been changed in Drupal 8:
Drupal 7> Drupal 8
  • MYTHEME.info> MYTHEME.info.yml
  • template.php> MYTHEME.theme
  • template_name.tpl.php> template_name.html.twig

I was surprised that theme-settings.php was not renamed and how it works hand in hand with what template.php used to be . Also, not much has changed in theme-settings.php , it usually works from Drupal 7 without changes, although I could not find a page describing the API function system_theme_settings API for Drupal 8.

Another big change in the templates is that the arrays of attributes and classes were combined together into an attribute object. Before rendering global classes and attributes for body, nodes and comments as:
class=""
... if you convert word to word for Twig, you get:
class="{{ classes }}"{{ attributes }}
However, this is not quite a working option, in fact, in a new way it is declared like this:
class="{{ attributes.class }}" {{ attributes }}
For brevity, you can simply do this:
{{ attributes }}

... without outputting specific classes, this one variable does everything. I prefer the first method, since it allows you to set your own theme classes to the tag, if you like, such as clearfix or whatever.

info theme file

Another important change related to the theming in Drupal 8 is the design of the info file. Now it is designed in the YAML style and analyzed by the Symfony YAML component. Converting the info file for Drupal 7 was pretty trivial. I took a look at the implementation at Bartik and used it as a guide to learn enough to transform Gratis. For example, what happened before:
; Stylesheets
stylesheets[all][] = css/style.css

will now look like this:
stylesheets:
  all:
   - css/style.css

Another problem I encountered while porting Gratis was that there seemed to be a lot of conflicting class matches between the new Drupal 8 admin panel and Gratis. It seems that the admin panel uses some very general classes for theming , such as ul.menu . In the end, I just pointed out more specific classes in my topic to avoid conflicts.
In general, I did not find the full documentation on the theming in Drupal 8, I had to dig into the files of the main themes of Drupal 8 to understand how it all works.

API changes

Converting theme templates to Twig is pretty trivial, updating custom template.php code to MYTHEME.theme is not very. The basis of the conversion of these functions is that some of them are not recommended, they still work, but in the end they will leave it. Other functions simply will not work and will throw errors, as the API has changed for them - completely or there are new functions for which they need to be replaced. PhpStorm has a nice visual indicator of functions deprecated in Drupal 8, it is really very convenient.

For example, drupal_add_js and drupal_add_css are deprecated, so you will need to use #attachedmethod to add any custom js for your theme. Drupal 8 is now very thin, which means that it doesn’t by default load a lot of Javascript for anonymous users, so now you will need to use hook_library_info to create dependencies to load things like jQuery.once or even drupal.js.

PS
This is my free translation of an article by Danny Englander - Porting a Contrib Theme to Drupal 8: Get Twig-gy With It

Also popular now: