# Custom output content types

**URL:** <https://discourse.gohugo.io/t/custom-output-content-types/4584>\
**Category:** feature\
**Created:** [November 16, 2016, 3:14pm UTC](https://discourse.gohugo.io/t/custom-output-content-types/4584 "2016-11-16T15:14:42Z")\
**Posts on this page:** 5\
**Page:** 1

<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:** [November 16, 2016, 3:14pm UTC](https://discourse.gohugo.io/t/custom-output-content-types/4584/1 "2016-11-16T15:14:42Z")

</div>

Once I finish my move of `Node` to `Page`, and _everything is a Page which can contain `Pages`_ – which in itself solves some interesting problems – Hugo has a much cleaner model which can be exploited.

I see a lot of questions about rendering alternative representations of a Hugo site, or parts of a Hugo site: **how can I create more RSS feeds? How to output a page or site as JSON? Create iCal calendar file? Google AMP? Facebook instant pages? How can I generate multiple representations of the same content?**

For discussion, given the content tree below:

```auto
content
├── _index.md
├── categories
│ ├── _index.md
│ └── photo
│ └── _index.md
├── post
│ ├── _index.md
│ └── hugo-rocks.md
└── tags
    ├── _index.md
    └── hugo
        └── _index.md

```

Today we have some implicit default content types. RSS, html, sitemap.

If we extend on that we could define the output content types in Site config and override in page front matter, i.e.

```auto
output = ["rss", "html", "ical", "amp"]

```

And then we define some template lookup rules based on what gets rendered (taxonomy, home page, section listing etc.), so rendering a `section` for `amp` would look for templates like this:

```auto
return []string{"section/" + section + ".amp.html", "_default/amp.html", "amp.html", "_internal/_default/amp.html"}

```

Plenty of details left out in the above, but it could be plenty powerful and flexible me thinks. This also allows for creating sites without RSS, sitemap, RSS only and any combo.

**_Thoughts?_**

---

<div class="post-metadata">

**Author:** ![rdwatters](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.gohugo.io/rdwatters/32/2848_2.png) [@rdwatters](https://discourse.gohugo.io/u/rdwatters)\
**Post date:** [November 16, 2016, 7:44pm UTC](https://discourse.gohugo.io/t/custom-output-content-types/4584/2 "2016-11-16T19:44:36Z")

</div>

I think this is a _great_ idea for many reasons, not the least of which is the added flexibility for pulling from content files to create new files in serialized data formats (specifically `.json`).

> [@bep](#):
>
> If we extend on that we could define the output content types in Site config and override in page front matter, i.e.

What if you skip the config piece altogether and just allow for overrides in individual front matter for specific use cases where an individual content file should _not_ be output. This assumes the appropriate-file-extension page will be generated automatically based on the extensions alone in the layouts folder(s). Granted, this might be a bigger (breaking) change, and I think this is kind of what you’re saying already:

```auto
layouts
|_default
   ├── single.html
   ├── single.amp.html
   ├── single.json (don't konw when you'd use this, but just to extend the example)
   ├── list.html
   ├── list.json
   ├── rss.xml
   ├── sitemap.xml

```

##As an aside…

I’ve noticed when editing a local copy of the docs that terms are often confusing in Hugo. I would be careful with the term “content types.” This is pedantic for this feed and slightly tangential, but I think we’re talking about “file type” or—better considering Hugo’s use of “type”—“file format” or “file extension.”

This is a bit more standard, I think…

**file format** or **file extension** : `.md`, `.html`, `.json`  
**content type** : post, event, author, speaker  
**content section** or **section** : blog,events,authors,speakers  
**content model** : `post <==> author`, `event <==>speaker`, etc

---

<div class="post-metadata">

**Author:** ![RickySpanish](https://avatars.discourse-cdn.com/v4/letter/r/e19b73/32.png) [@RickySpanish](https://discourse.gohugo.io/u/RickySpanish)\
**Post date:** [December 13, 2016, 3:21am UTC](https://discourse.gohugo.io/t/custom-output-content-types/4584/3 "2016-12-13T03:21:24Z")

</div>

Agree, this is a great idea!

---

<div class="post-metadata">

**Author:** ![moorereason](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.gohugo.io/moorereason/32/592_2.png) [@moorereason](https://discourse.gohugo.io/u/moorereason)\
**Post date:** [December 24, 2016, 4:04pm UTC](https://discourse.gohugo.io/t/custom-output-content-types/4584/4 "2016-12-24T16:04:30Z")

</div>

One question I have is how we go about providing a `text/template` renderer when requested. Outputting JSON or Javascript (or anything non-XML) with the `html/template` engine tends to just complicate things when the `text/template` engine would be much simpler. If we did offer a `text/template` engine, we’d need to look at our template funcs to make sure they can work in both contexts (ie. make sure we’re returning strings instead of `template.HTML`).

```auto
# config.toml

# Define output types used in this site
output = ["html", "json", "js", "rss", "svg"]

# Designate certain output types as text-based
outputText = ["json", "js"]

```

---

<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:** [December 24, 2016, 4:10pm UTC](https://discourse.gohugo.io/t/custom-output-content-types/4584/5 "2016-12-24T16:10:28Z")

</div>

> [@moorereason](#):
>
> output = [“html”, “json”, “js”, “rss”, “svg”]

That is a very good question. I think we can make the output definition a little more complex, i.e.

```auto
output = [{name: "html"}, {name: json, output: "text"}]

```

In the above we default the output to HTML.
