Ryota400’s blog

エンジニアを目指して書いてます。

埋め込みメディアタイプにTwitterの追加

実装したいこと

twitterのツイートを埋め込みコンテンツとして選択できるようにする(タイムラインではない)
twitterが選択され、適切なURLが入力されたら、ツイートが表示されるようにする
youtubeに関しても、IDではなくURL(https://youtu.be/dZ2dcC4OnQE のような形式)を入力したら動画を表示できるようにする
カラム名は現状のままで構いません
・入力項目のラベル名も本来はURLに変えるべきではありますが自動テストの制約上IDのままにしてください
・貼り付けるべきURLはyoutube再生画面の「共有」を押した後に表示されるものとする。 ・ブロックヘッダーのアイコンもYoutube/Twitterと適切に切り替わるようにする
・ブロック追加画面のアイコンはYoutubeTwitterの二つが表示されるようにする

イメージ

Image from Gyazo

Image from Gyazo

Image from Gyazo

カラム準備

models/embed.rb

class Embed < ApplicationRecord

  enum embed_type: { youtube: 0, twitter: 1 }
#embed_typeでYoutubeかTwitterを選択する。

  validates :identifier, length: { maximum: 200 }
#identifierでURLを保存します。

  def split_id_from_youtube_url
    # YoutubeならIDのみ抽出
    identifier.split('/').last if youtube?
  end

end

説明

  def split_id_from_youtube_url
    # YoutubeならIDのみ抽出
    identifier.split('/').last if youtube?
  end

最初はgoogleyoutube投稿された全ての動画の全てに割り振ったURLの末尾の11桁のvideo_idと呼ばれる数字を抽出した。だが開始時間を指定したurlになると、末尾の11桁が変わってしまうので、splitを使用して「/」で区切りをつけて「last」=最後の部分のみ抽出する。

記事ブロックの見出しのアイコンもtwitter

app/decorators/article_block_decorator.rb

elsif embed?
      blockable.youtube? ? content_tag(:i, nil, class: 'fa fa-youtube-play') : content_tag(:i, nil, class: 'fa fa-twitter')
end

記事ブロック挿入画面のアイコンもtwitter

app/views/admin/articles/article_blocks/_insert_block.html.slim

.d-inline-flex
   i.fa.fa-youtube-play
   i.fa.fa-twittertter

Twitterカード表示部分の実装

app/views/shared/_embed_twitter.html.slim

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

Youtube埋め込みブロックのsrc部分を動的に指定

app/views/shared/_embed_youtube.html.slim

.embed-youtube
  = content_tag 'iframe', nil, width: width, height: height, src: "https://www.youtube.com/embed/#{embed.split_id_from_youtube_url}", \
    frameborder: 0, gesture: 'media', allow: 'encrypted-media', allowfullscreen: true

/ Youtube公式に乗っている埋め込み用のHTMLを出力する形にする。
/ #{embed.identifier.last(11)}でIDを切り取ると、開始秒指定されたときにOUT

app/views/admin/articles/article_blocks/_show_embed.html.slim

.box-body
  - if embed.identifier?
    - if embed.youtube?

      = render 'shared/embed_youtube', embed: embed, width: 560, height: 315
    - if embed.twitter?
      = render 'shared/embed_twitter', embed: embed

lib

複数のアプリケーション間で共有するライブラリを格納するディレクト

lib/tasks/temp/fix_embed_youtube_identifier.rake

namespace :fix_embed_youtube_identifier do
  desc 'IDを入力していたidentiferカラムの過去データを一括で修正'
  task update_old_identifier_for_youtube_embed: :environment do
    Embed.youtube.each do |embed|
      embed.update(identifier: "https://youtu.be/#{embed.identifier}")
    end
  end
end

参考文献

qiita.com

webukatu.com