Combining Data Ranges and Short Codes

I’d like to use the YouTube shortcode in conjunction with data templates to show a list of videos that is driven by the contents of a JSON file.

Ideally, in site/content/, I’d have something like this:

# Some YouTube videos
{{ range $ }}
    {{< youtube .id >}}
{{ end }}

and in site/data/youtube.yml, I’d have something like this:

- id: abc123
- id: xyz456

so that each of the video ids that I list in my .yml file is rendered as an embedded YouTube video on my homepage.

The problem here is that I can’t seem to use hugo functions like range in .md files. When I try this, the first code snippet just gets rendered as text, rather than being replaced with YouTube videos.

Fair enough, let’s extract the code into a partial that lives in site/layouts/partials/youtube-list.html:

{{ range $ }}
    {{< youtube .id >}}
{{ end }} 

Then we’ll modify site/content/ to reference the partial:

# Some YouTube Videos
{{ partial "youtube-list.html" . }}

Now, when I try to run the server, Hugo tells me that I can’t use the < character in a partial:

ERROR 2018/01/05 11:30:33 partials/youtube-list.html : template: partials/youtube-list.html:2: unexpected "<" in command

Great. I suppose I could create a custom shortcode instead, but they appear to have the same limitation - a shortcode cannot reference another shortcode:

ERROR 2018/01/05 11:32:39 shortcodes/youtube-list.html : template: shortcodes/youtube-list.html:3: unexpected "<" in command

I guess I could find the source for the YouTube shortcode in Hugo’s GitHub repository and “borrow” it wholesale for use in my new shortcode, but that seems like unnecessary duplication of code.

tl;dr: Is there any way to combine data templates and shortcodes in Hugo so that the same shortcode is used to render each element in a list that is read from a data template?

You can only use shortcodes in content files. You can’t use shortcodes in templates, and you can’t use template logic in content.

You should probably create your own shortcode. You can see the embedded youtube shortcode here.