# Headless bundles and content structure

**URL:** <https://discourse.gohugo.io/t/headless-bundles-and-content-structure/16234>\
**Category:** support\
**Created:** [January 8, 2019, 11:34pm UTC](https://discourse.gohugo.io/t/headless-bundles-and-content-structure/16234 "2019-01-08T23:34:06Z")\
**Posts on this page:** 15\
**Page:** 1

<div class="post-metadata">

**Author:** ![pancake](https://avatars.discourse-cdn.com/v4/letter/p/ecd19e/32.png) [@pancake](https://discourse.gohugo.io/u/pancake)\
**Post date:** [January 8, 2019, 11:34pm UTC](https://discourse.gohugo.io/t/headless-bundles-and-content-structure/16234/1 "2019-01-08T23:34:06Z")

</div>

My objective is to create a page `/sponsors/` that lists all sponsors, `sponsor1` and `sponsor2`, and show their titles, descriptions and logos. I want to use this information on other pages as well, such as the homepage.

I do not want to create single pages for the sponsors, so no `/sponsors/sponsor1/`, which is why I’ve made them headless.

This is the content structure I’ve created:

```
content
  sponsors
  _index.md
     sponsor1
       index.md (headless = true)
       logo.png
     sponsor2
       index.md (headless = true)
       logo.png

```

Is this the correct approach? I’m struggling with getting this to work. I’ve been trying to do this:

```
{{ $headlessbundle := .Site.GetPage "/sponsors/sponsor1" }}
{{ range ( $headlessbundle.Resources.ByType "page" ) }}
{{.Title}}
{{ end }}

```

which gives the title of sponsor1.

I don’t know if I’m doing this overly complicated, or just not understanding correctly. I’ve searched through the forum and read the docs. Appreciate any guidance.

---

<div class="post-metadata">

**Author:** ![pancake](https://avatars.discourse-cdn.com/v4/letter/p/ecd19e/32.png) [@pancake](https://discourse.gohugo.io/u/pancake)\
**Post date:** [January 9, 2019, 2:07pm UTC](https://discourse.gohugo.io/t/headless-bundles-and-content-structure/16234/2 "2019-01-09T14:07:49Z")

</div>

I’ve managed to get this to work how I want, but the solution doesn’t feel right. Any suggestions?

**Content Folder**

```
content
  sponsors
  _index.md
     sponsor1
       index.md (headless = true)
       sponsor1.md
       sponsor1.png
     sponsor2
       index.md (headless = true)
       sponsor2.md
       sponsor2.png

```

**sponsors/\_index.md**

```
+++
date = "2019-01-08T18:14:52+01:00"
description = "Description"
title = "Title"
+++

```

**sponsors1/index.md**

```
+++
date = "2019-01-08T18:14:52+01:00"
description = "Description"
title = "Sponsor1"
headless = "true"
[[resources]]
src = "/sponsors/sponsor1/sponsor1.png"
name = "sponsor1.png"
+++

```

**layouts/sponsors/list.html**

```
{{$headlessbundle1 := .Site.GetPage "/sponsors/sponsor1"}}
{{range ($headlessbundle1.Resources.ByType "page")}}
{{.Title}} - {{.Description}} - {{.Content}}
{{end}}

{{range ($headlessbundle1.Resources.ByType "image")}}
<img src="{{.RelPermalink}}>
{{end}}

{{$headlessbundle2 := .Site.GetPage "/sponsors/sponsor2"}}
{{range ($headlessbundle2.Resources.ByType "page")}}
{{.Title}} - {{.Description}} - {{.Content}}
{{end}}

{{range ($headlessbundle2.Resources.ByType "image")}}
<img src="{{.RelPermalink}}">
{{end}}
```

---

<div class="post-metadata">

**Author:** ![alexandros](https://avatars.discourse-cdn.com/v4/letter/a/ecc23a/32.png) [@alexandros](https://discourse.gohugo.io/u/alexandros)\
**Post date:** [January 9, 2019, 3:08pm UTC](https://discourse.gohugo.io/t/headless-bundles-and-content-structure/16234/3 "2019-01-09T15:08:56Z")

</div>

If you have a lot of sponsors that’s a lot of headless bundles to configure.

The bright side through is that with this cumbersome structure you will be able to call each sponsor’s details whenever and wherever you want.

However if these are meant to go in a simple row or a table then the above approach seems like overkill.

In this case I would create just one headless bundle and enter all relevant resources along with their meta data in a long `index.md` then I would use a naming convention for all the logos to control their order i.e. `00-<logo-name>.png`, `01-<logo-name>.png` and then simply range through them as needed in the template.

---

<div class="post-metadata">

**Author:** ![pancake](https://avatars.discourse-cdn.com/v4/letter/p/ecd19e/32.png) [@pancake](https://discourse.gohugo.io/u/pancake)\
**Post date:** [January 9, 2019, 6:13pm UTC](https://discourse.gohugo.io/t/headless-bundles-and-content-structure/16234/4 "2019-01-09T18:13:23Z")

</div>

Thanks. There will only be 2-3 sponsors.

Is there a way I can use the same structure, but not have to repeat the same logic and hard code the path to each sponsor? I would use a range, but it seems you can’t range over headless bundles.

I’m looking for something like this:

```
{{$headlessbundle := .Site.GetPage "/sponsors/%s" (some_variable)}}

```

where some variable would be sponsor1, sponsor2.

---

<div class="post-metadata">

**Author:** ![zwbetz](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.gohugo.io/zwbetz/32/16088_2.png) [@zwbetz](https://discourse.gohugo.io/u/zwbetz)\
**Post date:** [January 9, 2019, 6:22pm UTC](https://discourse.gohugo.io/t/headless-bundles-and-content-structure/16234/5 "2019-01-09T18:22:39Z")

</div>

Try something like this (untested)

```nohighlight
{{$slice := slice "sponsor1" "sponsor2" }}

{{range $slice}}
  {{$headlessbundle := $.Site.GetPage (printf "/sponsors/%s" .)}}
  {{range ($headlessbundle.Resources.ByType "page")}}
    {{.Title}} - {{.Description}} - {{.Content}}
  {{end}}
  {{range ($headlessbundle.Resources.ByType "image")}}
    <img src="{{.RelPermalink}}>
  {{end}}
{{end}}

```

---

<div class="post-metadata">

**Author:** ![pancake](https://avatars.discourse-cdn.com/v4/letter/p/ecd19e/32.png) [@pancake](https://discourse.gohugo.io/u/pancake)\
**Post date:** [January 9, 2019, 6:29pm UTC](https://discourse.gohugo.io/t/headless-bundles-and-content-structure/16234/6 "2019-01-09T18:29:09Z")

</div>

Thanks for helping out.

I get the following error message:

`execute of template failed: template: sponsors/list.html:4:12: executing "sponsors/list.html" at <"sponsor1">: can't give argument to non-function "sponsor1"`

---

<div class="post-metadata">

**Author:** ![alexandros](https://avatars.discourse-cdn.com/v4/letter/a/ecc23a/32.png) [@alexandros](https://discourse.gohugo.io/u/alexandros)\
**Post date:** [January 9, 2019, 6:32pm UTC](https://discourse.gohugo.io/t/headless-bundles-and-content-structure/16234/7 "2019-01-09T18:32:01Z")

</div>

> [@zwbetz](#):
>
> `{{$slice := "sponsor1" "sponsor2" }}`

Try changing the above to:  
`{{$slice := slice "sponsor1" "sponsor2" }}`

---

<div class="post-metadata">

**Author:** ![zwbetz](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.gohugo.io/zwbetz/32/16088_2.png) [@zwbetz](https://discourse.gohugo.io/u/zwbetz)\
**Post date:** [January 9, 2019, 6:32pm UTC](https://discourse.gohugo.io/t/headless-bundles-and-content-structure/16234/8 "2019-01-09T18:32:45Z")

</div>

Yep, as @alexandros mentioned, was missing the `slice` keyword.

---

<div class="post-metadata">

**Author:** ![pancake](https://avatars.discourse-cdn.com/v4/letter/p/ecd19e/32.png) [@pancake](https://discourse.gohugo.io/u/pancake)\
**Post date:** [January 9, 2019, 6:44pm UTC](https://discourse.gohugo.io/t/headless-bundles-and-content-structure/16234/9 "2019-01-09T18:44:32Z")

</div>

Thanks again. Unfortunately, I get this error message now:

`execute of template failed: template: sponsors/list.html:16:30: executing "sponsors/list.html" at <.Site.GetPage>: can't evaluate field Site in type string`

Not sure if this is to do with headless bundles.

---

<div class="post-metadata">

**Author:** ![pancake](https://avatars.discourse-cdn.com/v4/letter/p/ecd19e/32.png) [@pancake](https://discourse.gohugo.io/u/pancake)\
**Post date:** [January 9, 2019, 6:48pm UTC](https://discourse.gohugo.io/t/headless-bundles-and-content-structure/16234/10 "2019-01-09T18:48:02Z")

</div>

I think I’ve solved it now. Need to add a $ to .Site.GetPage

---

<div class="post-metadata">

**Author:** ![zwbetz](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.gohugo.io/zwbetz/32/16088_2.png) [@zwbetz](https://discourse.gohugo.io/u/zwbetz)\
**Post date:** [January 9, 2019, 6:48pm UTC](https://discourse.gohugo.io/t/headless-bundles-and-content-structure/16234/11 "2019-01-09T18:48:43Z")

</div>

It’s a context issue. I’ve updated the code snippet again.

---

<div class="post-metadata">

**Author:** ![pancake](https://avatars.discourse-cdn.com/v4/letter/p/ecd19e/32.png) [@pancake](https://discourse.gohugo.io/u/pancake)\
**Post date:** [January 9, 2019, 6:49pm UTC](https://discourse.gohugo.io/t/headless-bundles-and-content-structure/16234/12 "2019-01-09T18:49:50Z")

</div>

Thanks again for helping out. You too @alexandros🙏

---

<div class="post-metadata">

**Author:** ![emiller](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.gohugo.io/emiller/32/3120_2.png) [@emiller](https://discourse.gohugo.io/u/emiller)\
**Post date:** [January 14, 2019, 5:19pm UTC](https://discourse.gohugo.io/t/headless-bundles-and-content-structure/16234/13 "2019-01-14T17:19:50Z")

</div>

As of Hugo v.53, the .Site var has a lowercase alias **site** that behaves the same in any context. I have simplified my code by replacing all instances of .Site , $.Site etc… with site and it works the same. Please correct me if I’m mistaken, I’d hate to spread misinformation.

---

<div class="post-metadata">

**Author:** ![kaushalmodi](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.gohugo.io/kaushalmodi/32/2567_2.png) [@kaushalmodi](https://discourse.gohugo.io/u/kaushalmodi)\
**Post date:** [January 14, 2019, 6:40pm UTC](https://discourse.gohugo.io/t/headless-bundles-and-content-structure/16234/14 "2019-01-14T18:40:40Z")

</div>

You are correct. [Here’s a refactoring I did recently](https://gitlab.com/kaushalmodi/hugo-theme-refined/commit/bb4de7a313680028af4918d134fd08d2ac38eb89): Replaced `$.Site` and `.Site` with just `site`, and the same for `.Hugo` to `hugo`.

---

<div class="post-metadata">

**Author:** ![Mehdi\_Saada](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.gohugo.io/mehdi_saada/32/16885_2.png) [@Mehdi\_Saada](https://discourse.gohugo.io/u/Mehdi_Saada)\
**Post date:** [September 6, 2022, 1:35pm UTC](https://discourse.gohugo.io/t/headless-bundles-and-content-structure/16234/15 "2022-09-06T13:35:34Z")

</div>

Hi,  
I have a similar issue too. It doesn’t seem like I understood what headless is for.  
It says it won’t be published, only included as a ressource in pages mentioning it.

But here I have

```auto
---
headless: true
bookToc: false
---

```

in the file intro\_en.md, and it does get published, and appears as a menu entry unless I add `bookhidden:true`.
