Creating a Custom Theme in Drupal 8 and Twig for Custom Content Types

This tutorial is designed for front end developers who want to get right to theming in Drupal and not have to worry about fussing with getting Drupal to cooperate. By following this quick tutorial, you will be up and running with a blank template in a few minutes. You'll also be ready to have different templates for Drupal custom content types.

Begin by either cloning your team's Drupal repository, or installing Drupal yourself.

With Drupal installed, download or clone this starter theme repo. You will need to go into the /themes folder and create a new folder inside it called "custom." This is where all custom themes go. With the starter theme you just downloaded, move it to the /themes/custom/folder you just created. The example is called "caxy," so you'll need to change the folder name and all the file names and function references. Do that later. For now, just stay with the naming provided. https://github.com/caxy/drupal-custom-theme-starter

To get started right away, you can use the /templates/page.html.twig template and use it just like you would any other HTML template. Drupal provides a number of variables to the template, but the key ones are already in the file: 

  • {{ page.content }} - will print the content from the page

  • {{ page.primary_menu }}

  • {{ page.breadcrumb }}

  • {{ page.footer }}

And so on. You can review the other variables by looking at the twig syntax.

The sample theme provided introduces a key concept in the caxy.theme file. The .theme file is the PHP code used when the theme loads. Drupal uses a "theme suggestion" engine when a given piece of content loads. It starts at a high, more general level and then looks for suggestions about what it might use instead. In the starter file, we have added a function that adds logic to look for a template with the same name as a content type. That gives the front end theme builder the ability to easily create different layouts for different content types without getting into too much coding. In the Drupal back end, simply create a new content type and then create a template in the /themes/custom/caxy folder with the same name. The full file name is page--{the content type name}.html.twig. In our example, that is page--customtype.html.twig found in /themes/custom/caxy/templates/page--customtype.html.twig.

Note: create a page or two of each content type so that you have something to test. A common error is to try to get a template for a custom content type to work when there is no content entered for that content type.

Also included in the sample template is a starter caxy.info.yml file that specifies some external files and libraries you are likely to want. 

The first section handles the issue of Drupal including styles that you do NOT want as a part of its defaults.


# Remove defaults you do not want

stylesheets-remove:

  - "main.css"

The second section includes a library file that you can use to specify css and js files.


# Add your CSS

libraries:

  - caxy/global-css

  - caxy/global-js

The last section defines some standard regions / variables for the theme.


regions:

  headline: headline

  header: header

  content: content

  sidebar: sidebar

  footer: footer

The caxy.libraries.yml file specifies the files:

global-css:

  css:

    theme:

      css/style.css: {}

      css/bootstrap.css: {}

global-js:

  js:

    js/main.js: {}

    js/bootstrap.js: {}

In our example, we've included bootstrap.

To make changes and develop your theme, you can simply add more template files and/or add to the css and js files. 

A key aid in this process is to turn on twig debugging. When viewing the source of a given page, it will show you, in comments, the series of template suggestions that were tried. You can simply use one of the files mentioned if you wish to override the template at that stage of the output.

To do this, edit the /sites/default/services.yml file and change the twig debug setting to:

  twig.config:
    debug: true

And then clear the cache at /admin/config/development/performance.

If you view the source for our custom content type "customtype" you should see this:

<!-- THEME DEBUG -->
<!-- THEME HOOK: 'page' -->
<!-- FILE NAME SUGGESTIONS:
   x page--customtype.html.twig
   * page--node--2.html.twig
   * page--node--%.html.twig
   * page--node.html.twig
   * page.html.twig
-->

You can see from the "x" that Drupal chose the "page--customtype.html.twig" template as suggested by the modification in the caxy.theme file.