How to build a Drupal 8 website | Part 1: initialize theme

Open Source Drupal


  • Nederlands
  • English
Node Author

In this blog serie I will explain how we have built a new multilingual Drupal 8 site. During the process the required HTML, CSS en Javascript was supplied statically and used to build a custom Drupal 8 theme. So we did not use a Drupal core or contrib theme.

We are talking about this website:

This Drupal 8 website consists of pages that are built up from Drupal blocks. Therefore I will explain in detail how we have built these blocks. Furthermore this Drupal 8 website is multilingual: Dutch and English. As listed below I will explain:

  1. Generic structure of a Drupal 8 theme
  2. Initiation Drupal 8 theme and placing supplied assets: CSS, JS, fonts and images.
  3. Breaking down supplied HTML into Twig template files (.html.twig files).
  4. Determination of the Drupal regions.
  5. Building homepage HTML using blocks, and Drupal and Twig template files.
  6. Building contact page using blocks and Drupal 8 core contact form.
  7. Building other pages using Drupal 8 blocks.

Basic knowledge

I assume you already have some experience with Drupal:

  • Installation and general configuration of the Drupal 8 core, modules and themes.
  • Configuration of content types

Drupal 8 theme | The structure

What is a Drupal 8 theme

A theme is a collection of files that determine the look of your Drupal website: what the visitor sees. Only 1 file is required, the .info.yml, but for a complete theme more files are needed.

Drupal 8 uses by default PHP templating engine Twig, part of the Symfony framework where Drupal 8 is built on.

Where do you insert the theme

When creating a custom theme, this is inserted in the /themes folder. Be sure to put the Drupal core themes in the folder /core/themes. Never ever do you put your own theme there, that would be a core-hack: a crying shame.

To keep your themes folder organized, it is a best practice to divide them in the folders:

  • /contrib: place here all themes downloaded from Drupal.org
  • /custom: place here all themes that you are building yourself.

Each individual theme is inserted in a folder with the name of the concerning theme. That name can only contain lowercase letters, must start with a letter and use underscores (_) instead of spaces.

The (partial) structure for our installation will look like this:

|-core
| |-modules
| |-themes
| | |-bartik
| | |-seven
..
|-modules
|-themes
| |-contrib
| |-custom
| | |-openlucius

Which files are part of a Drupal 8 theme

As indicated, a useful theme will contain more files then just the mandatory THEMENAME.info.yml.

About .yml files

Yaml (.yml) files are files intended for data and not for markup. These are not necessarily Drupal 8 specific files: they are also used in other programming languages such as C, Perl and Python. Within Drupal 8 they are mainly used to include definition and configuration; part of the Configuration Management Initiative

A Drupal 8 theme has the following structure:

|-THEMENAME.breakpoints.yml
|-THEMENAME.info.yml
|-THEMENAME.libraries.yml
|-THEMENAME.theme
|-config
| |-install
| | |-THEMENAME.settings.yml
| |-schema
| | |-THEMENAME.schema.yml
|-css
| |-style.css
|-js
| |-THEMENAME.js
|-images
| |-background_frontpage_header.png
|-logo.png
|-screenshot.png
|-templates
| |-maintenance-page.html.twig
| |-node.html.twig

THEMENAME.info.yml

This is the only mandatory file of the theme, that defines the theme and that is recognized by Drupal 8. Extra ‘meta data’ is also placed here, such as:

  • description: short description of the theme.
  • libraries: which libraries are where.
  • block regions: defined regions, see below for more info.
  • overrides: which Drupal 8 core services do you want to override and where are these overrides.

THEMENAME.libraries.yml

Defines the Javascript and CSS libraries used by the Drupal 8 theme.

THEMENAME.theme

Contains PHP code where preparatory logics can be programmed: (pre)processing of the HTML output.

THEMENAME.breakpoints.yml

Breakpoints are points on which a responsive webdesign should change to be displayed properly across devices. These breakpoints can be defined here.

/templates/

The template files implement the HTML code for your Drupal 8 website. Drupal 8 template files have format THEMENAME.html.twig and must be placed in this subfolder (unlike Drupal 7).

The Drupal 8 core provides a number of template files. If you maintain certain naming conventions for template files in your own theme, then Drupal will automatically use your templates instead of the core templates. Allowing you to override the HTML markup.

Place for example the file node.html.twig in this folder and Drupal will use your version instead of the core version: /core/modules/node/templates/node.html.twig

/css/

It is a best practice to place .css files in the subfolder /css. Drupal 8 core themes structure CSS files in accordance with the SMACCS style guide. CSS files should be defined in the .libraries.yml file and can be override or disabled in the .info.yml file.

/js/

This folder contains the Javascript files of the Drupal 8 theme. To load them, they should also be defined in the .libraries.yml file.

/images/

It is a best practice to place theme image in this subfolder. Don’t confuse it with content images.

screenshot.png

When you insert this image, then it will appear on the Appearance backend page in Drupal 8. The location of screenshot.png could be placed somewhere else; that alternative location should then be defined in the .info.yml file.

logo.svg

The logo of your website, that is usually shown in the header to your visitors. This logo can also be uploaded in the Drupal 8 backend under Appearance > Settings

Subthemes

Within Drupal 8 it is also possible to work with base-themes and sub-themes. Subthemes are just like other themes with the difference that they inherit resources from the base-theme. It is even possible to create sub-sub-themes and sub-sub-sub-themes (and so on).

In this tutorial I will not discuss sub-theming in Drupal 8 any further.

Drupal 8 theme structure | Regions

As the word implies: a region is a certain region in your Drupal 8 website, which is used to place content. More detailed: this content is added in blocks, that are placed in regions. A block can be seen as a building block; regions give your Drupal 8 website the layout to place your blocks (meaning the content).

Regions are defined in the theme in the .info.yml file

Drupal 8 core regions

Drupal 8 knows the following standard regions:

  • page.header: Items for the header region.
  • page.primary_menu: Items for the primary menu region.
  • page.secondary_menu: Items for the secondary menu region.
  • page.highlighted: Items for the highlighted content region.
  • page.help: Dynamic help text, used mainly for admin pages.
  • page.content: The ‘main content’ of the current page.
  • page.sidebar_first: Items for the ‘first sidebar’.
  • page.sidebar_second: Items for the ‘second sidebar’.
  • page.footer: Items for the ‘footer region’.
  • page.breadcrumb: Items for the ‘breadcrumb region’.

If your custom theme does not define regions, then you will have these at your disposal.

Hidden regions

When you go deeper into Drupal 8 theming, then you will also get to see these regions:

  • page_top
  • page_bottom

These are hidden regions and can be seen in html.html.twig, a template file that is usually not overridden in a custom theme. These regions are used to place HTML entirely at the beginning or the end of the page, for example:

More info about regions

Can be found here.

Drupal 8 theme structure | Template files

Template files contain the HTML that is eventually sent to the browser of your website visitor. These are all files with extension .html.twig. If you look at the template files of the Drupal 8 core theme ‘Bartik‘, you will see the following:

These files all follow a by Drupal 8 determined naming convention so that Drupal knows which template file to use for what. This can range from an entire page, to theming a block, to theming one small select element. In fact, all html generated (or additionally required) by Drupal core can be changed to custom HTML. Creating a theme with supplied, so 100% custom, HTML is therefore possible.

The template files are divided into:

  • HTML for the header
  • HTML for the page
  • HTML for regions
  • HTML for blocks
  • HTML for nodes
  • HTML for taxonomy terms
  • HTML for fields
  • HTML for comments
  • HTML for maintenance page
  • HTML for search results

As an example, these are the naming conventions for the node template files:

  1. node--nodeid--viewmode.html.twig
  2. node--nodeid.html.twig
  3. node--type--viewmode.html.twig
  4. node--type.html.twig
  5. node--viewmode.html.twig
  6. node.html.twig

Per page Drupal will run this list from top to down, the file that is first defined in the theme, will be applied by Drupal to the appropriate item.

See here an overview of all template naming conventions.

In case this should all be a little too abstract, don’t worry: in the actual implementation that is discussed further down in this blog, everything will become clear.

Implementation custom Drupal 8 theme | Initiation

Installation Drupal 8

We are starting with a new Drupal installation. Download and install Drupal 8 from this page, or install via the Drupal console with site:new.

Initiation Drupal 8 theme

In the initiation phase the following theme structure was made: the required folders and files were placed in drupal8 root/themes/custom/

openlucius
|-css
| |-base
| | |- css files
| |-components
| | |- css files
| |- mobile-overrides.css
| |- overrides.css
|-fonts
| |- font files
|-images
| |-backgrounds
| | |- images
| |-flags
| | |- images
| |-glyphicons
| | |- images
| |-gradients
| | |- images
|-js
| |-base
| | |- javascript-files
| |-components
| | |- javascript-files
|-templates
| |-block.html.twig
| |-block--system-branding.html.twig
| |-block--system-menu-block.html.twig
| |-node.html.twig
| |-page.html.twig
| |-page-title.html.twig
| |-region--header.html.twig
| |-status-messages.html.twig
|-logo.png
|-openlucius.info.yml
|-openlucius.libraries.yml
|-openlucius.theme

Inserting supplied assets of the theme

All supplied assets of the theme are divided into the following folders:

  • /css
  • /javascript
  • /images
  • /fonts

openlucius.libraries.yml

All CSS and JS files need to be recognized by Drupal, this is done in openlucius.libraries.yml, with us this is looking as follows:

openlucius.theme

Additional logics that is required before rendering the HTML, will be placed here.

Not implemented: openlucius.breakpoints.yml

We did not use this file, as necessary breakpoints have already been supplied to the implemented static HTML/CSS.

Enable the Drupal theme

In the Drupal 8 backend go to ‘Appearence’ and click ‘install and set as default’ at the new custom theme.

Theme initiation done

The Drupal 8 theme is now initiated, but at the moment only an ‘empty’ page can be seen. In the following blogs I will fill the page by inserting the HTML through blocks.