Hello,
I’m trying to construct a data-driven partial template which can serve any kind of embedded video, regardless of the provider, with only a url supplied in front matter. I’m starting with only YouTube and Vimeo, but it would be ideal to add functionality for many of the less prominent video providers as well. So, for example, in front matter a user could paste in any of the following URLs:
- http://www.youtube.com/watch?v=asxzkUjTMcE
- http://youtu.be/asxzkUjTMcE
- http://www.youtube-nocookie.com/v/asxzkUjTMcE?version=3&hl=en_US&rel=0
- http://vimeo.com/channels/staffpicks/10655199
- http://vimeo.com/10655199
- http://player.vimeo.com/video/10655199
and the referenced video will embed with the proper respective player. Before someone immediately replies, “Why not just paste in the video ID?”, please understand i’m going for the lowest common denominator here with respect to end-user behavior. From a usability standpoint, at least for the clients who will be using the sites i’m building, pasting in an entire URL, regardless of the provider, is more feasible than correctly identifying a video ID and then pasting only that into a front matter field.
Using Vimeo’s oEmbed tool, this is pretty straight forward, except for a few strange surprises (more on those some other time). YouTube’s oEmbed tool is a little less robust, but it providers similar functionality.
Here’s how i’ve got things setup so far:
Front matter
video:
url: "//vimeo.com/10655199"
description: ""
title: ""
another_param: ""
another_param_you_get_the_idea: ""
In whatever template i want a video
{{ partial "video.html" (dict "url" .Params.video.url ) }}
Partial template
{{ $vimeo := getJSON "https://vimeo.com/api/oembed.json?url=" .url }}
{{ with $vimeo.html }}
{{ . | safeHTML }}
{{ end }}
{{ $youtube := getJSON "https://www.youtube.com/oembed?url=" .url }}
{{ with $youtube.html }}
{{ . | safeHTML }}
{{ end }}
By the way, it’s easy and helpful to take a look at the data made available via oEmbed. In my example, one could do so this way:
{{ printf "%#v" $vimeo }}
{{ printf "%#v" $youtube }}
There’s a lot of flexibility and customization that could be achieved with this data, but i’ll save that for future post when i’ve actually got it working!
The problem
I need to write some conditional logic that will not return a build-error when no file is found. If the user pastes in a Vimeo url, then obviously the YouTube request will return file-not-found. And if s/he pastes in a YouTube url, the Vimeo request will return file not found. As i hopefully add additional players, this will only increase. This is the expected behavior since, again, i’m trying to create a one-size-fits-all solution wherein the user only interacts with one front matter param: “video”.
I’ve tried with
, if
, if ne
(to a length of 0 characters), if ne
(to nil), etc., but no matter what i get the same can’t-build-the-site error:
error calling getJSON: Failed to retrieve remote file: Not Found
The goal is to cycle through every provider until the url returns a result.
Any thoughts are most appreciated! And here’s an emoji since i’m new here and i want that emoji badge real bad.