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 (private)

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>

Note: If you create your own base.html and place it in the layouts folder it will do nothing.

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.

Example:

{% 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 needs 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 from this component will be placed inside the <head> and </head> tags.

<!-- components/html_head.html -->

<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

Content from this component will be included before the closing </body> tag.

<!-- components/post_body.html -->

<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

# content/index.md

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