2015-02-11 18:16:03 -05:00
---
aliases:
2015-07-23 06:54:58 -04:00
- /doc/datadrivencontent/
2016-01-06 17:45:19 -05:00
lastmod: 2015-07-23
2015-02-11 18:16:03 -05:00
date: 2015-02-14
menu:
main:
parent: extras
next: /extras/highlighting
prev: /extras/datafiles
2015-07-23 06:54:58 -04:00
title: Data-driven Content
2015-02-11 18:16:03 -05:00
weight: 91
2015-05-11 12:39:40 -04:00
toc: true
2015-02-11 18:16:03 -05:00
---
2015-07-23 06:54:58 -04:00
Data-driven content with a static site generator? Yes, it is possible!
2015-02-11 18:16:03 -05:00
2015-02-15 01:41:46 -05:00
In addition to the [data files ](/extras/datafiles/ ) feature, we have also
2015-07-23 06:54:58 -04:00
implemented the feature "Data-driven Content", which lets you load
2015-02-14 18:01:58 -05:00
any [JSON ](http://www.json.org/ ) or
[CSV ](http://en.wikipedia.org/wiki/Comma-separated_values ) file
from nearly any resource.
2015-02-11 18:16:03 -05:00
2015-07-23 06:54:58 -04:00
"Data-driven Content" currently consists of two functions, `getJSON`
2015-03-18 02:44:12 -04:00
and `getCSV` , which are available in **all template files** .
2015-02-11 18:16:03 -05:00
2015-02-13 01:21:26 -05:00
## Implementation details
2015-02-11 18:16:03 -05:00
2015-02-13 01:21:26 -05:00
### Calling the functions with an URL
2015-02-11 18:16:03 -05:00
2015-03-18 01:53:17 -04:00
In any HTML template or Markdown document, call the functions like this:
2015-02-14 18:01:58 -05:00
2015-03-18 02:44:12 -04:00
{{ $dataJ := getJSON "url" }}
{{ $dataC := getCSV "separator" "url" }}
2015-02-14 18:01:58 -05:00
2015-03-18 01:53:17 -04:00
or, if you use a prefix or postfix for the URL, the functions
2015-02-15 01:41:46 -05:00
accept [variadic arguments ](http://en.wikipedia.org/wiki/Variadic_function ):
2015-02-11 19:40:06 -05:00
2015-03-18 02:44:12 -04:00
{{ $dataJ := getJSON "url prefix" "arg1" "arg2" "arg n" }}
{{ $dataC := getCSV "separator" "url prefix" "arg1" "arg2" "arg n" }}
2015-02-11 19:40:06 -05:00
2015-03-18 02:44:12 -04:00
The separator for `getCSV` must be put in the first position and can only
2015-03-18 01:53:17 -04:00
be one character long.
2015-02-11 19:40:06 -05:00
2015-03-18 01:53:17 -04:00
All passed arguments will be joined to the final URL; for example:
2015-02-11 19:40:06 -05:00
2015-02-13 01:21:26 -05:00
{{ $urlPre := "https://api.github.com" }}
2015-03-18 02:44:12 -04:00
{{ $gistJ := getJSON $urlPre "/users/GITHUB_USERNAME/gists" }}
2015-02-11 19:40:06 -05:00
2015-02-13 01:21:26 -05:00
will resolve internally to:
2015-02-11 19:40:06 -05:00
2015-03-18 02:44:12 -04:00
{{ $gistJ := getJSON "https://api.github.com/users/GITHUB_USERNAME/gists" }}
2015-02-11 19:40:06 -05:00
2015-03-18 01:53:17 -04:00
Finally, you can range over an array. This example will output the
first 5 gists for a GitHub user:
2015-02-14 18:01:58 -05:00
< ul >
2015-03-18 01:53:17 -04:00
{{ $urlPre := "https://api.github.com" }}
2015-03-18 02:44:12 -04:00
{{ $gistJ := getJSON $urlPre "/users/GITHUB_USERNAME/gists" }}
2015-03-18 01:53:17 -04:00
{{ range first 5 $gistJ }}
{{ if .public }}
< li > < a href = "{{ .html_url }}" target = "_blank" > {{ .description }}< / a > < / li >
{{ end }}
{{ end }}
2015-02-14 18:01:58 -05:00
< / ul >
2015-02-13 01:21:26 -05:00
2015-02-11 19:40:06 -05:00
2015-02-13 01:21:26 -05:00
### Example for CSV files
2015-02-11 19:40:06 -05:00
2015-03-18 02:44:12 -04:00
For `getCSV` , the one-character long separator must be placed in the
2015-02-14 18:01:58 -05:00
first position followed by the URL.
< table >
< thead >
< tr >
< th > Name< / th >
< th > Position< / th >
< th > Salary< / th >
< / tr >
< / thead >
< tbody >
{{ $url := "http://a-big-corp.com/finance/employee-salaries.csv" }}
{{ $sep := "," }}
2015-03-18 02:44:12 -04:00
{{ range $i, $r := getCSV $sep $url }}
2015-02-14 18:01:58 -05:00
< tr >
< td > {{ index $r 0 }}< / td >
< td > {{ index $r 1 }}< / td >
< td > {{ index $r 2 }}< / td >
< / tr >
{{ end }}
< / tbody >
< / table >
The expression `{{index $r number}}` must be used to output the nth-column from
the current row.
2015-02-13 01:21:26 -05:00
### Caching of URLs
2015-02-14 18:01:58 -05:00
Each downloaded URL will be cached in the default folder `$TMPDIR/hugo_cache/` .
2015-03-18 01:53:17 -04:00
The variable `$TMPDIR` will be resolved to your system-dependent
2015-02-14 18:01:58 -05:00
temporary directory.
2015-02-13 01:21:26 -05:00
2015-03-18 01:53:17 -04:00
With the command-line flag `--cacheDir` , you can specify any folder on
2015-02-14 18:01:58 -05:00
your system as a caching directory.
2015-02-13 01:21:26 -05:00
2015-02-15 01:41:46 -05:00
If you don't like caching at all, you can fully disable to read from the
2015-03-18 01:53:17 -04:00
cache with the command line flag `--ignoreCache` . However, Hugo will always
2015-02-14 18:01:58 -05:00
write, on each build of the site, to the cache folder (silent backup).
2015-02-13 01:21:26 -05:00
### Authentication when using REST URLs
2015-02-11 19:40:06 -05:00
2015-03-18 01:53:17 -04:00
Currently, you can only use those authentication methods that can
2015-02-15 01:41:46 -05:00
be put into an URL. [OAuth ](http://en.wikipedia.org/wiki/OAuth ) or
other authentication methods are not implemented.
2015-02-11 19:40:06 -05:00
2015-02-13 01:21:26 -05:00
### Loading local files
2015-02-11 19:40:06 -05:00
2015-03-18 02:44:12 -04:00
To load local files with the two functions `getJSON` and `getCSV` , the
2015-03-18 01:53:17 -04:00
source files must reside within Hugo's working directory. The file
2015-02-14 18:01:58 -05:00
extension does not matter but the content.
2015-02-11 19:40:06 -05:00
2015-02-14 18:01:58 -05:00
It applies the same output logic as in the topic: *Calling the functions with an URL* .
2015-02-11 19:40:06 -05:00
2015-03-18 01:53:17 -04:00
## LiveReload
2015-02-11 19:40:06 -05:00
2015-02-14 18:01:58 -05:00
There is no chance to trigger a [LiveReload ](/extras/livereload/ ) when
2015-03-18 01:53:17 -04:00
the content of an URL changes. However, when a local JSON/CSV file changes,
then a LiveReload will be triggered of course. Symlinks not supported.
2015-02-14 18:01:58 -05:00
2015-03-18 01:53:17 -04:00
**URLs and LiveReload**: If you change any local file and the LiveReload
got triggered, Hugo will either read the URL content from the cache or, if
2015-02-15 01:41:46 -05:00
you have disabled the cache, Hugo will re-download the content.
This can create huge traffic and you may also reach API limits quickly.
2015-02-13 01:21:26 -05:00
2015-02-15 01:41:46 -05:00
As downloading of content takes a while, Hugo stops with processing
2015-03-18 01:53:17 -04:00
your Markdown files until the content has been downloaded.
2015-02-13 01:21:26 -05:00
2015-02-14 18:01:58 -05:00
## Examples
2015-02-13 01:21:26 -05:00
2015-02-14 18:01:58 -05:00
- Photo gallery JSON powered: [https://github.com/pcdummy/hugo-lightslider-example ](https://github.com/pcdummy/hugo-lightslider-example )
2015-03-18 01:53:17 -04:00
- GitHub Starred Repositories [in a posts ](https://github.com/SchumacherFM/blog-cs/blob/master/content%2Fposts%2Fgithub-starred.md ) with the related [short code ](https://github.com/SchumacherFM/blog-cs/blob/master/layouts%2Fshortcodes%2FghStarred.html ).
- More? Please tell us!