ssg  
Where to Discuss?

Local Group

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.

11ty: Page Content: Simple Blog List


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 }}&nbsp;<span class="fa fa-folder"></span>
            </a>&nbsp;
          {%- 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.

11ty: Page Content: Blog List with Meta


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

11ty: Shortcode: simple example


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&nbsp;</a>
      </div>

    </div></div>
  {%- endfor -%}
  </div>

I also add read more button.

Render: Browser

The blog list, now looks like this below:

11ty: Page Content: Blog List with Excerpt


What is Next ?

Consider continue reading [ Eleventy - Custom Output ]. We are going to make an archive in JSON form.

Thank you for reading.