How to create JSON of _index.md

I’m currently using Hugo to build a JSON API, as I’m transitioning from a static site to something with a backend.

At the root of sections, I have a _index.md file which represents the root i.e. https://hello.com/articles

My only issue is that I’m unable to generate a JSON of _index.md. In the selected section, I have single.json.json and list.json.json which renders single templates and list templates. However, I’m unable to generate a single.json.json of just that root _index.md file.

Basically, the /articles/index.json is rendering the list.json.json (which makes sense) but what would i have to do to render a JSON with the front matter of the /articles/ page?

Hi,

I’m not sure I understand what you are trying to do.

the _index.md would need a list layout, not a single layout.

if /articles/ is a section, you need a /articles/_index.md to put your front matter into.

It would help if we could see what the structure of your content is.

Apologises, I’ll explain it a little better.

In order to generate the /articles route, there is an _index.md file inside /content/articles/_index.md (all obvious stuff). Inside that _index.md file is a bunch of front matter specific to /articles. (again, obvious).

Now, what I’m attempting to do is generate JSON of all my content. This is done by defining custom outputs, as well as placing *.json files in the theme, so it knows what data to generate.

single.json will render all /articles/.md files EXCEPT for the _index.md, because that’s technically not /articles/.md. Instead, it is merely the /articles route itself.

list.json will render all /articles/*.md as a list of objects, containing the front matter of those contents.

What I’m needing is a third .json type that will supply the front matter for _index.md, however I’m not exactly sure how, nor if the system can do that.

What I have been doing as a work around, is putting the front matter from _index.md inside a file called /articles/articles_front_matter.md that will then render that front matters via single.json.json, however it also gets added to list.json which is not what I want.

In other words, I’m not sure how to export the _index.md front matter as json, natively.

Any clues?

EDIT: The reason for this is because list.json actually gets rendered as /articles/index.json

Given content structure like this:

content/articles/
├── art1.md
├── art2.md
├── art3.md
└── _index.md 

and layouts like this:

layouts/articles/
├── list.json
└── single.json

Hugo generates this:

public/articles/
├── art1
│   └── index.json  # single.json
├── art2
│   └── index.json  # single.json
├── art3
│   └── index.json  # single.json
└── index.json      # list.json

Where do you want the _index.md front matter to be generated? In its own separate file? Or included in public/articles/index.json?

If it is the latter, why not add it to the list.json layout? The below (very simplified example) will give you a list of articles and the params/front matter for _index.md:

{
  "layout" : "articles/list.json",
  "params" : {
    {{ range $key, $val := .Params }}
    "{{$key}}" : "{{$val}}",
    {{ end }}
  },
  "articles": [
    {{ range .Pages }}
    {
      "title" : "{{.Title}}"
    },
    {{ end }}
  ]
}
{
  "layout" : "articles/list.json",
  "params" : {
    "draft" : "false",
    "something" : "custom",
    "title" : "Articles",
  },
  "articles": [
    {"title" : "Art3"},
    {"title" : "Art2"},
    {"title" : "Art1"},
  ]
}
1 Like

Oh right, that is a very good point about putting it in the list.json!

I suppose the downside to that is that I would need to load all of the articles, along with the front matter if I just wanted to load the front-matter.

I suppose I was looking for a solution where I could have a third type, that wasn’t single.json or list.json, but could just have the _index.md on it’s own. But I might go ahead and just put it in the list.json.

If you wanted just the front matter in your json, what you could do is, for example, create a placeholder md to generate the path for you, then use a custom third layout. So,

# in content/articles/frontmatter.md
layout: frontlayout

then in layouts/articles/frontlayout.json

{{$articles := .Site.GetPage "articles/_index.md"}}
{
  "params" : {
    {{- range $key, $val := $articles.Params -}}
    "{{$key}}" : "{{$val}}",
    {{ end }}
  }
}

and that should give you public/articles/frontmatter/index.json with just the front matter.

1 Like