Build a JSON API With Hugo's Custom Output Formats

Hi guys!

I was recently lucky enough to be enrolled by Forestry.io into writing a post for them!
The article is about building a Hugo JSON API with Hugo’s Output format. You can add it as a layer on top of your existing site or a simple stand-alone GET API.

Special thanks to Forestry’s Sebastian (@forestry.io) and @dwalkr for supporting me and shaping this article into an incredible read!

10 Likes

Very cool!

The only thing I have to add is that you could have done without manual “comma-management” by using dict and jsonify.

For example, I use the below for my search index json:

{{- $.Scratch.Add "index" slice -}}
{{- range .Site.RegularPages -}}
    {{- $.Scratch.Add "index" (dict "title" .Title "tags" .Params.tags "categories" .Params.categories "contents" .Plain "permalink" .Permalink) -}}
{{- end -}}
{{- $.Scratch.Get "index" | jsonify -}}
1 Like

Hi @kaushalmodi!

Yes, I just didn’t feel like adding a layer of .Scratch to the educational scope (primarly output format and templating). So I sticked with the basics on this one :slight_smile:.

2 Likes

I can sort of agree with that :slight_smile:. JSON is not my strength, and missing/extra commas are painful there.

BTW can you still or would you add a demo site + source to that post so that people can see the actual code + site in action? (or did I miss that?)

here you go, we’ll add it to the post soon: https://github.com/regisphilibert/hugoGetApi/

2 Likes

Yes, lovin the custom outputs feature.

I’m putting together a custom data file for a list of categories and a list of tags.

The reason is to try and use them with Forestry.IO to make up for not being able to use a dropdown list when manually editing content. One of the few things I miss from WordPress.

I would like to be able to create separate files really rather than a single JSON file. No sure if that is possible but this is enough for now.

I’m also producing an index file that I will use for search.

@regis Looks like you probably couldn’t have done that way, as I seem to be hitting a Go templating limitation.

No you’d have to use .Scratch.SetInMap extensively just like @chrisdmacrae did in his Algolia piece.

Hmm, I did use .SetInMap (see)… will have a look at the Algolia piece later.


Update: Got it working, though, with a nasty hack (sample output).

Hi to all, first of all thank you @regis.

The tutorial is really great, but I’m not able to produce a right json list of section items.

I have a section called “comune” and I have these files:

  • layout/default/baseof.json
{
	"data" : {{ block "response" .}}{{ end }}
}
  • layout/default/single.json.json
{{ define "response" }} {{ .Render "item" }} {{ end }}
  • layouts/comune/item.json.json
{
    "name": "{{ .Title }}"
}
  • layouts/comune/list.json.json
{{ define "response" }}
[
    {{ range $index, $e := .Data.Pages }}
    {{ if $index }}, {{ end }}{{ .Render "item" }}
    {{ end }}
]
{{ end }}

If I call http://localhost:1313/comune/accumoli/index.json I have a right output:

{
	"data" :  {
    "name": "Accumoli (Lazio)"
} 
}

If I call the list (http://localhost:1313/comune/index.json) the loop works (I have 6 items in “comune” section), but I do not have the render of the items:

{
	"data" : 
[
    
    
    
    , 
    
    , 
    
    , 
    
    , 
    
    , 
    
]

}

What’s wrong in my files?

I’m usinng hugo v0.42.1.

Thank you

Hi @aborruso!

Yes this is getting old and Hugo is moving fast! Try modifying the transformer file so the permalink is grabbed with this (.OutputFormats.Get "json").Permalink) rather than simply .Permalink.

Hi Regis, I’m not sure to have understood you, sorry :frowning:

I have modified my item.json.json in

{
    "name": "{{ ((.OutputFormats.Get "json").Permalink)  }}"
}

And I have a correct single item output but always a list without the rendering of the items.

Thank you

Do you have a repo I could look at?

Yes, this one Andrea Borruso / jhugo · GitLab

Thank you

.Render is not always our friend :frowning: I switched to the use of a partial instead (Like I did in most of my recent API hugo) through this PR

1 Like

It works, thank you very much!!

Some questions:

  • the .Render behavior is a hugo bug?
  • why does it work with your repo (I have not tested but I suppose it works) and not with mine?

However I think you should insert some note in your great post. Because it’s a sort of a milestone.

Best regards

Not sure.

It appears the problem occur when you have several output formats. I’ll investigate more before editing the post. Thanks for bringing this up!

I wrote about the issue here, but it didn’t get too much traction.

1 Like

I think I found the problem and reported it. We’ll see.

1 Like

I know I might be a little late to the party, but i was following your articles. And I just can’t make it work.
I’m stuck at customOutputs, seems like its not rendering the custom “players” json.

The common outputs in console:
WARN 2019/09/29 12:29:31 found no layout file for “players” for “page”: You should create a template file which matches Hugo Layouts Lookup Rules for this combination.

Any hints? something changed?