Quite a few times we come across Bootstrap themes when we wish to use in our Drupal website. You have searched Drupal download and it is not available as sub-theme. How about creating a new theme in Drupal 8 out of HTML template. In this post we are going to discuss, how we need to approach and build Drupal 8 bootstrap sub theme based on a html bootstrap template.

Bootstrap is html, css and js framework for building mobile first responsive themes. Bootstrap is available for Drupal 7 and 8 with starter kits using cdn and less. If you need to build your Drupal 8 theme using bootstrap starter kit, please go through this simple tutorial on How-to-build-your-drupal-8-theme-using-bootstrap-less. We have explained the basic folder structure of Drupal 8 theme in one of previous blog post - understanding-of-drupal-8-theming.

We will be creating Drupal theme out of this in following steps -

Creating sub theme

First we need to download the base theme bootstrap and place it in `/themes` directory in web root. Create new directory for sub theme, let say `my_sub_theme`. For sub theme, to be usable minimum we need is theme info.yml file. Info file would be like this initially,

Theme based on HTML bootstrap template

Step one: Identifying regions

First step in theming based on html bootstrap template is to find out possible regions in context of Drupal 8 site. List of region in Drupal site can be obtained from `admin/structure/block/demo/my_sub_theme`. For bootstrap, it will be like,

File: my_sub_theme.info.yml
name: my_sub_theme
type: theme
base theme: bootstrap
description: 'A simple starter theme for Drupal 8.'
core: '8.x'

Once info.yml file is been defined, we can enable the new theme. At this point if you view the page, what you would see is nothing simple and default bootstrap’s look and feel. Now the next part would be how can we integrate our html bootstrap template.

Bootstrap theme regions

Once you found out the possible regions and the regions provided by bootstrap is more than enough you can skip this section. If you need to alter regions, list them in info.yml file. Then only listing regions would be available for newly created theme.

File: my_sub_theme.info.yml
name: my_sub_theme
. .
. .
core: '8.x'

  header: 'Top Bar'
  help: 'Help'
  content: 'Content'
  footer: 'Footer'

Step two: Create libraries.yml

Make a list of css and js libraries is been used in all page template. Also figure out list of css and js libraries used only in some pages (says only pages which having forms). Once this listing is been done, we are ready to create libraries.yml file. Libraries need to be defined section wise, like libraries needed for all pages as one section and libraries needed for specific set of pages as separate section for each. Suppose let libraries.yml be

File: my_sub_theme.libraries.yml
theme: # Libraries needed in all pages.
      css/font-awesome.min.css: {}
      css/animate.css: {}
      css/style.css: {}
      # External library
      http://fonts.googleapis.com/css?family=Lobster: { type: external }
    js/jquery.appear.js: {}
    js/jqBootstrapValidation.js: {}
    js/modernizr.custom.js: {}
    js/script.js: {}
    - bootstrap/theme
contact_me: # Libraries needed only in contact page.
    js/contact_me.js: {}

In this libraries.yml file you might have noticed, basic bootstrap css and js libraries are missing. Since my_sub_theme is sub theme of bootstrap, we can specify what all libraries needed from base theme as dependencies. In above code, we have given `bootstrap/theme` as dependency where first part (bootstrap) is theme name and second part (theme) is key of library defined in bootstrap.libraries.yml.

Done with defining libraries.yml. Now how do we use it or include it or attach it? Just include in info.yml. Same way you can include any other libraries you need in info.yml.

File: my_sub_theme.info.yml
name: my_sub_theme
. .
. .
core: '8.x'

. .
. .

  - 'my_sub_theme/theme'

# List of css need to removed.
  - themes/bootstrap/css/3.3.5/overrides.min.css

Libraries specified in info.yml will be attached for all pages. We may need some libraries defined in libraries.yml need to be conditionally or for specific pages. This can be achieved by using template_preprocess_HOOK() in my_sub_theme.theme file.

File: my_sub_theme.theme
function my_sub_theme_preprocess_page(&$variables) {
  if ($variables['is_front']) {
    $variables['#attached']['library'][] = 'my_sub_theme/contact_me';

For more info, you can refer Drupal 8 documentation Adding stylesheets (CSS) and JavaScript (JS) to a Drupal 8 module on how to achieve it.

We can avoid or remove some css from base theme to be get attached using `stylesheets-remove`.

Step three: Modifying template

Modifying html to suit the HTML bootstrap template will be more difficult task initially, but i must say you will enjoy it and find it challenging to work in Drupal 8 after turning on twig debugging. For turning on twig debugging, rename the file `sites/default/default.services.yml` to `sites/default/services.yml` and change the value of debug from false to true under section `twig.config` and finally clear the cache.

Drupal services yml

Now onwards, you can get template info and template suggestions from browser developer tool. It looks like

Debug twig template

So where ever we need to change the html structure, we can identify the template file and can override by simply copy pasting the file within our theme template directory. For example if we need to alter the /page.html.twig then we need to place this in `/themes/my_sub_theme/templates/system/page.html.twig`.

Also we can make use of theme suggestions to override template only for specific page or region or block. For example, if we need to alter html template of navigation region then need to copy `/themes/bootstrap/templates/system/region.html.twig` to `/themes/my_sub_theme/templates/system/` and rename it as `region--navigation.html.twig` as per theme template suggestions.

In Drupal 8, twig template engine is being used as default template engine. That’s why template file follows the extension *.html.twig.

New to twig template then, these basics of twig will help you

Set and Print variables

Use set tag with in {% ... %} for assigning values. While printing variables can be modified using various filters followed by pipe( | ).

{% set foo = ‘bar’ %}
{{ foo }} {# outputs ‘bar’ #}
{{ foo|title }} {# outputs ‘Bar’ #}

{% set foo = {‘bar’: ‘foo’} %}
{{ foo.bar }} {# outputs ‘foo’ #}
{{ foo[‘bar’] }} {# outputs ‘foo’ #}

Control statements

Like variable assignment, control statements like if, elseif, else and for loops should be contained in {% … %} blocks.

{% if menus|length > 0 %}
	<li>{% for menu in menus %}</li>
	<li>{{ menu.link }}</li>
	<li>{% endfor %}</li>
{% else %}
	<li>{{ login_menu.link }}</li>
{% endif %}


Commenting can be done using {# … #} blocks.

{# Inline comment. #}
{# Multi line commenting.
    {% set foo = {‘bar’: ‘foo’} %}
    {{ foo.bar }}

Debugging variables

For dumping any variable use dump() function.

{{ dump(foo) }}

For more reference on twig, please go through Twig for Template Designers.


comments powered by Disqus