Files in the layouts directory define the layout of the site pages. They are written in the Nunjucks templating language and have an .html extension, i.e.layouts/about.html

Nunjucks Templating

Unibit uses the Nunjucks templating language. Nunjucks was chosen because it is a rich and powerful templating system, written in JS and it has a familiar templating syntax for those coming from other SSGs.

For more details on the Nunjucks tags, functions and filters available in Unibit see the following sections: Nunjucks Features

Nunjucks Functions

Nunjucks Filters

Example Nunjucks Syntax:

{% extends "base.html" %}

{% block header %}
<h1>{{ title }}</h1>
{% endblock %}

{% block content %}
<ul>
  {% for name, item in items %}
  <li>{{ name }}: {{ item }}</li>
  {% endfor %}
</ul>
{% endblock %}

❗️ Note: Layout files can use all of the Nunjucks features, but only a subset of these features is supported when converting templates to other SSGs. See supported Nunjucks features for more info.

Base Layout

Layout files must have 2-level inheritance hierarchy. The first inheritance level is internal to Unibit where body.html extends from base.html. While body.html can be customized, the base.html could not. The second level is an extension of body.html by any other layout file:

                ┌───────────┐
                │ base.html │ (private)
                └───────────┘
                      ↓
                ┌───────────┐
                │ body.html │ (layouts/body.html)
                └───────────┘
              ↙       ↓       ↘
┌───────────┐   ┌───────────┐   ┌───────────┐
│ home.html │   │ page.html │   │ post.html │ (layouts/*.html)
└───────────┘   └───────────┘   └───────────┘

base.html

As previously noted, the base.html itself is an internal file generated by Unibit and has the following structure. If a Unibit theme includes a base.html in the layouts folder it does not override the internal base.html.

The internal base.html (generated by Unibit):

<!doctype html>
<html>
    <head>
        {% include "html_head.html" %}
    </head>
    <body {% if templates.body_class %}class="{{ templates.body_class }}"{% endif %}>
        {% block body %}{% endblock %}
        {% include "post_body.html" %}
    </body>
</html>

body.html

The body.html is a required file and must follow these rules:

  1. Place body.html in the layouts folder
  2. It must extend from base.html
  3. It must define single outer block tag named body
  4. It must define single inner block tag named content, inside the body block

Other content such as HTML markup and other Nunjucks tags can be used as usual.

A minimal body.html example:

{% extends "base.html" %}              {# extends from base.html #}
{% block body %}                       {# defines single outer "body" block #}
    {% block content %}{% endblock %}  {# defines single inner "content" block #}
{% endblock %}

A richer example for body.html could be:

{% extends "base.html" %}

{% block body %}
<div class="container">
    {% include "header.html" %}
    {% block content %}{% endblock %}
    {% include "footer.html" %}
</div>
{% endblock %}

HTML Head & Post Body

The base.html uses 2 special components. These files must be created in the site's components folder and allow you to access areas of the base.html template.

html_head.html - content that will be placed inside the <head> and </head> tags.

<title>{% if page.title %}{{ page.title }} - {% endif %}{{ site.title }}</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link rel="stylesheet" href="{{ 'assets/css/main.css' | relative_url }}">

post_body.html - the content of this component will be included before the closing </body> tag.

<script src="{{ 'assets/js/main.js' | relative_url }}"></script>

Although the same behavior could be achieved by adding content at the bottom of body.html, there is a subtle difference. Content added in post_body.html will be rendered as SSR (server side rendering) when converted to Gatsby and running gatsby develop.

Adding New Layouts

New layout files must be added inside the layouts folder and must extend body.html.

<!- layouts/homepage.html ->

{% extends "body.html" %}
{% block content %}

<h1>{{ site.title }}</h1>
<h2>{{ page.params.sub_heading }}</h2>
{{ page.content  }}
{% endblock %}

Linking Content to Layouts

Unlike other static site generators that infer which layout is used based on where the markdown files are placed in the content directory, Unibit requires that you explicitly set the layout in the front matter.

Every markdown file should have layout parameter that defines which layout file will be used to render the page. In the code example below setting layout: home will use the layout file found in layouts/home.html

---
title: Hello World!
layout: home
----