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 }} <i data-feather="tag" class="feather-14"></i>
</a></span>
{% endfor %}
</div>
</div>
<div class="clearfix"></div>
</div></div>
{% endfor %}
</div>
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>
{% 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>
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.
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.
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" }}
</time></div>
<div class="clearfix"></div>
</div>
{% endfor %}
</div>
</section>
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>
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.