youtube、twitterの埋め込み

アプリにyoutube動画とtwittertweetを表示させてみました。
APIを使う方法とローカルで埋め込む方法がありますが、今回はローカルで埋め込む方法でやっていきます。
レイアウトが崩れてますが完成形はこんな感じです。

Image from Gyazo

ではアプリの新規作成からやっていきましょう。

rails new embed_app
cd embed_app

で新規作成、移動したら

rails g scaffold Article title:string youtube_url:string twitter_url:string
rails db:migrate

scaffoldしてmigrateします。
viewはslimで書くのでgem slim-railshtml2slimを入れてます。

youtubeの埋め込み

まずはyoutubeからいきます。
記事詳細ページに埋め込みたいのでshow.html.slimを編集しましょう。

p#notice = notice

p
  strong Title:
  = @article.title
p
  strong Youtube url:
  .embed-youtube
  = content_tag 'iframe', nil, width: 560, height: 315, src: "https://www.youtube.com/embed/#{@article.split_id_from_youtube_url}", \
    frameborder: 0, gesture: 'media', allow: 'encrypted-media', allowfullscreen: true
p
  strong Twitter url:
  = @article.twitter_url

=> link_to 'Edit', edit_article_path(@article)
'|
=< link_to 'Back', articles_path

youtube動画の埋め込みはこんな感じです。
src@article.split_id_from_youtube_urlですが、モデルで

class Article < ApplicationRecord
  def split_id_from_youtube_url
    youtube_url.split('/').last
  end
end

こんなメソッドを定義しています。
splitメソッドで、受け取ったyoutube_urlを引数で指定した「/」で区切り、配列に入れています。
lastメソッドでその配列の一番後ろのものを取得しています。

Image from Gyazo

配列の一番後ろはyoutube動画の固有のIDである、11桁の英数字です。
動画の「共有」をクリックすると下のような共有用URLが表示されます。

https://youtu.be/L11fcH1J5tw

これをフォームに入力するとsplit_id_from_youtube_urlメソッドが動画のIDを切り出して

https://www.youtube.com/embed/L11fcH1J5tw

という形に変換してくれます。
(動画を埋め込む際はhttps://www.youtube.com/embed/動画IDという形式にする必要があります)
しかし

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

のような形式を入力するとうまく動画を埋め込むことができません。
先程のメソッドに当てはめるとwatch?v=L11fcH1J5twが取得されて

https://www.youtube.com/embed/watch?v=L11fcH1J5tw

というURLになってしまうからです。
そこでif文でこのように分岐させてみました。(もうちょっといい感じに書けそうですがうまくリファクタリングできませんでした)

strong Youtube url:
.embed-youtube
- if @article.youtube_url.include?('watch?v=')
  = content_tag 'iframe', nil, width: 560, height: 315, src: "https://www.youtube.com/embed/#{@article.youtube_url.last(11)}", \
    frameborder: 0, gesture: 'media', allow: 'encrypted-media', allowfullscreen: true
- else
  = content_tag 'iframe', nil, width: 560, height: 315, src: "https://www.youtube.com/embed/#{@article.split_id_from_youtube_url}", \
    frameborder: 0, gesture: 'media', allow: 'encrypted-media', allowfullscreen: true

動画のURLをそのままコピペしたらif、共有URLをコピペしたらelseに分岐して、
どちらのパターンでも動画が埋め込みできるようになりました。

twitterの埋め込み

次はtwitterの埋め込みです。

  .embed-twitter
    blockquote.twitter-tweet
      a href="#{@article.twitter_url}"
  script async="" charset="utf-8" src="https://platform.twitter.com/widgets.js"

こんな感じです。
https://publish.twitter.comのフォームにツイートのURLを入力すると埋め込み用のコードがコピーできます。
それをslim記法に直して必要なものだけ取り出したのが上記のコードです。
ただしhref属性を動的に変えるため"#{@article.twitter_url}"としています。

最終的なコードがこちらです。

p#notice = notice

p
  strong Title:
  = @article.title
p
  strong Youtube url:
  .embed-youtube
  - if @article.youtube_url.include?('watch?v=')
    = content_tag 'iframe', nil, width: 560, height: 315, src: "https://www.youtube.com/embed/#{@article.youtube_url.last(11)}", \
      frameborder: 0, gesture: 'media', allow: 'encrypted-media', allowfullscreen: true
  - else
    = content_tag 'iframe', nil, width: 560, height: 315, src: "https://www.youtube.com/embed/#{@article.split_id_from_youtube_url}", \
      frameborder: 0, gesture: 'media', allow: 'encrypted-media', allowfullscreen: true
p
  strong Twitter url:
  .embed-twitter
    blockquote.twitter-tweet
      a href="#{@article.twitter_url}"
  script async="" charset="utf-8" src="https://platform.twitter.com/widgets.js"

=> link_to 'Edit', edit_article_path(@article)
'|
=< link_to 'Back', articles_path

最後に

無事、埋め込むことができました。
youtubetwitterの埋め込みは汎用性が高そうですね。
今回は以上です。ありがとうございました。

参考サイト

動画と再生リストを埋め込む - YouTube ヘルプ

タイムラインを埋め込む方法

【Rails】YoutubeとTwitterをAPIを使わずに記事に埋め込む - Ruby on Rails Learning Diary

railsアプリに投稿されたYouTubeURLを自動的に埋め込み表示させる方法~無理やり編~ - Qiita