ssg  
Article Series

Jekyll in General

Jekyll Plain

Where to Discuss?

Local Group

Preface

Goal: Using simple template inheritance with Liquid in Jekyll Layout.

This is going to be a long article, because I pour all the code here intentionally, so that we do not need to rewrite down, all of the relationship all over again, for the rest of the tutorial.

Source Code

This article use tutor-08 theme.

Related Article: CSS

This article is not a CSS tutorial, but rather than applying simple CSS theme, into jekyll layout.

The CSS part of this article is, already discussed in this SASS article below. The only different is that I use plain CSS instead of SASS.


6: Layout: Blog

Pattern

Can you see the pattern?

We have very similar pages with the Bootstrap’s double columns layout, and we write down the same layout over and over again in each layout: post, page, archive by year, archive by month, tags, tag-names, categories and who knows how this site will grow later.

Liquid is a powerful templating engine, and capable to solve this situation. We do not need to exhaustingly repeat ourselves.

Since page layout is already a double column layout, we can utilize this layout as a parent for other layout. This is exactly the same with previous pattern in the article.

The page based on layout, and that layout call a partial include. The Bootstrap part html formatting lies in partial include.

Page Content: Blog

---
layout    : blog
title     : Blog Posts
permalink : /pages/
---

We can say that this content wear blog layout.

Layout Liquid: Blog

---
layout: page
---

{% assign posts = site.posts %}
{% include index/blog-list.html %}

This layout is a child of page layout.

Partial Liquid: Blog List

This is the Bootstrap View Part.

We have one partial HTML view for this layout.

  <div>
  {% for post in posts %}
    <div class="archive pb-2">
    <div class="p-2">

      <div class="meta">
        <div class="float-left">
          <a class="text-dark"
             href="{{ post.url | prepend: site.baseurl }}"
            >{{ post.title }}
          </a>
        </div>
        <div class="float-right">
          {% for tag in post.tags %}
          <span class="badge badge-dark">
            <a class="text-light"
               href="{{ site.baseurl }}/tags/#{{ tag | slugify }}"
              >{{ tag }}&nbsp;<i data-feather="tag" class="feather-14"></i>
            </a></span>&nbsp;
          {% endfor %}
        </div>
      </div> 

      <div class="clearfix"></div>

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

Jekyll Bootstrap: Blog List


7: Layout: Taxonomy

With the method above, we can rewrite the all other layouts as well.

Partial Liquid: Terms

This is the Bootstrap View Part.

We have two partial HTML views for this layout: terms-badge for top summary, and terms-tree for details.

  <div class="py-3">
  {% for item in (0..terms.size) %}{% unless forloop.last %}
    {% assign this_word = term_array[item] | strip_newlines %}
    <span>
      {{ $posts := where $value.Pages "Type" "post" }}
      {{ $postCount := len $posts -}}
      <a href="#{{ this_word | slugify }}">
        <span class="badge badge-dark">
          {{ this_word }} 
          <span class="badge badge-light">
          {{ terms[this_word].size }}
          </span>
        </span>
      </a>
    </span>
    &nbsp;
  {% endunless %}{% endfor %}
  </div>
  <section class="py-1" id="archive">
  {% for item in (0..terms.size) %}{% unless forloop.last %}
    {% assign this_word = term_array[item] | strip_newlines %}
      <div id="{{ this_word | slugify }}" class ="anchor-target">
        <strong>{{ this_word }}</strong>
      </div>

      <div class="py-1">
      {% for post in terms[this_word] %}
        {% if post.title != null %}
        <div>
          <div class="has-text-right">
            <time class="float-right"
                  datetime="{{ post.date | date_to_xmlschema }}">
              {{ post.date | date: "%b %-d, %Y" }}
            </time></div>
          <div class="float-left">
          <a href="{{ post.url | prepend: site.baseurl }}">
            {{ post.title }}
          </a></div>
          <div class="clearfix"></div>
        </div>
        {% endif %}
      {% endfor %}
      </div>

  {% endunless %}{% endfor %}
  </section>

Jekyll Bootstrap: ViM Terms Tree

As you can see there is almost nothing happened in each page content. Most have been done within the _includes/index/terms-tree.html partial, using default Bootstrap stylesheet feature. It means, whenever any changes happened, you only need to rewrite this partial view.

Template inheritance is very useful in this case.

Page Content: Categories

---
layout    : list-category
title     : All Categories
permalink : /categories/
---

Layout Liquid: Category List

---
layout: page
---

{% assign terms = site.categories %}
{% include index/terms-array.html %}
{% include index/terms-badge.html %}
{% include index/terms-tree.html %}

As usual, this layout is also a child of page layout.

Jekyll Bootstrap: Categories with Tree Details

Page Content: Tags

---
layout    : blog
title     : Blog Posts
permalink : /pages/
---

Layout Liquid: Tag List

---
layout: page
---

{% assign posts = site.posts %}
{% include index/blog-list.html %}

As usual, this layout is also a child of page layout.

Jekyll Bootstrap: Tags with Tree Details


8: Layout: Grouped Archives

The same relationship applied to archive. The page based on layout, and that layout call a partial include.

Making a grouping archive by month and year is not hard, it just need carefully carved with patient. We are going to build archive by month, but since it has a complex logic, we are going to start from simple using archive by-year.

Page Content: Archive By Year

---
layout    : by-year
title     : Archive by Year
permalink : /by-year/
---

Layout Liquid: Archive By Year

---
layout: page
---

{% assign posts = site.posts %}
{% include index/by-year.html %}

This layout is a child of page layout.

Partial Liquid: Archive By Year

This is the Bootstrap View Part

As usual, we setup the liquid logic first.

{% assign postsByYear = posts
          | group_by_exp: "post", "post.date | date: '%Y'"  %}

<div id="archive">
{% for year in postsByYear %}

  {% capture spaceless %}
    {% assign current_year = 'now' | date: '%Y' %}
    {% assign year_text = nil %}

    {% if year.name == current_year %}
      {% assign year_text = year.name
                | prepend: "This year's posts (" | append: ')' %}
    {% else %}
      {% assign year_text = year.name %}
    {% endif %}
  {% endcapture %}

  <section>
    ...
  </section>

{% endfor %}
</div>

And then, fill the view with HTML elements, along with bootstrap class.

  <section>
    <p class ="anchor-target" 
       id="{{ year.name }}"
      >{{ year_text }}</p>

    <div class="py-1">
      {% for post in year.items %}
      <div>
        <div class="float-left">
          <a href="{{ site.baseurl }}{{ post.url }}">
          {{ post.title }}
        </a></div>
        <div class="float-right text-right">
        <time>
            {{ post.date | date:"%d %b" }}&nbsp;
        </time></div>
        <div class="clearfix"></div>
      </div>
      {% endfor %}
    </div>
  </section>

Jekyll Bootstrap: Archive By Year

Page Content: Archive By Month

---
layout    : by-month
title     : Archive by Month
permalink : /by-month/
---

Layout Liquid: Archive By Month

---
layout: page
---

{% assign posts = site.posts %}
{% include index/by-month.html %}

This layout is a child of page layout.

Partial Liquid: Archive By Month

This is the Bootstrap View Part

As usual, we setup the liquid logic first.

{% assign postsByYear = posts
          | group_by_exp: "post", "post.date | date: '%Y'"  %}

<div id="archive">
{% for year in postsByYear %}

  {% capture spaceless %}
    {% assign current_year = 'now' | date: '%Y' %}
    {% assign year_text = nil %}

    {% if year.name == current_year %}
      {% assign year_text = year.name 
                | prepend: "This year's posts (" | append: ')' %}
    {% else %}
      {% assign year_text = year.name %}
    {% endif %}
  {% endcapture %} 

  <section>
    <p class ="anchor-target mb-0"
         id="{{ year.name }}"><b>{{ year_text }}</b></p>

    {% assign postsByMonth = year.items
              | group_by_exp:"post", "post.date | date: '%m'"
              | sort: 'name'
              | reverse %}

    {% for month in postsByMonth %}

    <div class="py-1">
      ...
    </div>

    {% endfor %}
  </section>

{% endfor %}
</div>

And then, fill the view with HTML elements, along with bootstrap class.

    <div class="py-1">

      {% for post in month.items limit:1 %}
      <div id="{{ year.name }}-{{ month.name }}">
           {{ post.date | date: '%b - %Y' }}</div>
      {% endfor %}

      <div class="py-1">
        {% for post in month.items %}
        <div>
          <div class="float-left">
          <a class="text-dark"
             href="{{ site.baseurl }}{{ post.url }}">
            {{ post.title }}
          </a></div>
          <div class="float-right has-text-right"><time>
              {{ post.date | date:"%d %b" }}
          </time></div>
          <div class="clearfix"></div>
        </div>
        {% endfor %}
      </div>
    </div>

Jekyll Bootstrap: Archive By Month

I know this is a long article, to remind the reader about the relationship, between pages, layout and partial include. The next article should be shorter, focusing on stylesheet stuff.


What is Next?

Consider continue reading [ Jekyll Bootstrap - SASS Intro ].

Thank you for reading.