ssg  

Preface

Goal: Create custom page to create landing page, and terms list.

Making custom page in Hexo is easy. The only known limitation is all custom page must follow basic layout.

Table of Content

  • Preface: Table of Content

  • 1: Landing Page

  • 2: Tags

  • 3: Categories

  • What is Next ?

Source Code

You can download the source code of this article here.

Extract and run on CLI:

$ npm install

1: Landing Page

The easier way to understand custom page is to give simple example. Our previous article has stated that the main page has sidebar, because it use page.ejs.

We can make special template so that it has no sidebar, but only full width content.

Layout: EJS Landing Page

<main role="main" 
     class="column is-full blog-column box-deco
            has-background-white has-text-centered">
  <article class="blog-post">
    <h1 class="title is-4"><%= config.author %></h1>
    <h2 class="subtitle is-4"><%= config.subtitle %></h2>
    
    <%- page.content %>
  </article>
</main>

Content: Index

It is time apply this kind of custom page layout. All you need to do is add layout in frontmatter.

layout: kind/landing

We also need to modify main page content, to make it more like a landing page. I don’t know how to make a pretty landing page, so I put business card instead.

---
layout: kind/landing
title: Welcome to Heartbeat
---

  <div class="justify-content-center">
    <img src="site/images/adverts/one-page.png" 
         class="bio-photo" 
         alt="business card">
  </div>

  <p>Every journey begins with a single step.</p>

Render: Browser

Open in your favorite browser. Your landing page is ready.

Hexo Bulma: Landing Page

As I promised before, nomore sidebar.


2: Tags

Remember that Hexo default provide this links ?

But why can’t we have this summary as one ?

Consider walking further for a different kind of custom page layout, that provide list of tags. The URL would be as below:

Layout: EJS Simple Tags List

  • themes/tutor-03/layout/kind/tags.ejs
<main role="main" 
      class="column is-full box-deco has-background-white">

  <section class="section">
    <h1 class="title is-4"><%= config.author %></h1>
    <h2 class="subtitle is-4"><%= config.subtitle %></h2>

    <h3 class="title is-3"><%= page.title %></h3>
  </section>

  <% site.tags.each(function(item){ %>
    <div id="<%= item.name %>">
      <p><%= __('tag') %>: 
        <a href="<%- url_for(item.path) %>">
        <%= item.name %></a>
      </p>
    </div>
  <% }) %>
</main>

.

Content: Tags

Custom page is not enough. We need content.

---
layout: kind/tags
title: Tags
---

Render: Browser

Open in your favorite browser. You should see, a post, with sidebar.

Hexo: Custom Page: Simple Tag List

The Loop

How Does It Works?

The simplified range loop, is as below:

  <% site.tags.each(function(item){ %>
    ...
    <%= item.name %>
    ...
  <% }) %>

Layout: EJS Tags with Tree

Why don’t we go further, giving tree view for this tag list. Every tag should show thier post list.

<main role="main" 
      class="column is-full box-deco has-background-white">

  <section class="section">
    <h1 class="title is-4"><%= config.author %></h1>
    <h2 class="subtitle is-4"><%= config.subtitle %></h2>

    <h3 class="title is-3"><%= page.title %></h3>
  </section>

  <% site.tags.each(function(item){ %>
  <section class="section">
    <div id="<%= item.name %>">
      <p><%= __('tag') %>: 
      <a href="<%- url_for(item.path) %>">
      <%= item.name %></a></p>
    </div>

    <ul>
    <% item.posts.each(function(post){ %>
      <li>
        <div class="is-pulled-left">
          <a href="<%- url_for(post.path) %>">
          <%= post.title %>
        </a></div>
        <div class="is-pulled-right has-text-right"><time>
          <%= date(post.date, "DD MMM") %>&nbsp;
        </time></div>
        <div class="is-clearfix"></div>
      </li>
    <% }) %>
    </ul>
  </section>
  <% }) %>
</main>

.

Render: Browser

Open in your favorite browser.

Hexo: Custom Page: Tag List with Tree

It is still simple, but pretty enough.

The Loop

How Does It Works?

The range loop, is consist of inner and outer loop as below:

  <% site.tags.each(function(item){ %>
    ...
    <%= item.name %>
    ...
    <% item.posts.each(function(post){ %>
      ...
      <%= post.title %>
      ...
    <% }) %>
    ...
  <% }) %>

3: Categories

The same method applied to categories.

Does it looks like repetitive, copy paste the same code? Don’t worry it just temporary. We are going to refactor in the next section.

Layout: EJS Categories List with Tree

<main role="main" 
      class="column is-full box-deco has-background-white">

  <section class="section">
    <h1 class="title is-4"><%= config.author %></h1>
    <h2 class="subtitle is-4"><%= config.subtitle %></h2>

    <h3 class="title is-3"><%= page.title %></h3>
  </section>

  <% site.categories.each(function(item){ %>
  <section class="section box">
    <div id="<%= item.name %>">
      <p><%= __('category') %>: 
        <a href="<%- url_for(item.path) %>"
           class="button is-small">
        <%= item.name %></a>
      </p>
    </div>

    <ul>
    <% item.posts.each(function(post){ %>
      <li>
        <div class="is-pulled-left">
          <a href="<%- url_for(post.path) %>">
          <%= post.title %>
        </a></div>
        <div class="is-pulled-right has-text-right"><time>
          <%= date(post.date, "DD MMM") %>&nbsp;
        </time></div>
        <div class="is-clearfix"></div>
      </li>
    <% }) %>
    </ul>
  </section>
  <% }) %>
</main>

.

Content: Categories

again, custom page is not enough. We still need content to make this works.

---
layout: kind/categories
title: Categories
---

Render: Browser

Open in your favorite browser.

Hexo: Custom Page: Category List with Tree


What is Next ?

There are, some interesting topic about Custom Page in Hexo. Consider continue reading [ Hexo - Custom Page Refactored ].

Thank you for reading.