Preface
Goal: Build blog list, an article index with different looks.
Source Code
This article use tutor-06 theme. We will create it step by step.
1: Layout: Blog
I need to be creative, so I put more than one design to represent my blog list. What I mean is, you don’t need to be stuck in just one layout design. And then, you can make your own layout design.
Layout: Nunjucks Blog
First we need to create new Layout.
{% extends "layouts/columns-double.njk" %}
{% block main_color %}brown{% endblock %}
{% block aside_color %}light-green{% endblock %}
{% block widget_body %}
<p>This is a blog kind layout.
This layout is intended to show blog list.</p>
{% endblock %}
.eleventy.js
And also set a new alias.
eleventyConfig.addLayoutAlias("blog", "layouts/blog.njk");
2: Views: Simple
Start with simple example
Partial: Nunjucks: Simple
Consider, add a page content to layout as below.
<div class="archive-list">
{%- for post in posts -%}
{% include "index/each-post.njk" %}
{%- endfor -%}
</div>
Where the posts
is defined in content page.
Page Content: Nunjucks: pages/blog
Now let’s you have yourself your simple index pages.
And our old content page would be as simple as this code below:
---
layout : blog
title : Blog List
permalink : /pages/
eleventyExcludeFromCollections: true
---
{%- set posts = collections.posts -%}
{%- set posts = posts | sort(false, true, 'date') | reverse -%}
{% include "index/blog-simple.njk" %}
Since there is no grouping required with pagination, the sorting process should be is easier. We just need to sort by date field for each post object.
Render: Browser
Now you can see the result in your favorite browser.
3: Views: Meta
I usually use this blog post design, in conjuction with pagination. For this pagination page, I need to show excerpt, and some also necessary meta information for each post. There is no grouping required for pagination pages.
Page Content: Nunjucks: pages/blog
Change the pages/blog
content to use index/blog-list
{%- set posts = collections.posts -%}
{%- set posts = posts | sort(false, true, 'date') | reverse -%}
{% include "index/blog-list.njk" %}
Partial: Nunjucks: Blog List
Consider, move the page content to layout as below.
<div class="post-list">
{%- for post in posts -%}
<div class="archive p-b-10">
<div class="meta-item p-10 hoverable">
<strong><a class="meta_link brown-text text-darken-3"
href="{{ post.url | url }}">{{ post.data.title }}
</strong></a>
{% include "index/blog-each-meta.njk" %}
</div></div>
{%- endfor -%}
</div>
Where the posts
is defined in content page.
Partial: Nunjucks: Each Meta
Each meta can be represent as nunjucks
template below:
<div class="meta">
<div class="meta_time is-pulled-left">
<i class="fa fa-calendar"></i>
<time datetime="{{ post.date | date() }}">
{{ post.date | date('MMM D, Y') }}</time>
</div>
<div class="meta_tags is-pulled-right">
{%- for tag in post.data.tags -%}
{%- set tagUrl %}/tags/{{ tag }}/{% endset -%}
<a class="tag is-small is-dark brown z-depth-1 hoverable"
href="{{ tagUrl | url }}"
>{{ tag }} <span class="fa fa-folder"></span>
</a>
{%- endfor -%}
</div>
</div>
<div class="is-clearfix"></div>
Where the post
is defined in blog-list
layout.
Render: Browser
Now you can see the result in your favorite browser.
4: Shortcode: Simple Example
We need to understand what shortcode is using simple example.
Official Documentation
Simple Shortcode
Using fat arrow in javascript as function return equivalent.
exports.showText = (doc) => {
return 'This is an example shortcode.';
}
Page Content: Jerry Maguire
And put it somewhere inside one of your content:
---
layout : post
title : Jerry Maguire
date : 2015-01-01 17:35:15
tags : ['subtitle', 'story']
---
You had me at Hello.
{% exampleShortcode %}
Render: Browser
Then you’ll see
5: Shortcode: Excerpt
We also can utilize shortcode, to manage excerpt.
Verbatim Copy
The excerpt shortcode that use is, verbatim copy of code made by Philipp Rudloff.
Source Code
const excerptMinimumLength = 140;
const excerptSeparator = ''
/**
* Extracts the excerpt from a document.
*
* @param {*} doc A real big object full of all sorts of information about a document.
* @returns {String} the excerpt.
*/
exports.extractExcerpt = (doc) => {
if (!doc.hasOwnProperty('templateContent')) {
console.warn('Failed to extract excerpt: Document has no property `templateContent`.');
return;
}
const content = doc.templateContent;
if (content.includes(excerptSeparator)) {
return content.substring(0, content.indexOf(excerptSeparator)).trim();
}
else if (content.length <= excerptMinimumLength) {
return content.trim();
}
const excerptEnd = findExcerptEnd(content);
return content.substring(0, excerptEnd).trim();
}
/**
* Finds the end position of the excerpt of a given piece of content.
* This should only be used when there is no excerpt marker in the content (e.g. no `<!--more-->`).
*
* @param {String} content The full text of a piece of content (e.g. a blog post)
* @param {Number?} skipLength Amount of characters to skip before starting to look for a `</p>`
* tag. This is used when calling this method recursively.
* @returns {Number} the end position of the excerpt
*/
function findExcerptEnd(content, skipLength = 0) {
if (content === '') {
return 0;
}
const paragraphEnd = content.indexOf('</p>', skipLength) + 4;
if (paragraphEnd < excerptMinimumLength) {
return paragraphEnd + findExcerptEnd(content.substring(paragraphEnd), paragraphEnd);
}
return paragraphEnd;
}
- .
Page Content: Jerry Maguire
And put it somewhere inside one of your content:
---
layout : post
title : Jerry Maguire
date : 2015-01-01 17:35:15
tags : ['subtitle', 'story']
excerpt : "Show me the money!"
---
You had me at Hello.
<!--more-->
You complete me.
With code above we have two options.
We can either use <!--more-->
, or the first paragraph.
6: Views: Excerpt
Consider complete this blog list view with these excerpt solution.
Excerpt form Frontmatter
I prefer the third option, to manage excerpt from frontmatter.
layout : post
title : Jerry Maguire
date : 2015-01-01 17:35:15
tags : ['subtitle', 'story']
excerpt : "Show me the money!"
Partial: Nunjucks: Blog List
Consider, move the page content to layout as below.
<div class="post-list">
{%- for post in posts -%}
<div class="archive p-b-10">
<div class="meta-item p-10 hoverable">
<strong><a class="meta_link brown-text text-darken-3"
href="{{ post.url | url }}">{{ post.data.title }}
</strong></a>
{% include "index/blog-each-meta.njk" %}
<div>
{% if post.data.excerpt %}
{{ post.data.excerpt }}
{% else %}
{% excerpt post %}
{% endif %}
</div>
<div class="read-more is-light">
<a href="{{ post.url | url }}"
class="button is-dark is-small brown z-depth-1 hoverable"
>Read More </a>
</div>
</div></div>
{%- endfor -%}
</div>
I also add read more
button.
Render: Browser
The blog list, now looks like this below:
What is Next ?
Consider continue reading [ Eleventy - Custom Output ]. We are going to make an archive in JSON form.
Thank you for reading.