Preface
Goal: Getting started with layout using Nunjucks templating engine.
Layout enable you to create many kind of page template, such as page kind, post kind, landing page (home kind), or archive page.
Source Code
This article use tutor-02 theme. We will create it step by step.
Official Site.
Layout Preview for Tutor 02
0: Theme Making
Consider to have a look at the big picture below:
1: Configuration
Consider go straight away to templating engine called nunjucks
.
In order to use nunjucks, we need to alter the configuration a bit.
.eleventy.js
module.exports = function(eleventyConfig) {
// Return your Config object
return {
// URL Related
pathPrefix: "/",
// Templating Engine
templateFormats: [
"md",
"njk",
"html"
],
markdownTemplateEngine: false,
htmlTemplateEngine: "njk",
dataTemplateEngine: false,
// Directory Management
dir: {
// default
input: "views",
output: "_site",
// ⚠️ This value is relative to your input directory.
includes: "_includes",
}
};
};
What’s New Here?
- Utilize markdown as an article
templateFormats: [
"md",
"njk",
"html"
],
- Treat
pages/archive.html
as anunjucks
template.
markdownTemplateEngine: false,
htmlTemplateEngine: "njk",
dataTemplateEngine: false,
2: Refactor
Directory Tree: Includes
Consider create each artefacts manually.
$ tree views/_includes
views/_includes
├── layouts
│ ├── base.njk
│ ├── page.njk
│ └── post.njk
└── site
├── footer.njk
├── header.njk
└── head.njk
2 directories, 6 files
Layout: Nunjucks Base
Instead of put everything in one html
file,
we can separate each html
part in different nunjucks
file,
and call them using include
.
<html>
<head>
{% include "site/head.njk" %}
</head>
<body>
{% include "site/header.njk" %}
<main role="main">
{% block main %}{% endblock %}
</main>
{% include "site/footer.njk" %}
</body>
</html>
And three include
s:
-
head
, -
header
, -
footer
.
We are going to replace {% block main %}{% endblock %}
,
in both page.njk
and post.njk
.
Partial: Nunjucks Head
We can use default title, if there is no title available, in frontmatter.
<title>{{ title or "Your mission. Good Luck!" }}</title>
Partial: Nunjucks Header
<blockquote>
<i>Your mission, should you decide to accept it.</i>
</blockquote>
Partial: Nunjucks Footer
<blockquote>
<i>As always, should you be caught or killed,
any knowledge of your actions will be disavowed.</i>
</blockquote>
Layout: Nunjucks Page
Template inheritance in nunjucks
,
start with the word extends
.
{% extends "layouts/base.njk" %}
{% block main %}
<h2>{{ title }}</h2>
<strong>This is a page kind layout.</strong>
<br/>
{{ content | safe }}
{% endblock %}
Layout: Nunjucks Post
Template inheritance in nunjucks
,
start with the word extends
.
{% extends "layouts/base.njk" %}
{% block main %}
<h2>{{ title }}</h2>
<pre>{{ page.date }}</pre>
<br/>
<strong>This is a post kind layout.</strong>
<br/>
{{ content | safe }}
{% endblock %}
I add {{ page.date }}
to differ post
kind and page
kind.
Finally
We are done with simple refactoring.
These simple snippets, show how nunjucks
works.
Especially template inheritance.
3: Pages and Posts
We are freely to make any kind of pages. Here we make two common blog page kind:
-
Page Kind
-
Post Kind
Remember, that in configuration,
every html
file is actually using nunjucks
template engine.
Directory Tree: Includes
Consider create each artefacts manually.
$ tree views/ -I '_includes'
views/
├── index.html
├── pages
│ ├── about.md
│ └── archive.html
└── posts
└── every-day.md
2 directories, 4 files
Page Content: index
It is actually very similar with previous index.html
.
---
layout : layouts/page
eleventyExcludeFromCollections: true
---
<p>To have, to hold, to love,
cherish, honor, and protect?</p>
<p>To shield from terrors known and unknown?
To lie, to deceive?</p>
<p>To live a double life,
to fail to prevent her abduction,
erase her identity,
force her into hiding,
take away all she has known.</p>
What’s new here is, we don’t want this page to be included in collections.
eleventyExcludeFromCollections: true
Page Content: pages/about
This is a markdown file artefact, with frontmatter.
---
layout : layouts/page
title : About Rescue Mission
---
This was not a rescue mission!
Let me put to you like this.
If the secretary wanted me out of there,
then things are really bad out here.
Page Content: pages/archive
It is clear that this one is using nunjucks
template engine.
With permalink
in frontmatter, you can render the page,
from view/pages/archive.html
to _site/pages/index.html
---
layout : layouts/page
title : Archive
permalink : /pages/
eleventyExcludeFromCollections: true
---
<ul>
{%- for post in collections.all | reverse -%}
<li>
<a href="{{ post.url | url }}">
{{ post.data.title }}</a>
</li>
{%- endfor -%}
</ul>
Pay attention to the loop.
{% for post in collections.all %}
...
{% endfor %}
You can try to set eleventyExcludeFromCollections: false
,
and see what’s happened.
Post Content: posts/every-day
And this one has some more information in frontmatter.
---
layout : layouts/post
title : Every Day
date : 2015-10-03 08:08:15
slug : every-day
tags : ['subtitle', 'story']
---
I've been thinking about this
over and over and over.
<!-- more -->
I mean, really, truly,
imagine it.
Local Render
You might want to see how it works by looking at the _site
directory.
$ tree _site
_site
├── index.html
├── pages
│ ├── about
│ │ └── index.html
│ └── index.html
└── posts
└── every-day
└── index.html
4 directories, 4 files
What’s in your browser is what rendered in _site
.
4: Default Variable
We can set variable in frontmatter, and in content. But you need to be aware of the differences between this two method.
Layout: Nunjucks Color
Consider this example layout below:
<html>
<head>
{% include "site/head.njk" %}
</head>
<body>
{# use default unless available #}
{% set color = color or 'brown' %}
<main role="main">
<p><i>This is a variable propagation test.</i></p>
{{ content | safe }}
<p>In this layout, color is <b>{{ color }}</b>.</p>
</main>
</body>
</html>
This layout will read color
variable from page
,
or using brown
color as default, if it cannot find any color.
{% set color = color or 'brown' %}
Page Content: pages/color-test-01
This page set color
in frontmatter.
---
layout : layouts/color
title : Test Color in Frontmatter
eleventyExcludeFromCollections: true
color : red
---
<p>In this content, color is <b>{{ color }}</b>.</p>
Page Content: pages/color-test-02
This page set color
in frontmatter.
---
layout : layouts/color
title : Test Color in Content
eleventyExcludeFromCollections: true
---
{% set color = 'indigo' %}
<p>In this content, color is <b>{{ color }}</b>.</p>
Both method have different result.
As you can see, both have different result. This difference behavior in nunjucks has advantage, that you can choose, whether you want the layout and content, has the same color, or different color. We will explore this advantage later.
What is Next ?
Consider continue reading [ Eleventy - Configuration ]. Still with pure HTML without any stylesheet. We are going to add most common configuration, that required to make a simple site.
Thank you for reading.