cogdog
cogdog

Reputation: 98

How to replace hyperlinked URL to YouTube Video with embed

I am working with a static web site generator (Hugo) that converts all plaintext URLs in my source to hyperlinks to the same URL, e.g.

<p><a href="https://www.youtube.com/watch?v=xLrLlu6KDss">https://www.youtube.com/watch?v=xLrLlu6KDss</a></p>

I'd rather have that as an embedded video.

There are plenty of code bits to convert a plaintext YouTube URL to an embed (example) that work, but how can I get an embed when it is hyperlinked?

Or if someone can help me convert all href links where the link value is the same as the link name to just the plain URL? e.g. how to replace

<p><a href="https://www.youtube.com/watch?v=xLrLlu6KDss">https://www.youtube.com/watch?v=xLrLlu6KDss</a></p>

with

https://www.youtube.com/watch?v=xLrLlu6KDss

Upvotes: 2

Views: 2378

Answers (1)

Jack Taylor
Jack Taylor

Reputation: 6217

The best way to do this is to have Hugo make the embedding code itself. You can put the HTML code straight inside the markdown document if you like, or to make it easier, you can use a shortcode. Hugo even has a built-in shortcode for YouTube.

{{< youtube xLrLlu6KDss >}}

If you put that in your markdown document, Hugo will embed the YouTube video when it generates the page, and it doesn't require any custom jQuery code.


Edit:

If you absolutely have to do this with JavaScript, you can do something like this. (Note: this example requires jQuery.)

$("a").each(function () {
  // Exit quickly if this is the wrong type of URL
  if (this.protocol !== 'http:' && this.protocol !== 'https:') {
    return;
  }

  // Find the ID of the YouTube video
  var id, matches;
  if (this.hostname === 'youtube.com' || this.hostname === 'www.youtube.com') {
    // For URLs like https://www.youtube.com/watch?v=xLrLlu6KDss
    matches = this.search.match(/[?&]v=([^&]*)/);
    id = matches && matches[1];
  } else if (this.hostname === 'youtu.be') {
    // For URLs like https://youtu.be/xLrLlu6KDss
    id = this.pathname.substr(1);
  }

  // Check that the ID only has alphanumeric characters, to make sure that
  // we don't introduce any XSS vulnerabilities.
  var validatedID;
  if (id && id.match(/^[a-zA-Z0-9]*$/)) {
    validatedID = id;
  }

  // Add the embedded YouTube video, and remove the link.
  if (validatedID) {
    $(this)
      .before('<iframe width="200" height="100" src="https://www.youtube.com/embed/' + validatedID + '" frameborder="0" allowfullscreen></iframe>')
      .remove();
  }
});

This loops through all the links in the page, checks whether they are from YouTube, finds the video ID, validates the ID, and then converts the link into an embedded video. It is probably a good idea to tailor the "a" selector to only point to links in the content area, rather than the whole page. Also, I am guessing that this may be slow for pages with lots of links in; if that's the case, you might have to do some performance tuning.

Upvotes: 3

Related Questions