ssg  
Article Series

Jekyll in General

Jekyll Plain

Where to Discuss?

Local Group

Preface

Goal: More about blog post content: Header, Footer, and Navigation.

Source Code

This article use tutor-11 theme. We will create it step by step.


1: Prepare

This preparation is required.

Preview: General

Consider redesign the looks of blog post. This is what we want to achieve in this tutorial.

Jekyll Content: Preview All Artefacts

Layout: Liquid: Columns Double

We need to redesign _layouts/columns-double.html partial. This layout is also equipped with a partial set in blog_footer.

---
layout : default

# default color
color_main  : blue
color_aside : teal

# layout chuncks
blog_header     : page/blog-header.html
aside_message   : This is a double columns kind layout.
---

{% assign color_main  = page.color_main  | default: layout.color_main %}
{% assign color_aside = page.color_aside | default: layout.color_aside %}

  <main id="main_toggler"
        class="col-md-8 px-0">
    <section id="main_toggler_wrapper"
             class="main-wrapper oc-{{ color_main }}-5">
      <div class="blog oc-white z-depth-3 hoverable">

        <section class="blog-header oc-{{ color_main }}-0">
          {% include {{ layout.blog_header }} %}
        </section>

        <article class="blog-body" itemprop="articleBody">
          {{ content }}
        </article>

        {% if layout.blog_footer %}
        <section class="blog-footer oc-{{ color_main }}-0">
          {% include {{ layout.blog_footer }} %}
        </section>
        {% endif %}

      </div>
    </section>
  </main>

  <aside id="aside_toggler"
         class="col-md-4 px-0">
    {% include {{ layout.aside_content }} %}
  </aside>

Talking about schema, you can read this nice site:

Layout: Liquid: Post

We need to manage the content in _layouts/post.html partial.

---
layout: columns-double

# override color
color_main  : blue
color_aside : teal

# layout chuncks
blog_header     : post/blog-header.html
blog_footer     : post/blog-footer.html
aside_content   : post/aside-content.html
---

{{ content }}
{% include post/navigation.html %}

Jekyll Content: ViM Post Layout

Partials: New Artefacts

The code above require three new partials.

Create three empty partial artefacts,

  • _includes/post/blog-header.html,

  • _includes/post/blog-footer.html,

  • _includes/post/navigation.html.

And one more artefact that is required in post/header.html.

  • _includes/post/time-elapsed.html

SASS: Main

And add relevant stylesheet

// Import partials from `sass_dir` (defaults to `sass/css`)
@import 
  // Heeyeun's Open Color
  "open-color/_open-color-variables",

  // Bootstrap Related
  "../bootstrap/functions",
  "variables",
  "../bootstrap/variables",
  "../bootstrap/mixins/breakpoints",

  // Tailor Made
  "main/layout-page",
  "main/layout-content",
  "main/logo",
  "main/decoration",
  "main/sticky-footer",
  "main/list",
  "main/pagination",
  
  "post/content",
  "post/navigation"
;

We do not really need adjustment in Bootstrap. All seems good.


2: Header

Consider begin with header.

Preview

Jekyll Content: Blog Post Header

Partial: Header: Minimum

The minimum header is simply showing title.

  <header class="p-2"> 
    <div class="main_title"> 
      <h1 class="h4 font-weight-bold" itemprop="name headline">
        <a class="text-dark"
           href="{{ site.url | append:site.baseurl | append:page.url }}"
        >{{ page.title }}</a></h1>
    </div>
  </header>

Partial: Header: Meta

Consider add meta data in post header.

  • Author
      {% if page.author %}
        <span class="badge mr-2 oc-indigo-7 oc-white-text z-depth-1 hoverable">
          <span itemprop="author" itemscope itemtype="http://schema.org/Person">
          <span itemprop="name">
            <i data-feather="user" class="feather-14"></i>&nbsp;
            {{ page.author }}
          </span></span>
        </span>
      {% endif %}
  • Time Elapsed (include partial)
        <span class="badge mr-2 oc-green-7 oc-white-text z-depth-1 hoverable">
          <i data-feather="calendar" class="feather-14"></i>&nbsp;
          {% include post/time-elapsed.html %}
        </span>
  • Tags
      <span class="mr-2">
        {% for tag in page.tags %}
          <a href="{{ site.url | append:site.baseurl }}/pages/tag#{{ tag }}">
            <span class="badge oc-teal-7 oc-white-text z-depth-1 hoverable">
            <i data-feather="tag" class="feather-14"></i>
            &nbsp;{{ tag }}</span></a>
        {% endfor %}
      </span>
  • Categories
      <span class="mr-2">
        {% for cat in page.categories %}
          <a href="{{ site.url | append:site.baseurl }}/pages/category#{{ cat }}">
            <span class="badge oc-teal-7 z-depth-1 hoverable">
            <i data-feather="folder" class="feather-14"></i>
            &nbsp;{{ cat }}</span></a>
        {% endfor %}
        &nbsp;
      </span>

I use bootstrap badge, with the eye candy Feather Icon.

Partial: Header: Complete Code

Here below is my actual code. I use float-left and float-right to arrange the looks.

  <header class="p-2"> 
    <div class="main_title"> 
      <h1 class="h4 font-weight-bold" itemprop="name headline">
        <a class="text-dark"
           href="{{ site.url | append:site.baseurl | append:page.url }}"
        >{{ page.title }}</a></h1>
    </div>

    <div class="clearfix"></div>
    
    <div class="float-left">
      {% if page.author %}
        <span class="badge mr-2 oc-indigo-7 oc-white-text z-depth-1 hoverable">
          <span itemprop="author" itemscope itemtype="http://schema.org/Person">
          <span itemprop="name">
            <i data-feather="user" class="feather-14"></i>&nbsp;
            {{ page.author }}
          </span></span>
        </span>
      {% endif %}
        <span class="badge mr-2 oc-green-7 oc-white-text z-depth-1 hoverable">
          <i data-feather="calendar" class="feather-14"></i>&nbsp;
          {% include post/time-elapsed.html %}
        </span>
    </div>
    <div class="float-right">
      <span class="mr-2">
        {% for cat in page.categories %}
          <a href="{{ site.url | append:site.baseurl }}/pages/category#{{ cat }}">
            <span class="badge oc-teal-7 z-depth-1 hoverable">
            <i data-feather="folder" class="feather-14"></i>
            &nbsp;{{ cat }}</span></a>
        {% endfor %}
        &nbsp;
      </span>
      <span class="mr-2">
        {% for tag in page.tags %}
          <a href="{{ site.url | append:site.baseurl }}/pages/tag#{{ tag }}">
            <span class="badge oc-teal-7 oc-white-text z-depth-1 hoverable">
            <i data-feather="tag" class="feather-14"></i>
            &nbsp;{{ tag }}</span></a>
        {% endfor %}
      </span>
    </div>

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

3: Elapsed Time

As it has been mentioned above, we need special partial for this.

Issue

As a static generator, jekyll build the content whenever there are any changes. If there are no changes, the generated time remain static. It means we cannot tell relative time in string such as three days ago, because after a week without changes, the time remain three days ago, not changing into ten days ago.

The solution is using javascript. You can download the script from here

That way the time ago is updated dynamically as time passes, as opposed to having to rebuild jekyll every day.

Do not forget to put the script in static directory.

Partial: Time Elapsed

    <time datetime="{{ page.date | date_to_xmlschema }}" 
          itemprop="datePublished">
    <span class="timeago"
          datetime="{{ page.date | date: "%Y-%m-%d %T" }}">
    </span></time>
    &nbsp; 

    <script src="{{ site.baseurl }}/assets/js/timeago.min.js"></script>
    <script type="text/javascript">
      var timeagoInstance = timeago();
      var nodes = document.querySelectorAll('.timeago');
      timeagoInstance.render(nodes, 'en_US');
      timeago.cancel();
      timeago.cancel(nodes[0]);
    </script>

We already have header. Why do not we continue with footer?

Preview

Jekyll Content: Blog Post Footer

  <footer class="p-2 mb-4">
    <div class="d-flex flex-row justify-content-center align-items-center">

      <div class="p-2 text-center">
        <img src="{{ site.baseurl }}/assets/images/license/cc-by-sa.png" 
             class="bio-photo" height="31" width="88"
             alt="CC BY-SA 4.0"></a>
      </div>

      <div class="p-2">
        This article is licensed under:<br/>
        <a href="https://creativecommons.org/licenses/by-sa/4.0/deed" 
           class="text-dark">
          <b>Attribution-ShareAlike</b> 4.0
          International (CC BY-SA 4.0)</a>
      </div>

    </div>
  </footer>

Assets: License

I have collect some image related with license, so that you can use license easily.


5: Post Navigation

Each post also need simple navigation.

Preview

Jekyll Content: Blog Post Navigation

Partial: Navigation

By default, jekyll have built in function, to handle post navigation, using:

  1. page.previous, and

  2. page.next.

  <ul class="pagination justify-content-between" 
      role="navigation" aria-labelledby="pagination-label">

      {% if page.previous %}
      <li class="page-item post-previous">
        <a class="page-link" 
           href="{{ page.previous.url | prepend: site.baseurl }}"
           title="{{ page.previous.title }}">
           <i data-feather="chevron-left"></i>
        </a>
      </li>
      {% endif %}

      {% if page.next %}
      <li class="page-item post-next">
        <a class="page-link" 
           href="{{ page.next.url | prepend: site.baseurl }}" 
           title="{{ page.next.title }}">
           <i data-feather="chevron-right"></i>
        </a>
      </li>
      {% endif %}

  </ul>

SASS: Post Navigation

Code above require two more classes

  1. post-previous

  2. post-next

// -- -- -- -- --
// _post-navigation.sass

li.post-previous a:after {
  content: " previous";
}

li.post-next a:before {
    content: "next ";
}

.blog-body .pagination {
  margin-top: 1rem;
  margin-bottom: 1rem;
}

.


6: Before Content: Table of Content

Sometimes we need to show recurring content, such as table of content in article series. For article series, we only need one TOC. And we do not want to repeat ourself, writing it over and over again.

To solve this case, we need help form frontmatter.

Layout: Liquid: Post

We are going to insert TOC, before the content, by including toc something partial, provided from frontmatter.

We need to manage the content in _layouts/post.html partial.

---
...
---

{% if page.toc %}
  {% include {{ page.toc }} %}
{% endif %}

{{ content }}

{% include post/navigation.html %}

Page Content: Example Frontmatter

Now here it is, the TOC in frontmatter, as shown in this example below.

---
layout      : post
title       : Brooke Annibale - By Your Side
...

related_link_ids :
  - 19052535  # Yours and Mine
---

...

Layout: Liquid: TOC

Now you can have your TOC here.

  <div class="white hoverable py-1">
    <div class="widget-header oc-blue-1">

      <strong>Table of Content</strong>
      <i data-feather="link-2" class="float-right"></i>

    </div>
    <div class="widget-body oc-blue-0">

      <ul class="widget-list">
        <li><a href="{{ "/lyric/2019/05/25/brooke-annibale-yours-and-mine.html"
                    | prepend: site.baseurl | prepend: site.url }}"
              >Brooke Annibale - Yours and Mine</a></li>
        <li><a href="{{ "/lyric/2019/05/15/brooke-annibale-by-your-side.html"
                    | prepend: site.baseurl | prepend: site.url }}"
              >Brooke Annibale - By Your Side</a></li>
      </ul>

    </div>
  </div>

Notice the .html file extension. We are still using liquid. This HTML document is, actually a liquid document.

Render: Browser

Now you can see the result in the browser.

Jekyll Raw HTML: Table of Content


7: Toggler

Sometimes the audience of our blog need a wider view. We can arrange it with javascript toggler. You can read the detail here:

Layout: Liquid: Post

Our complete layout would be

---
layout: columns-double

# override color
color_main  : blue
color_aside : teal

# layout chuncks
blog_header     : post/blog-header.html
blog_footer     : post/blog-footer.html
aside_content   : post/aside-content.html
---

{% include post/toggler.html %}

{% if page.toc %}
  {% include {{ page.toc }} %}
{% endif %}

{{ content }}

{% include post/navigation.html %}

Render: Browser

The toggle will be shown in desktop screen. And hidden in mobile screen.


8: Conclusion

It is enough for now. There are many part that can be enhanced, in about content area.

After all, it is about imagination.


What is Next?

Consider continue reading [ Jekyll Bootstrap - Content ].

Thank you for reading.