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:
- Generic structure of a Drupal 8 theme
- Initiation Drupal 8 theme and placing supplied assets: CSS, JS, fonts and images.
- Breaking down supplied HTML into Twig template files (.html.twig files).
- Determination of the Drupal regions.
- Building homepage HTML using blocks, and Drupal and Twig template files.
- Building contact page using blocks and Drupal 8 core contact form.
- 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:
- Google conversion tracking or analytics code
- Facebook Pixel code
- An admin toolbar
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:
- node--nodeid--viewmode.html.twig
- node--nodeid.html.twig
- node--type--viewmode.html.twig
- node--type.html.twig
- node--viewmode.html.twig
- 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.
