hugo/docs/content/extras/custom-output-types.md
Bjørn Erik Pedersen 29d3778ba1 docs: Move the rough custom output formats spec to docs
This isn't meant to be the final useer docs on this feature!
2017-03-27 15:43:56 +02:00

4.9 KiB

aliases date draft menu title weight toc
/doc/custom-output/
2017-03-22T08:20:13+01:00 true
main
parent
extras
Custom Output Types 5 true

NOTE: This isn't the final docs format, but pulled from the "Sketch of Spec For Custom Output Formats" and will be adaptet to a more end user friendly format.

Media Type

We add a media type (also known as MIME type and content type). This is a two-part identifier for file formats and format contents transmitted on the Internet.

For Hugo's use cases, we use the top-level type name/subtype name + suffix. An example would be application/json+json.

Users can define their own media types by using them in an Output Format definition (see below).

The full set of media types will be registered in Go's mime package, so they will be recognised by Hugo's development server.

Output Format

A Page in Hugo can be rendered to multiple representations on the file system: All will get an HTML page and some of them will get an RSS page (home page, sections etc.).

When we now create a more formal definition for these output representations, the built-ins mentioned above will be the standard set that can be extended.

So an OutputFormat:

OutputFormat:
   Name
   MediaType
   Path
   IsPlainText (default false)
   Protocol

  # And then some optional options
  NoUglyURLs
  URI # Turn index.x into somevalue.x (similar to `RSSUri` in Hugo `0.19`)

So:

  • Name: The key.
  • Path - defaults to "", which is the root. Multiple outputs to the same suffix must be separated with a path, ie. "amp" for AMP output.
  • IsPlainText: Whether to parse the templates with text/template or html/template.
  • Protocol: I.e. webcal:// for calendar files. Defaults to the baseURL protocol.

Standard Output Formats

So, according to the above, the current Hugo will look like this:

Name MediaType Path IsPlainText
HTML text/html+html "" false
RSS application/rss+xml "" false

Layouts

The current situation (slightly simplified):

Kind Layouts
home index.html, _default/list.html
section section/SECTION.html, SECTION/list.html, _default/section.html, _default/list.html
taxonomy taxonomy/SINGULAR.html,_default/taxonomy.html, _default/list.html
taxonomyTerm taxonomy/SINGULAR.terms.html, _default/terms.html
page TYPE/LAYOUT.html, _default/LAYOUT.html, _default/single.html

The above is what the Output Format HTML must resolve to.

So, let us make up some other Output Formats and see how that will have to look:

Name MediaType Path IsPlainText
JSON application/json+json "" true
AMP text/html+html amp false

Both of the above can be handled if we add both Name and the Suffix to the mix. Let us use the home page as an example:

Type Layouts
JSON index.json.json, index.json, _default/list.json.json, _default/list.json
AMP index.amp.html, index.html, _default/list.amp.html, _default/list.html
  • The above adds the lower-case Name as a prefix to the lookup path.
  • The above also assumes that it makes sense to edit the templates with the same suffix as the end result (.html, .json etc.).

TODO: RSS, 404 etc.

Examples

config.toml:

# Add some custom output type definitions:
[[outputFormats]]
name = "Calendar"
mediaType = "text/calendar+ics"
protocol = "webcal://"
isPlainText = true

[[outputFormats]]
name = "JSON"
mediaType = "application/json" # Will get its file suffix from the sub-type, i.e. "json"
isPlainText = true

[[outputFormats]]
name = "AMP"
mediaType = "text/html"
path = "amp"

Note that Hugo well hard code a predefined list of the most common output types (not sure what that would be, suggestions welcome) with the obvious identifiers and sensible defaults: So whenever you want them, you can just say "json, yaml, amp ..." etc.

Page frontmatter:

title = "My Home Page"
outputs = ["html", "rss", "json", "calendar", "amp" ]

About the outputs in the page frontmatter:

  • If none is provided, it defaults to the current behaviour (HTML + RSS (for the list pages))
  • Is some are provided, no defaults will be added. So, if you want the plain HTML representation, you must be explicit. This way you can have the home page as JSON only if you want.
  • The names used are case-insensitive and must match either a definition in config.toml or the standard set.

Note that it should also be possible to set a list of default output formats in config.toml, avoiding the need to repeat the outputs list in thousands of pages, with a way to restrict each type to a set of pages (using Kind, probably).