# How to iterate over headless pages?

**URL:** <https://discourse.gohugo.io/t/how-to-iterate-over-headless-pages/12536>\
**Category:** support\
**Created:** [June 19, 2018, 9:00pm UTC](https://discourse.gohugo.io/t/how-to-iterate-over-headless-pages/12536 "2018-06-19T21:00:16Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![openscript](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.gohugo.io/openscript/32/4511_2.png) [@openscript](https://discourse.gohugo.io/u/openscript)\
**Post date:** [June 19, 2018, 9:00pm UTC](https://discourse.gohugo.io/t/how-to-iterate-over-headless-pages/12536/1 "2018-06-19T21:00:16Z")

</div>

Dear community

On my home page I render a list of references. The tree looks like this:

- Root / home page
  - References
    - Reference A
      - index.md
      - index.en.md

    - Reference B
      - index.md
      - index.en.md

    - Reference C
      - index.md
      - index.en.md

In this index.md files I set headless to true. As expected the file is not rendered, but the reference is also not rendered on my home page, where I use the following template code:

```
<section id='references'>
    {{ with .Site.GetPage "section" "references" }}
    <h2>{{ .Title }}</h2>
    {{ .Content }}
    <div class='references-container'>
        {{ range .Pages }}
        <span class='reference'>
            <a href='{{ .Params.website }}'>
            {{ with .Resources.GetMatch .Params.logo }}
            {{ $image := .Fit "1000x100" }}
            <img src='{{ $image.RelPermalink }}'>
            {{ end }}
            </a>
        </span>
        {{ end }}
    </div>
    {{ end }}
</section>

```

How can make the references appear and stop Hugo from rendering unused files?

Thank you in advance!

---

<div class="post-metadata">

**Author:** ![maiki](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.gohugo.io/maiki/32/16384_2.png) [@maiki](https://discourse.gohugo.io/u/maiki)\
**Post date:** [June 19, 2018, 10:06pm UTC](https://discourse.gohugo.io/t/how-to-iterate-over-headless-pages/12536/2 "2018-06-19T22:06:09Z")

</div>

Please read [Requesting Help](https://discourse.gohugo.io/t/requesting-help/9132?u=maiki) for tips on getting help in the forums.

You include a lot of information in your posts, but in order to reproduce the issues, we’d have to build a Hugo project and paste in snippets and produce dummy content… not fun!

So please share a link to a repo that one can clone and see your issue.

---

<div class="post-metadata">

**Author:** ![openscript](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.gohugo.io/openscript/32/4511_2.png) [@openscript](https://discourse.gohugo.io/u/openscript)\
**Post date:** [June 19, 2018, 10:23pm UTC](https://discourse.gohugo.io/t/how-to-iterate-over-headless-pages/12536/3 "2018-06-19T22:23:28Z")

</div>

Thank you for your response @maiki.

I totally get your point. Here is an example repository: [https://github.com/openscript/hugo-headless-example](https://github.com/openscript/hugo-headless-example)

Here is a short gif which explains my question quite well (I hope at least):

 ![2018-06-20_00-21-20](https://canada1.discourse-cdn.com/flex036/uploads/gohugo/original/2X/3/36776fc6ad9133fe12a06dd182d598ee6218a6ec.gif)

How can I render the “first” reference in this case, but prevent Hugo from outputting a separate file for this reference?

Thank you in advance 🙂

---

<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:** [June 19, 2018, 11:13pm UTC](https://discourse.gohugo.io/t/how-to-iterate-over-headless-pages/12536/4 "2018-06-19T23:13:57Z")

</div>

Try:

```
Site.GetPage "references" "first"
```

---

<div class="post-metadata">

**Author:** ![bep](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.gohugo.io/bep/32/3332_2.png) [@bep](https://discourse.gohugo.io/u/bep)\
**Post date:** [June 19, 2018, 11:25pm UTC](https://discourse.gohugo.io/t/how-to-iterate-over-headless-pages/12536/5 "2018-06-19T23:25:15Z")

</div>

> [@openscript](#):
>
> In this index.md files I set headless to true. As expected the file is not rendered, but the reference is also not rendered on my home page, where I use the following template code:

Headless pages are not a member of any of the site collections, and you will then not see it in ` {{ with .Site.GetPage "section" "references" }}`.

They have a very specific intended use case: A collection of reusable page snippets, images etc., but you have to be explicit when doing lookups.

---

<div class="post-metadata">

**Author:** ![openscript](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.gohugo.io/openscript/32/4511_2.png) [@openscript](https://discourse.gohugo.io/u/openscript)\
**Post date:** [June 19, 2018, 11:38pm UTC](https://discourse.gohugo.io/t/how-to-iterate-over-headless-pages/12536/6 "2018-06-19T23:38:42Z")

</div>

I understand your answer and thank you for that, but how do I prevent the output of unnecessary files in this case?

---

<div class="post-metadata">

**Author:** ![openscript](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.gohugo.io/openscript/32/4511_2.png) [@openscript](https://discourse.gohugo.io/u/openscript)\
**Post date:** [June 19, 2018, 11:39pm UTC](https://discourse.gohugo.io/t/how-to-iterate-over-headless-pages/12536/7 "2018-06-19T23:39:16Z")

</div>

That works, but I can’t dynamically iterate over my references anymore.

---

<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:** [June 20, 2018, 8:07am UTC](https://discourse.gohugo.io/t/how-to-iterate-over-headless-pages/12536/8 "2018-06-20T08:07:00Z")

</div>

As @bep said a headless bundle exists outside of the `section` loop.

A headless bundle is only available through `.GetPage`

So to render your references pages (that are not headless bundles) you need to `range` through them separately in your template.

---

<div class="post-metadata">

**Author:** ![openscript](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.gohugo.io/openscript/32/4511_2.png) [@openscript](https://discourse.gohugo.io/u/openscript)\
**Post date:** [June 20, 2018, 8:14am UTC](https://discourse.gohugo.io/t/how-to-iterate-over-headless-pages/12536/9 "2018-06-20T08:14:29Z")

</div>

Yes, I understand that.

Currently we have something like a ignore file on the deployment server, which deletes all the files which Hugo generated and we don’t need (about 140 pages). Is there really no other way than this script?

Would a PR be appreciated, which adds another flag to prevent Hugo from outputting pages for flagged content files?

---

<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:** [June 20, 2018, 8:49am UTC](https://discourse.gohugo.io/t/how-to-iterate-over-headless-pages/12536/10 "2018-06-20T08:49:27Z")

</div>

I am already doing what you describe without server scripts.

In Hugo there are `disableKinds` and many other ways to filter content.

But you need to share your repo for people in this forum to see what you mean by flagged content.

Regarding sending a PR for this in the Hugo repo @bep is the maintainer so he is the one who reviews these things.

But again there are ways to filter content and prevent it from being rendered. We need to see what the use case is before adding more code.

---

<div class="post-metadata">

**Author:** ![openscript](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.gohugo.io/openscript/32/4511_2.png) [@openscript](https://discourse.gohugo.io/u/openscript)\
**Post date:** [June 20, 2018, 10:30am UTC](https://discourse.gohugo.io/t/how-to-iterate-over-headless-pages/12536/11 "2018-06-20T10:30:05Z")

</div>

Thank you for your answer @alexandros.

I’ve checked out `disableKinds` before. Unfortunately I can not disable a specific section. Like in the example above, I want to stop Hugo from rendering everything from references.

```
disableKinds = ["references"] 

```

This doesn’t have any effect, because according to the docs I can only disable all sections or none.

> [@alexandros](#):
>
> `` and many other ways to filter content.

What are the other ways?

---

<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:** [June 20, 2018, 10:34am UTC](https://discourse.gohugo.io/t/how-to-iterate-over-headless-pages/12536/12 "2018-06-20T10:34:39Z")

</div>

`disableKinds` is global configuration.

But there is a known hack to disable a specific section.

> [@Would like to "ignoreFiles" but use the underlying content](https://discourse.gohugo.io/t/would-like-to-ignorefiles-but-use-the-underlying-content/6368/10):
>
> If layouts/foo/single.html and layouts/section/foo.html are zero-length, no files will be published for section foo, but the content can still be retrieved through taxonomies, etc. This was briefly broken in 0.20-0.20.2, but was fixed in 0.20.3.

---

<div class="post-metadata">

**Author:** ![openscript](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.gohugo.io/openscript/32/4511_2.png) [@openscript](https://discourse.gohugo.io/u/openscript)\
**Post date:** [June 20, 2018, 10:47am UTC](https://discourse.gohugo.io/t/how-to-iterate-over-headless-pages/12536/13 "2018-06-20T10:47:10Z")

</div>

Unfortunately this pages are still in the sitemap then.

It seems like there is no other way around than do some kind of post-processing after Hugo rendered. ☹

---

<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:** [June 20, 2018, 10:49am UTC](https://discourse.gohugo.io/t/how-to-iterate-over-headless-pages/12536/14 "2018-06-20T10:49:18Z")

</div>

You can exclude them from the sitemap with a front matter parameter.

Search the forum. There have been topics about this.

---

<div class="post-metadata">

**Author:** ![openscript](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.gohugo.io/openscript/32/4511_2.png) [@openscript](https://discourse.gohugo.io/u/openscript)\
**Post date:** [June 20, 2018, 11:02am UTC](https://discourse.gohugo.io/t/how-to-iterate-over-headless-pages/12536/15 "2018-06-20T11:02:17Z")

</div>

> [@\[SOLVED\] Ignore section but render its content with custom url](https://discourse.gohugo.io/t/solved-ignore-section-but-render-its-content-with-custom-url/9828/2):
>
> Search the forum for adding a param called `hidden` (or anything you want) in the `_index.md` of your section and how to conditionally render your xml if that param is not present.

You are talking about this? I’ve found this before. I’ve added `hidden = true` to all references, but they are still in the sitemap.xml. The documentation didn’t tell me anything about this parameter.

Let me formulate my question again, maybe we understand us wrong.

I’ve a list of references. I use them as a part of the home page and I make them visible there. I just use the content, but Hugo doesn’t need to output anything from this files to rendered pages, to the sitemap or to anything else.

Currently we have a whitelist of file we need and the rest is deleted from the output of Hugo. We realized, that we also need to post-process the sitemap.xml. The only thing which kind of worked so far, is to have empty templates for this sections.

Maybe we are using Hugo in a wrong way?

---

<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:** [June 20, 2018, 11:07am UTC](https://discourse.gohugo.io/t/how-to-iterate-over-headless-pages/12536/16 "2018-06-20T11:07:47Z")

</div>

Front Matter Parameters are user defined. You can name them any way you want.

Here are the contents of a `sitemap.xml` from a Hugo project of mine

```auto
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
  {{ range .Pages }}{{ if not .Params.hidden }}
  <url>
    <loc>{{ .Permalink }}</loc>
    {{ with .Sitemap.ChangeFreq }}
    <changefreq>{{ . }}</changefreq>{{ end }}{{ if ge .Sitemap.Priority 0.0 }}
    <priority>{{ .Sitemap.Priority }}</priority>{{ end }}
  </url>
  {{ end }}{{ end }}
</urlset>

```

Every content page with the front matter param `hidden = "true"` is excluded from the sitemap.

---

<div class="post-metadata">

**Author:** ![openscript](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.gohugo.io/openscript/32/4511_2.png) [@openscript](https://discourse.gohugo.io/u/openscript)\
**Post date:** [June 20, 2018, 1:06pm UTC](https://discourse.gohugo.io/t/how-to-iterate-over-headless-pages/12536/17 "2018-06-20T13:06:05Z")

</div>

Thank you for this answer.

We started to flag the files and use your template for the sitemap xml.

```
{{ if .Params.hidden }}
{{ "<!--hidden-->" | safeHTML }}
{{ end }}

```

And then on the CI/CD we run `grep -iRl '<!--hidden-->' --include '*.html' . | xargs -0 rm -f --`. That works quite well so far 🙂

This can be improved by deleting the whole folder of the file, so also resources are removed.

```
grep -iRl '<!--hidden-->' --include '*.html' . | xargs -0 dirname | xargs rm -rf
```

---

<div class="post-metadata">

**Author:** ![Randy\_Lough](https://avatars.discourse-cdn.com/v4/letter/r/85e7bf/32.png) [@Randy\_Lough](https://discourse.gohugo.io/u/Randy_Lough)\
**Post date:** [June 20, 2018, 8:21pm UTC](https://discourse.gohugo.io/t/how-to-iterate-over-headless-pages/12536/18 "2018-06-20T20:21:10Z")

</div>

I’ve been trying to accomplish a similar result as well. I have a section that has a mixture of headless and non-headless pages. On the main listing page I’ve been trying to range over all the pages (both headless and non) to display their name and logo and only the ones that are not headless have a link to their own page for more information.

Unfortunately, the only work around I have right now is to remove them on the sitemap through front-matter. I can’t disableKind the section since there is some I want to have a permalink/page.

---

<div class="post-metadata">

**Author:** ![regis](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.gohugo.io/regis/32/4958_2.png) [@regis](https://discourse.gohugo.io/u/regis)\
**Post date:** [June 24, 2018, 2:12pm UTC](https://discourse.gohugo.io/t/how-to-iterate-over-headless-pages/12536/19 "2018-06-24T14:12:22Z")

</div>

Would this be too complicated to create a new site variable along the line of `.Site.RegularPages`.?

We already have an `.AllPages` to display pages from every languages, so not sure how to call this new `.PagesHeadlessOrNot` site variable… but we could also only add **`.Site.HeadlessPages`** as a site variable and let the user manage the `where` clause in order to retrieve what he needs.

I think people will need to range on their headless pages eventually, I see a lot of use cases where people use them as data with a bundle… (sponsors, ads, team member) resulting in dozens of headless pages which, at some point in a template, needs to be conveniently iterated over.

As of today, I don’t see any easy way. You have to know where to look in order to create a range on their filename and then use `.GetPage` on each of them inside the range…

---

<div class="post-metadata">

**Author:** ![julianoaklein](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.gohugo.io/julianoaklein/32/2981_2.png) [@julianoaklein](https://discourse.gohugo.io/u/julianoaklein)\
**Post date:** [May 1, 2019, 1:32pm UTC](https://discourse.gohugo.io/t/how-to-iterate-over-headless-pages/12536/20 "2019-05-01T13:32:41Z")

</div>

I had the same issue.

To iterate over a folder of headless pages, here is what I did:

```
{{- $services := slice -}}
{{ range (readDir "content/services") }}
    {{ $services = $services | append ( $.Site.GetPage ( print "services/" .Name ) ) }}
{{ end }}
```

[Next page](https://discourse.gohugo.io/t/how-to-iterate-over-headless-pages/12536.md?page=2)
