ssg  

Preface

Goal: Custom content output example: json, text, yaml

There is no such thing as custom output in Hexo. We cannot just do it natively without plugin.

But there is a trick do it. These takes a few steps.

Table of Content

  • Preface: Table of Content

  • 1: Inside HTML Template

  • 2: Prepare: Default Template

  • 3: Plain Text

  • 4: JSON

  • 5: Summary

  • What is Next ?

Source Code

You can download the source code of this article here.

Extract and run on CLI:

$ npm install

1: Inside HTML Template

This is the ugliest trick.

Supposed you need to extract data from your blog in yaml format, you can put it inside a pre element.

Layout: EJS Archives YAML Inside HTML

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

<pre>
# Helper for related links
# <%= page.title %>

<% site.posts.each(function(post){ %>
- id: <%= date(post.date, "YYMMDDmm") %>
  title: "<%= post.title %>"
  url: <%= post.path %>
<% }) %>
</pre>

  </article>
</main>

Content: Archives YAML Inside HTML

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

---
layout: kind/yaml
title: Archives
---

Render: Browser

Open in your favorite browser.

Hexo Bulma: Archives YAML Inside HTML

This will show something similar as below:

# Helper for related links
# Archives

...

- id: 15051535
  title: "Susan Wong - I Wish You Love"
  url: 2015/05/15/lyrics/natalie-cole-i-wish-you-love/

- id: 18091335
  title: "Norah Jones - Shoot The Moon"
  url: 2018/09/13/lyrics/norah-jones-shoot-the-moon/

...

We need to get rid of the HTML tag, and get pure YAML.


2: Prepare: Default Template

This preparation is required

Layout: EJS Layout

We need to ignore original layout whenever needed.

  • themes/tutor-04/layout/layout.ejs
    [gitlab.com/…/layout/layout.ejs][tutor-layout-layout]
<%_ 
  var layout='kind/default'

  if ((page.layout=='kind/text') 
  ||  (page.layout=='kind/json')){
    layout=page.layout
  }
_%>
<%- partial(layout) _%>

.

Layout: EJS Default

And move the original layout to kind/default.

<!DOCTYPE html>
<html lang="en">
<%- partial('site/head') %>
<body>
<%- partial('site/header') %>

  <div class="columns is-8 layout-base maxwidth">
    <%- body %>
  </div>

<%- partial('site/footer') %>
<%- partial('site/scripts') %>
</body>
</html>

Your site should work as usual. Now check your site, if thi default layout is working well.


3: Plain Text

We are almost ready to make custom non html output. But in this step we are still using .html mime type.

Layout: EJS Archives YAML Without Markup

# Helper for related links
# <%= page.title %>

<% site.posts.each(function(post){ %>
- id: <%= date(post.date, "YYMMDDmm") %>
  title: "<%= post.title %>"
  url: <%= post.path %>
<% }) %>

Content: Archives YAML Without Markup

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

---
layout: kind/text
title: Archives
---

Render: Browser

Open in your favorite browser.

Hexo Bulma: Archives YAML Without Markup

Well it still ugly. Of course, it is still using html mime type. You have to look at the source.

Hexo Bulma: Source of Archives YAML

Content: Javascript Mime Type

Alternatively, you can rename source/archives-text.html, to source/archives-text.js.

This will directly show the text. But remember, this mime type is javascript, and your content is yaml.

Still not good!


4: JSON

This is the closest thing to custom output so far. Why not make a custom output in JSON instead of YAML?

Layout: EJS Archives JSON as JS Mime

[
<%
  var count = site.posts.length
  var i = 0;
  site.posts.each(function(post){
    i++
_%>
  {
    "id": <%= date(post.date, "YYMMDDmm") %>,
    "title": "<%= post.title %>",
    "url": "<%= post.path %>"
  }<% if (i!=count){%>,<% } %>
<% }) _%>
]

.

Content: Archives JSON as JS Mime

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

---
layout: kind/json
---

Render: Browser: Site

Open in your favorite browser.

Hexo Bulma: Archives JSON as JS Mime

This will show something similar as below:

[
  ...
  {
    "id": 15010108,
    "title": "Dead Poet Society",
    "url": "2015/01/01/quotes/dead-poets-society/"
  },
  {
    "id": 15100308,
    "title": "Every Day",
    "url": "2015/10/03/quotes/every-day/"
  },
  ...
]

Render: Browser: File

To check the right JSON mime, save it somewhere in your computer, and open it in browser.

Hexo Bulma: Archives JSON File


5: Summary

Since we have some more layout kind, we need to summarize the layout.

$ tree themes/tutor-04/layout/kind 
themes/tutor-04/layout/kind
├── categories.ejs
├── default.ejs
├── json.ejs
├── landing.ejs
├── tags.ejs
├── text.ejs
└── yaml.ejs

0 directories, 7 files

Hexo Layout: Custom Output

And the related content is

$ ls source/archives-*
source/archives-json.js
source/archives-text.html
source/archives-yaml.html

Hexo Content: Custom Output


What is Next ?

Consider continue reading [ Hexo - Widget ]. There are, some interesting topic, about Hexo miscellanous range loop, such widget in a sidebar.

Thank you for reading.