Now that I understand how Hugo and JSON work separately and together, it’s time to figure out the next question.

Can I generate Markdown files based on the contents of a JSON?

My JSON File

I started with an SQL DB where my photos have lived for a long time. I exported the albums table to a JSON file (yes, phpMyAdmin can do that), cleaned it up by removing the cruft I didn’t need, and ended up with something like this:

[
 {
    "categories": "Adventures",
    "tags": "Index",
    "folder": "foobar",
    "title": "Foobar and Baz",
    "desc": "The adventures of Foobar and Baz.",
    "date": "2006-03-24 19:46:40"
  },
  {
    "categories": "Vacations",
    "tags": "Index",
    "folder": "botbob",
    "title": "Bot and Bob",
    "desc": "Bot and Bob's vacation photos",
    "date": "2006-03-24 11:51:04"
  }
]

By the way, I’m not going to address how to actually make the gallery with images here. Yet. The eventual idea I have here is to run this with WordPress doing that, but since I was messing around with this anyway, I figured I’d reuse what I had.

The end goal here, remember, is to export the JSON file from WordPress (list all top level categories, let’s say) and have Hugo generate a page for each one. That’s all. But WordPress has so much data, I decided to start with the smaller, simpler stuff.

Let’s move on.

Create a Markdown Page from JSON

Thankfully someone else has already tossed this idea around. I started with reading Dynamic Pages with Hugo

My idea is: Import any JSON or CSV from any local file or URL and make the JSON or CSV content available in a shortcode or directly in the layout files.

That was very close to what I wanted, but it would result in me having to make a page for each item. I don’t want that. I want a script to make the .md file for me.

So I stepped back and stopped asking “How do I make a Hugo page from JSON?” and I asked “How do I make a separate file for each entry in a .json file?”

Sidebar: My wife was trying to convert the Hebrew year (3595) into all the possible other calendars and asked me to help her with the math. I asked her “What Julian year is that?” She said it BCE so it didn’t work like that, but that was 167. I Googled “What is 167 BCE in the Chinese calendar?” Boom. WikiPedia’s page for 167 BC lists them all. As I pointed out, the trick to these things is not converting it all yourself, but getting from ‘weird’ to ‘Base 10.’ Once you’re at the default (the lowest common denominator), it’s allot easier to figure out other people’s weird.

This is related to my task at hand. Weird is being specific. Weird is caring what system I’m using. The root of my issue is this: I want to make a Markdown file for every entry in JSON.

I use Mustache. And, yes, someone already had this idea. He was using mustache-render in Grunt, which I’m already familiar with, but I made a few changes.

  1. I changed the templates folder to my Hugo Archetypes folder. This is my source, my style.
  2. I changed the data folder to my Hugo Data folder.
  3. The output went to (you got this one, right?) the Hugo Content folder.

This should work, right?

Mustache Render

My Gruntfile has this:

    mustache_render: {
      all: {
        options: {
          directory: "partials"
        },
        files: [
          {
            data: "../data/parents.json",
            template: "../archetypes/gallery.mustache",
            dest: "../content/gallery.md"
          }
        ]
      }

And my gallery.md file is like this:

---
title: {{title}}
author: Me
layout: default
permalink: /{{folder}}/
categories: {{categories}}
tags: {{tags}}
---

{{title}}

Except that doesn’t work. If I changed {{title}} to {{0.title}} then it showed Foo and Bar’s adventure information. Obviously the render was only going to show each entry individually. Now. This could work in a variety of situations, just not mine. Alternatively, I can wrap the output in this: {{#0}} ... {{/0}}

But what I want is ‘for each key in json, make a file…’ and since I can put the JSON output right into the gruntfile (data: { greeting: "Hello", target: "world" }) then in theory I want to generate this:

files: [
  {data: OUTPUT FROM KEY ,
   dest: KEY ID,
]

Okay so how do I tell Grunt to read from a JSON and for each key, do a thing? First I use grunt.file.readJSON:

pkg: grunt.file.readJSON('../data/parents.json'),

    mustache_render: {
        [...]
            files: [{
                template: '../archetypes/gallery.mustache',
                data: '<%= pkg.1 %>',
                dest: '../content/<%= pkg.1.id %>-foo.md'
            }]
      }
    }

And this will output item #2 (Bob’s vacations). So stage one is complete. Now I want the 1 in pkg.1 to be iterative or I want to pass a variable to the mustache file and change {{#0}} ... {{/0}} based on its value. Obviously if I had one JSON file for each ‘post’ I wanted to make, this would be easy.

Multiple Markdown Files from One JSON

I have no idea.

Seriously. I spent a few hours on this, lying in bed trying to feel less cold-and-flu-ish. At this point, I don’t really care what I use to do it, but the bones is this: Take one JSON file and split each object into it’s own file.

Can’t figure that out yet. But hey, there’s my 2016 project!

FYI: If you reply with ‘try project X!’ without a code example of how to do it, I’ll probably delete your comment. I’ve seen ‘Try handlebars!’ or ‘Try Assemble’ but my issue here is no one has an example of how to do it, and I work best by example. I need that Hello World.

I am looking at Handlebars and Assemble, by the way, but at 900+ words, it’s time to call a pause on the adventure.

Reader Interactions

Comments

  1. Why not write a quick script in, say, PHP? json decode, loop, output a file with the formatted data, repeat.

%d bloggers like this: