Let's say you have an Article model with a field (string) called embed :
YouTube examples to handle:
https://www.youtube.com/watch?v=u75Zsl1ECPQ&list=PLu9lbDbw-S8zyBwu9_aA2nE-3QocgyzRE&index=4
https://www.youtube.com/watch?v=u75Zsl1ECPQ
https://youtu.be/u75Zsl1ECPQ
https://youtu.be/u75Zsl1ECPQ?t=12
etc..
In the model (note.. I'm not applying width and height in the iframe, because I'll handle it globally in a stylesheet. Also, you can remove that regex and uncomment self.embed.include? .. to achieve the same validation:
#show (before_save)
# Returns a string (html_safe) .. iframe element from the embed string field
def iframe
if self.embed.present?
### YouTube
## Browser link --- use array to handle most playlist links, etc
if self.embed =~ /^(https?:\/\/)?(www\.)?youtube.com\/watch\?v=/ # self.embed.include? 'https://www.youtube.com/watch?v='
("<iframe src='https://www.youtube.com/embed/#{self.embed[32..42]}' frameborder='0' allow='accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture' allowfullscreen></iframe>").html_safe
## YouTube share link --- using array, because .split('https://youtu.be/').last wouldn't handle start at option ()?t=12)
elsif self.embed =~ /^(https?:\/\/)?(www\.)?youtu.be\// # self.embed.include? 'https://youtu.be/'
("<iframe src='https://www.youtube.com/embed/#{self.embed[17..27]}' frameborder='0' allow='accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture' allowfullscreen></iframe>").html_safe
### Validate + Generate iframe for whatever other embeds you want to allow (Google Maps, Vimeo, etc)
# elsif
else
self.embed = nil
end
end
end
In the articles#show view (note.. bootstrap classes for handling responsiveness):
<% if @article.embed.present? # no markup if nil %>
<div class="embed-responsive embed-responsive-16by9">
<%= @article.iframe %>
</div><!-- .embed-responsive -->
<% end %>
If you want to grab the thumbnail for the embed, this method works the same way:
#_articles (before_save)
# Returns a string (html_safe) .. img element from the embed string field
def thumb
if self.embed.present?
### YouTube
## Each YouTube video has 4 generated images [ /0 .. /3 ]
if self.embed =~ /^(https?:\/\/)?(www\.)?youtube.com\/watch\?v=/
("<img alt='Media' class='card-img-top' src='https://img.youtube.com/vi/#{self.embed[32..42]}/0.jpg' />").html_safe
elsif self.embed =~ /^(https?:\/\/)?(www\.)?youtu.be\//
("<img alt='Media' class='card-img-top' src='https://img.youtube.com/vi/#{self.embed[17..27]}/0.jpg' />").html_safe
else
self.embed = nil
end
end
end
So, in the articles#index view, you could call on the thumb method:
<% if article.embed.present? %>
<%= link_to article.thumb, article_path(article) %>
<% end %>
In each case, you'll use an activerecord callback in the article.rb model:
before_save :iframe, :thumb
<%= raw(youtube_embed(@experiment.researchsection.videolink)) %>
`. Thanks @PrestonSpratt. – sscirrus Jan 22 '13 at 22:11