YouTubeやTwitterの埋め込み
フォームに入力されたURLを埋め込みに使いたい
youtube用埋め込みパーシャルのcontent_tagのsrc属性に、フォームから入力されたURLを入れ込む方法を取ろうとするも、ブラウザのyoutube埋め込み箇所には「www.youtube.com で接続が拒否されました。」という表示が出てしまい上手く行かなかった。
/ 変更前 .embed-youtube = content_tag 'iframe', nil, width: width, height: height, src: "https://www.youtube.com/embed/#{embed.identifier}", \ frameborder: 0, gesture: 'media', allow: 'encrypted-media', allowfullscreen: true / 変更後 .embed-youtube = content_tag 'iframe', nil, width: width, height: height, src: embed.identifier, \ frameborder: 0, gesture: 'media', allow: 'encrypted-media', allowfullscreen: true
埋め込むURLとブラウザで直接見るURLの違い
YouTube動画埋め込み時に「www.youtube.com で接続が拒否されました。」が表示された際に確認すること | アナライズギア開発ブログ
# 「共有」→「コピー」で取得できるURL https://youtu.be/IwFO-FNnvrM # 「共有」→「埋め込む」で取得 https://www.youtube.com/embed/IwFO-FNnvrM
埋め込んで使うタイプのURLにはホスト名とドメイン、ディレクトリ名が加わっていた。src属性にブラウザで直接見るためのURLを入れ込んでも上手く表示できなかったのはこのため。
では、どうしたら良いのか
入力されたURLから末尾のパスのみを取得する
【Ruby】URL文字列から、相対パスを取得する手順 - スリ飯屋MaLankaのフリーエンジニアな日々
やり方は↑のサイトを参考にしました。
※ この項目を書いている時点で相対パスのことをURL末尾のパスと思っていたため、以降の内容にも正しくない表記があるかもしれません。念のため
※ 相対パスとは、現在いるファイルを基準にして説明した対象ファイルの位置のことを指します。(ex: 私の右隣にAさんがいるので、私から見てAさんは私の右隣にいる。私は1階にいて兄は2階にいる。この時、私から見て兄は2階に位置している。)
コンソールで試してみる
※ 課題で元から作られていたアプリを使用しています。
[6] pry(main)> embed = Embed.first Embed Load (0.1ms) SELECT "embeds".* FROM "embeds" ORDER BY "embeds"."id" ASC LIMIT ? [["LIMIT", 1]] (0.1ms) select sql from (select * from sqlite_master where type='table' union select * from sqlite_temp_master where type='table') where tbl_name = 'embeds' => #<Embed:0x00000001330a7ee8 id: 1, embed_type: "youtube", identifier: nil, created_at: Mon, 25 Apr 2022 19:27:35 JST +09:00, updated_at: Mon, 25 Apr 2022 19:27:35 JST +09:00> [7] pry(main)> embed.identifier => nil [8] pry(main)> embed.identifier = 'https://youtu.be/IwFO-FNnvrM' => "https://youtu.be/IwFO-FNnvrM" [9] pry(main)> URI.parse(embed.identifier).path => "/IwFO-FNnvrM" [10] pry(main)> URI.parse(embed.identifier).path.delete('/') => "IwFO-FNnvrM"
# これでURLの末尾のパスのみ取得できる URI.parse(URL文字列).path # /(スラッシュ)はいらないの削除して相対パスを取得する URI(URL文字列).path.delete('/')
これらを踏まえて
def get_relative_path URI.parse(self.identifier).path.delete('/') end
- どこのモデルにギミックを記載すべきか分からないので、embed.rbに書いておいた
- 何通りか試したものの、全部上手く行かずに下記の感じにおさまった(良し悪しはさておき)
【追記】
メソッド名のgetは不適切とチェックが入ったため削除
def getrelative_path
冗長なselfとlintチェックで警告されたため削除
URI.parse(self.identifier).path.delete('/')
↓付随して下記の呼び出し元のビューファイルの表記も修正
.embed-youtube = content_tag 'iframe', nil, width: width, height: height, src: "https://www.youtube.com/embed/#{embed.relative_path}", \ frameborder: 0, gesture: 'media', allow: 'encrypted-media', allowfullscreen: true
- ビュー側でembedに対し、作成したギミックを呼び出し
URLの相対パスを取得するロジック(別解)
def split_id_from_youtube_url identifier.split('/').last if youtube? end
- もしYouTubeならスラッシュの区切り文字で分解し、末尾を取得
ツイッターの埋め込み
同じようなツイッター用埋め込みパーシャルを作って、下記サイトに書いてある通りにしたらできた。
TwitterのAPIを使わずに任意のツイートを埋め込む方法 - Sakura scope
.embed-twitter blockquote.twitter-tweet a href = "#{embed.identifier}" script async="" charset="utf-8" src="https://platform.twitter.com/widgets.js"