API theme component, need help taming.Render and .Scratch

Hi,

I’m trying to build an open source theme component which would conveniently add a JSON API layer to any Hugo project. The repo follows but let me explain the issue first.

In this process, I need to manage transformers, meaning that depending on your page type (post, page, recipe, whatever) you can easily add a dedicated way to output the entry’s JSON object. It’s pretty much along the line of this post I wrote, only this time I rely solely on .Scratch to build my output and eventually jsonify it for the view.

Now, to achieve this custom transformer thing, I sided with .Render.
This way, the user would just have to add a /layout/my-page-type/transormer.json.json file with the desired transformation to its project. This transformer would be automatically picked up by Hugo when dealing with this kind of page, be it a list template or a single template.

Now this is what the transformer looks like (short version):

{{- .Scratch.SetInMap "item" "title" .Title -}}
{{- .Scratch.SetInMap "item" "created" .Date -}}
{{- .Scratch.SetInMap "item" "type" .Type -}}

Inside the transformer, a .Scratch object is built and attached to the page’s .Scratch.

Now from a list template, we just iterate over the pages, “Render” their transformer to attach their .Scratch object to it, and then add this object to the list’s overall .Scratch output object.

{{- range (.Scratch.Get "pages") -}}
	{{- .Render "transformer" -}}
	{{- $.Scratch.Add "items" (slice (.Scratch.Get "item")) -}}
{{- end -}}

It works for every single template and the list templates of one page type (roman) but when I try another one (personnage), it is not able to grab the .Scratch object created from inside the transformer… As a result a <nil> is added in place of the page object

{
  "data": {
  "count": 1260,
  "items": [
    null,
    null,
    null,
    null,
    null,
    null,
  ],
}

Sometime, one or two characters (personnage) manage to get their object in there but not often.

I may miss a few things on the correct usage of .Scratch in this case, but when I give up .Render and use a partial instead, everything works fine… but taking the partial route, is as always not as clean and simple as .Render.

Maybe some more advance .Scratch or .Render users out there can help

The repo is here (make sure to checkout the branch api-theme-component).

Take it a look:
http://localhost:1313/romans/index.json :+1:
http://localhost:1313/personnage/index.json :-1:

Thanks a ton!

2 Likes

I’m also looking for a solution here.