■現状:

現在、埋め込みタイプとして選択できるのは、YouTubeの一択です。

Untitled

■期待する機能:

①組み込みタイプに「Twitter」を追加する。

②ブロックヘッダーのアイコンもYoutube/Twitterと適切に切り替わるようする。

③Twitterが選択された場合とYouTubeが選択された場合で処理を分岐。

④ブロック追加画面のアイコンはYoutubeとTwitterの二つが表示されるようにしてください。

⑤Youtube/TwitterどちらもURLでカードが表示されるようする。

⑥twitterのツイートを埋め込みコンテンツとして選択できるようにしてください(タイムラインではありません)。

===========================================================================

■導入手順

①enumの作成

Untitled

app/models/embed.rb

class Embed < ApplicationRecord
  has_one :article_block, as: :blockable, dependent: :destroy
  has_one :article, through: :article_block

  enum embed_type: { youtube: 0, twitter: 1 } #youtubeとtwitterを追加する。 追加したら、選択欄に2つが選択できるようになる。

  validates :identifier, length: { maximum: 200 }
end
app/views/admin/articles/article_blocks/_edit_embed.html.slim

.box-body
= f.input :embed_type, collect: Embed.embed_types_i18n.invert, include_blank: false
= f.input :identifier

#simple_formの中で、Youtubeかtwitterかを選択し、identifierを入力できるようなフォームにします。

②記事ブロック見出しアイコンをTwitterに対応させる/③Twitterが選択された場合とYouTubeが選択された場合で処理を分岐。

下記のように、コンテンツの横にアイコンが出るようにする。

Untitled

Untitled

app/decorators/article_block_decorator.rb

module ArticleBlockDecorator
def box_header_iconif sentence?
      '<i class="fa fa-edit"></i>'.html_safe
    elsif medium?
      '<i class="fa fa-image"></i>'.html_safe
    elsif embed?
      blockable.youtube? ? '<i class="fa fa-youtube-play"></i>'.html_safe : '<i class="fa fa-twitter"></i>'.html_safe # 三項演算子を使いスッキリ書く
	    # blockable.youtube = ブロック追加でyoutubeを選択するか否か。youtubeを選択した場合は、埋め込みの横に「YouTubeロゴ」を出す。それ以外は「Twitterロゴ」を出す
		end
  end
end

Rspecで引っかかる記載:

このようにif文の中にif文を作ると、RubocopのLintチェックに引っかかりました。

Metrics/PerceivedComplexity: Perceived complexity for box_header_icon is too high. [8/7]

app/decorators/article_block_decorator.rb

module ArticleBlockDecorator
def box_header_icon
		if sentence?
      '<i class="fa fa-edit"></i>'.html_safe
    elsif medium?
      '<i class="fa fa-image"></i>'.html_safe
    elsif embed?
      if blockable.embed_type == 'youtube'   #if文の中にif文を入れると処理が複雑化しすぎるため、処理が遅くなる!!!
        '<i class="fa fa-youtube-play"></i>'.html_safe
      elsif blockable.embed_type == 'twitter'
        '<i class="fa fa-twitter"></i>'.html_safe
      end
    end
  end
end

④ブロック追加画面のアイコンはYoutubeとTwitterの二つが表示されるようにしてください。

記事ブロック挿入画面のアイコンを、YouTubeとTwitterが横並びになるようする。

Untitled

= link_to admin_article_article_blocks_path(article.uuid), \
	class: %w[btn btn-app btn-default js-insert-article-block], \
	data: { \
		remote: true, \
		disable: true, \
		method: :post, \
		params: { article_block: { level: level, blockable_type: 'embed' } } \
		} do

		**.d-inline-flex #**インラインのFlexコンテナーでこれで囲うことで表示を横並びにできる!!
			**i.fa.fa-youtube-play
			i.fa.fa-twitter**
		'
		| 埋め込み

[checkポイント]
bootstrapで用意されているインラインのFlexコンテナーです。 
こちらを使うことで、横並びを実現しています。 

ブラウザでは下記のようにレンダリングされています。
<div class="d-inline-flex">
  <i class="fa fa-youtube-play"></i>
  <i class="fa fa-twitter"></i>
</div>

⑤Youtube/TwitterどちらもURLでカードが表示されるようする。

youtube再生画面の「共有」を押した後に表示される埋め込み用URLというのは、以下の構成になっています。

Untitled

https://www.youtube.com/embed/11桁のID

[重要ポイント]
各動画は / より後ろの文字列により個別に分類されているので、
上記のURLを取得後、 / より後ろの文字列を取得し、「任意のYouTubeのID」に代入すると任意のYouTubeが表示されるようになります。

ID抽出メソッド作成:

以下のように、/ を区切り文字としてyoutubeのURLを後ろのidのみを抽出するsplitメソッドをEmbedモデル定義しましょう。

app/models/embed.rb

class Embed < ApplicationRecord
  has_one :article_block, as: :blockable, dependent: :destroy
  has_one :article, through: :article_block

	def split_id_from_youtube_url
    identifier.split('/').last if youtube? #splitメソッドで「/」を区切り文字としてyoutubeのURLを後ろのidのみを抽出する!!!!
  end

  enum embed_type: { youtube: 0, twitter: 1 } #youtubeとtwitterを追加する。 追加したら、選択欄に2つが選択できるようになる。

  validates :identifier, length: { maximum: 200 }
end

embedに対して、作成したメソッドを実行して下11桁の文字列だけ取り出して表示させましょう。

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  #{}の中に上でメソッド定義した「split_id_from_youtube_url」を入れる

⑥twitterのツイートを埋め込みコンテンツとして選択できるようにしてください(タイムラインではありません)。

tweet埋め込みツールは公式にて用意されています。

https://publish.twitter.com/#

公式ツールからコピーした埋め込み用HTML

<blockquote class="twitter-tweet">
	<p lang="en" dir="ltr">Sunsets don't get much better than this one over 
		<a href="[https://twitter.com/GrandTetonNPS?ref_src=twsrc^tfw](https://twitter.com/GrandTetonNPS?ref_src=twsrc%5Etfw)">@GrandTetonNPS</a>. 
		<a href="[https://twitter.com/hashtag/nature?src=hash&amp;ref_src=twsrc^tfw](https://twitter.com/hashtag/nature?src=hash&amp;ref_src=twsrc%5Etfw)">#nature</a> 
		<a href="[https://twitter.com/hashtag/sunset?src=hash&amp;ref_src=twsrc^tfw](https://twitter.com/hashtag/sunset?src=hash&amp;ref_src=twsrc%5Etfw)">#sunset</a> 
		<a href="[http://t.co/YuKy2rcjyU](http://t.co/YuKy2rcjyU)">[pic.twitter.com/YuKy2rcjyU](http://pic.twitter.com/YuKy2rcjyU)</a>
  </p>
		<a href="[https://twitter.com/Interior/status/463440424141459456?ref_src=twsrc^tfw](https://twitter.com/Interior/status/463440424141459456?ref_src=twsrc%5Etfw)">May 5, 2014</a>
</blockquote> 
<script async src="[https://platform.twitter.com/widgets.js](https://platform.twitter.com/widgets.js)" charset="utf-8"></script>

無駄な部分を省いて、必要な部分だけ残します。

公式ツールからコピーした埋め込み用HTML

<blockquote class="twitter-tweet">
	<a href="https://twitter.com/freelife_blog/status/1461534705292132354?ref_src=twsrc%5Etfw"></a>
</blockquote>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

slim形式に変換して整えます。

app/views/shared/_embed_twitter.html.slim

.embed-twitter
	blockquote.twitter-tweet
		a href="#{embed.identifier}" # tweetのURL部分に、embedのidentifierを入れる
	script async="" charset="utf-8" src="[https://platform.twitter.com/widgets.js](https://platform.twitter.com/widgets.js)"