The Info.yml
file is required when creating any theme. It helps notify Drupal that a theme exists and provides information to the Appearance interface that a theme is available to install. We will be working with *.info.yml
files when creating our first theme, so let's take a look at the makeup of a basic example.info.yml
file:
name: Example description: 'An Example theme.' type: theme package: Custom base theme: classy core: 8.x libraries: - example/global-styling regions: header: Header primary_menu: 'Primary menu' secondary_menu: 'Secondary menu' page_top: 'Page top' page_bottom: 'Page bottom' highlighted: Highlighted breadcrumb: Breadcrumb content: Content sidebar_first: 'Sidebar first' sidebar_second: 'Sidebar second' footer: 'Footer'
At first glance, the example.info.yml
file is logical in structure and syntax. Starting from the top and moving our way down, the file is broken down by different sections of metadata containing general information, libraries, and regions. This information is described using a key: value
format. We should begin with understanding how basic metadata works.
The metadata contained within any themes *.info.yml
file helps to describe what type of document it is. In our case, it begins to describe a theme, including the name, description, and the version of Drupal the theme works with. Some metadata is required for the theme to function properly, so let's explore the keys in more detail as follows:
base theme: false
).One of the most common mistakes when first creating a *.info.yml
file is forgetting to change the core
value to 8.x
. Failure to set this value will result in the theme not being displayed within the Appearance interface in the admin.
The next section of a *.info.yml
file allows us to manage assets (CSS or JS) using the new concept of libraries.
Drupal 8 introduced a new, high-level principle of managing assets using a libraries configuration file that can be loaded globally or on a per page basis. This concept helps to improve frontend performance as well as ensure that any dependencies that a particular asset needs is loaded properly. One advantage of this is that jQuery no longer loads on every page as it did in the previous versions of Drupal.
The concept of a *.libraries.yml
configuration file also means that the style sheets and scripts properties that we may have been familiar with in Drupal 7 no longer exist. Instead, the process to manage assets includes saving any CSS or JS files to our theme's css
or js
folder and then defining a library file that references the files we want to use in our theme.
When defining a *.libraries.yml
file for a theme, each library will reference the location of individual CSS or JS files and be organized using the SMACSS (https://smacss.com/) style categorization.
In most cases, a simple library reference will follow the theme categorization. For example, if we wanted to create an example.libraries.yml
file that included assets for CSS and JS, we would create a library that pointed to our assets, as shown here:
libraryname: css: theme: css/style.css: {} css/print.css: { media: print } js: js/scripts.js
We would then reference the library within our example.info.yml
configuration simply by adding the following:
libraries: - example/libraryname
This would result in Drupal adding to every page both CSS and JS files contained in our library. Where this becomes powerful is in the management of assets, as we would only ever need to make modifications to our example.libraries.yml
file if we ever needed to add or remove assets.
Libraries can also be overridden to modify assets declared by other libraries, possibly added by a base theme, by a module, or even the Drupal core. The ability to override libraries includes removing as well as replacing assets altogether. The same way we reference a library from our *.info.yml
file, we can override libraries by adding the following:
libraries-override: # Replace an entire library. core/drupal.vertical-tabs: example/vertical-tabs # Replace an asset with another. core/drupal.vertical-tabs: css: component: misc/vertical-tabs.css: css/vertical-tabs.css # Remove an asset. core/drupal.vertical-tabs: css: component: misc/vertical-tabs.css: false # Remove an entire library. core/modernizr: false
In this case, the libraries-override
configuration achieves something different for each line. Whether it is replacing an entire library or removing an asset, we now have the flexibility to control assets like never before.
Libraries can also be extended to allow overriding CSS added by another library without modifying the original files. This can be done by adding the following to our *.info.yml
configuration as follows:
libraries-extend: core/drupal.vertical-tabs: - example/tabs
In this case, the libraries-extend
configuration is extending Drupal's own core.libraries.yml
file and extending the drupal.vertical-tabs
library with additional styling.
While we now have a general understanding of how libraries are defined, overridden, and extended, we have only dealt with libraries globally loaded into our Drupal instance using our configuration file. However, there are two more methods to include assets within a page directly, without the need to add it to every page.
In many cases, we may be developing some CSS or JS functionality that is specific to an individual page. When we are presented with this requirement, we have the ability to attach a library to a page using two different methods.
While we will be learning all about Twig a little later in the chapter, we need to pause for a moment to reference a Twig function named {{ attach_library() }}
. This function allows us to add to any Twig template a library that may include CSS or JS that will load on that page only.
For example, if we wanted to add the Slick Carousel (http://kenwheeler.github.io/slick/) to our page, we may define the library within our example.libraries.yml
file as follows:
# Slick slick: version: VERSION css: theme: vendor/slick/slick.css: {} js: vendor/slick/slick.min.js: {} dependencies: - core/jquery
We could then turn around and add the following to our Twig template:
{{ attach_library('example/slick') }}
This provides us with some nice functionality to define individual libraries for various user functions and also to have those assets used wherever we choose to attach them.
Another method to attach a library to an individual page depends on creating a *.theme
file, which allows us to use preprocess functions to manipulate page variables. We will learn a lot more about creating a *.theme
file a little later in the chapter, but it's important to note that we could attach the same Slick Carousel to our homepage without globally calling it by using a preprocess function, as shown in the following example:
function example_preprocess_page(&$variables) { if ($variables['is_front']) { $variables['#attached']['library'][] = 'example/slick'; } }
Here, we are checking to see whether we are on the homepage of our website and attaching our Slick library using the #attached
library array. Again, this may seem a little bit advanced at this point but does merit mentioning.
The last section we will want to cover when working with any *.info.yml
file is about regions that can be defined for the layout of our theme.
Regions play a critical part in theming, as Drupal needs to know exactly where content can be displayed. This has an impact on what regions are visible to the Block layout for both system blocks and custom blocks that we may want to use. If we do not specify any regions within our *.info.yml
file, then Drupal will provide us with regions by default.
If we decide to add additional regions to our theme, we must also add the defaults or else we will not have access to them. Let's take a look at how this is implemented:
regions: header: Header primary_menu: 'Primary menu' secondary_menu: 'Secondary menu' page_top: 'Page top' page_bottom: 'Page bottom' highlighted: Highlighted breadcrumb: Breadcrumb content: Content sidebar_first: 'Sidebar first' sidebar_second: 'Sidebar second' footer: 'Footer'
The value for each key is what is displayed in the Block layout within the Drupal UI and can be named whatever we want to name it. We can add additional regions based on our theme as needed. We will look at this in more detail in Chapter 4, Getting Started – Creating Themes.
Now that we have covered the basics of theme configuration, it's time for us to set up a local development environment that will enable us to work with files and templates without worrying about having to clear the Drupal cache or guess what Twig templates are being used.