Learn and Discover Open Source with Daily Genuine Experience. From Coding, Front End, Back End, Database, and Static Site Generator.


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

Table of Content

  • Preface: Table of Content

  • 1: Prepare

  • 2: JSON

  • 3: Text and YAML

  • 4: Summary

  • What is Next ?

Source Code

You can download the source code of this article here.

Related Article

I also wrote about Hugo Bootstrap Custom Output. Step by step article, that you can read here:

I do not rewrite this article. It is exactly the same as the previous one, only with different content.

1: Prepare

We can make a custom content for archiving.

Content: Archives

Remember our last archive page ?

type  = "archives"
title = "Archives by Date"

Instead of just html page, we will enhanced this archive, to output different custom content type.

type  = "archives"
title = "Archives by Date"
outputs = ["html", "txt", "yml", "json"]

Why do we even need these custom outputs ?

  • The HTML, we already seen in previous chapter

  • The JSON artefact as a search data source for lunr json.

  • The YAML artefact to build data source for related pages, something that you usually seen in wordpress posts.

  • The plain text artefact, is just another demo. Because not every browser can handle yaml type, I use the plain fo easiness reason

Main Configuration

In order to do this, we need to make a little adjustment in our beloved config file. Making some new definition in config.toml.

# An example of Hugo site using Bulma for personal learning purpose.


    suffixes = ["yml"]

    baseName    = "index"
    mediaType   = "text/yaml"
    isPlainText = true
    baseName    = "index"
    mediaType   = "text/plain"
    isPlainText = true
  • JSON is already a standard output type. So we don’t need to change anything.

  • On the other hand, we need to define YAML mediaTypes.

  • However, we still need to define txt output formats.

Note that, newer Hugo require suffixes, instead of suffix.




We need these two artefacts.

$ touch themes/tutor-04/layouts/archives/baseof.json.json
$ touch themes/tutor-04/layouts/archives/single.json.json

We have already this archives.md, no need to recreate.

$ cat content/pages/archives.md

Layout: Baseof: JSON

Our base is as simply as this below.

{{ block "main" .}}{{ end }}

Layout: Single: JSON

The detail is in

{{ define "main" }}
{{- $posts := where .Site.Pages "Type" "post" -}}
{{- $postCount := len $posts -}}
  {{ range $i, $e := $posts }}
    "{{ .URL | urlize }}": {
      "title": {{ jsonify $e.Title }},
      "content": {{ jsonify ($e.Params.excerpt | default $e.Summary) }},
      "url": {{ jsonify .Permalink }},
      "author": {{ jsonify $e.Params.author }},
      "category": {{ jsonify $e.Section  }}
    {{- if not (eq (add $i 1) $postCount) }},{{ end -}}
  {{ end }}
{{ end }}

Server Output: Browser

Now you can see JSON output in your favorite browser.

This will produce something similar as shown below:

    "/quotes/2014/03/25/the-used-hard-to-say/": {
    "/quotes/2014/01/15/paul-simon-jonah/": {
      "title": "Paul Simon - Jonah",
      "content": "No one gives their dreams away too lightly They hold them tightly Warm against cold\nI know Jonah He was swallowed by a song",
      "url": "http://localhost:1313/quotes/2014/01/15/paul-simon-jonah/",
      "author": "epsi",
      "category": "quotes"

Modern browser automatically format, the JSON output in nice view collapsable view.

Hugo: JSON Content Type

3: Text and YAML


We need these two artefacts.

$ touch themes/tutor-04/layouts/archives/baseof.yml.yml
$ touch themes/tutor-04/layouts/archives/single.yml.yml
$ touch themes/tutor-04/layouts/archives/baseof.txt.txt
$ touch themes/tutor-04/layouts/archives/single.txt.txt

We have already the archives.md.

Layout: Baseof: Text and YAML

Our base for both yml and txt, have the same content.

Our base for both yml and txt, are as simply as this below.

{{ block "main" .}}{{ end }}

Layout: Single: Text and YAML

The detail are also the same for both

You can create anything that suit your own needs.

{{- define "main" -}}
# Helper for related links
# {{ .Title }}

{{ range (where .Site.Pages "Type" "post") }}
  {{- if .Date }}
- id: {{ .Date.Format "06010204" }}
  title: "{{ .Title }}"
  url: {{ .URL }}
  {{ end -}}
{{ end }}

{{- end -}}

Server Output: Browser: Text

Now you can see plain text output in your favorite browser.

This will produce something like:

# Helper for related links
# Archives by Date

- id: 18091335
  title: "Mothers - No Crying in Baseball"
  url: /quotes/2018/09/13/mothers-no-crying-in-baseball/
- id: 18090735
  title: "Julian Baker - Something"
  url: /quotes/2018/09/07/julian-baker-something/

Hugo: Text Content Type

So we can easily copy paste the output to any text editor.

Server Output: Browser: YAML

Now you can download YAML output in your favorite browser.

Since no handle for text/yaml in browser, the browser will ask if it should be downloaded

Hugo: YAML Content Type

So we can easily copy downloaded files using any file manager.

4: Summary

Since we have four type, we have four single layouts, as shown in tree below.

$ tree themes/tutor-04/layouts/archives/
├── baseof.json.json
├── baseof.txt.txt
├── baseof.yml.yml
├── list.html
├── single.html
├── single.json.json
├── single.txt.txt
└── single.yml.yml

Hugo: Archive Summary

What is Next ?

There are, some interesting topic, about Hugo miscellanous range loop, such in a sidebar. Consider continue reading [ Hugo - Side Panel ].

Thank you for reading.