Wagtailでメディアを埋め込みする[Embed Media]

YouTubeやTwitterなどのコンテンツを記事に埋め込む方法と仕組みを解説します。

Wagtailでメディアを埋め込みする[Embed Media]

Wagtailで運営するメディア記事の中でYouTubeの動画やTwitterのツイートを埋め込みしたいことがあります。これはEmbedと呼ばれる技術で、URLを入力するとそれに対応した形で記事に埋め込みコンテンツが展開されます。埋め込みコンテンツのHTMLはそれぞれのサービスで実装されており、コンテンツを呼び出す側はURLをしていするだけでメディアをリッチにできるのでとても便利な仕組みです。今回の記事ではWagtailでこのEmbedを利用する方法とその裏側の仕組みについて解説します。

oEmbedとは?

まずはEmbedの仕組みについてもう少し深堀りします。

埋め込み用のコンテンツを取得するための統一規格としてoEmbedと呼ばれるものがあります。oEmbedの仕様に沿って各サービスが埋め込みコンテンツ用の実装をすることで、様々なサービスのコンテンツの埋め込みを同じように扱うことができます。YouTubeやTwitter、SlideShareやSpotifyなど、世界的に人気な多くのサービスがこのoEmbedの規格に対応しており、Embedのデファクトスタンダードになっています。oEmbedでは、YouTubeの動画やTwitterのツイートなどの特定のURLを指定することで、その埋め込み用のコードを取得できます。この仕組みにより、メディアを運営している人が簡単に埋め込みコンテンツを表示できるようになっているのです。WagtailもデフォルトではこのoEmbedの仕組みを利用しており、この規格をもとにデータを扱うようになっているのです。

WagtailのEmbedモデル

それではWagtailにおけるEmbedの仕組みについて確認していきましょう。Wagtailでは埋め込み用のコンテンツを扱うためにEmbedというモデルが定義されています。Embedモデルに従って埋め込みコンテンツの情報を各サービスから取得し、情報を保持することで、Wagtail内で再利用できるようになっています。

Embedモデルはwagtail.embeds.models.Embedで定義されており、以下のようなフィールドを持っています。

  • url: コンテンツのオリジナルのURL
  • max_width: コンテンツの最大のwidth(指定した場合)
  • type: コンテンツのタイプ。 videophotolinkrichのいずれかの値をとる
  • html: ページに埋め込まれるHTML
  • title: コンテンツのタイトル
  • author_name: 作者名
  • provider_name: コンテンツのプロバイダの名前。YouTubeやTwitterなどのプラットフォーム名
  • thumbnail_url: ページに埋め込まれるサムネイル画像のURL
  • width: 画像か動画の横幅
  • height: 画像か動画の高さ
  • last_updated: Embedの情報を最後に取得した日時

これらのフィールドの情報はoEmbedの規格でも指定される情報であり、最初にコンテンツのURLにアクセスしたときにそれぞれのプロバイダから取得されるデータになります。

実際に利用する例を考えてみましょう。

Wagtailの管理画面からとあるYouTubeの動画を埋め込みする場合、そのYouTube動画のURLをコピーしておきます。この後解説しますが、WagtailではRichTextのエディタからEmbedのコンテンツを簡単に入力できるようになっており、そこにコピーしたURLを入力することで、Embedモデルのそれぞれのフィールドに必要な情報をYouTubeのサーバーから取得して、Embedモデルのインスタンスとしてデータベースに保存します。そのデータを利用して、テンプレート上にその埋め込みコンテンツのHTMLを付け加え、ページにYouTube動画を表示することができるようになるのです。URLを入力するだけでページに動画やツイートなどのコンテンツを綺麗に表示できるのでとても便利な仕組みです。

Embedモデルを利用する4つの方法

WagtailでEmbedモデルを利用する方法は4つあります。よく利用する方法から順に紹介していきます。

RichtText

RichTextではデフォルトでコンテンツの埋め込みができるようになっています。エディタのツールバーの再生マークのようなものからEmbedを利用することができます。

RichTextのEmbedボタン

埋め込みしたいコンテンツのURLを入力します。このサンプルではYouTubeの動画のURLを指定しています。

YouTubeのURLを指定

そのコンテンツのURLからEmbedに必要なデータが取得されます。それらはEmbedモデルのインスタンスとしてデータベースに保存され、エディタ内でもサムネイルで表示されます。

RichTextエディタ内でのEmbedサムネイル

テンプレート側での表示は通常のRichTextでの実装と同じで、RichText内で自動的にこのコンテンツの埋め込み用のHTMLがレンダリングされます。

ここで、実際にEmbedモデルのインスタンスとして登録された情報をデータベースにアクセスして確認してみましょう。コマンドラインでWagtailのshellにアクセスしてデータを引き出してみます。Embedモデルのフィールドを呼び出してみると、入力した動画URLに関連した情報が保存されているのがわかります。

# Wagtailプロジェクトのルートディレクトリ(manage.pyファイルがあるところ)で実行する

$ python manage.py shell
>>> from wagtail.embeds.models import Embed # Embedモデルをインポート
>>> content = Embed.objects.last() # Embedモデルで最後に登録したインスタンスを取得
>>>
>>> content.title
'White Wagtail Singing and Calling'
>>>
>>> content.url
'https://www.youtube.com/watch?v=Ffu-2jEdLPw'
>>>
>>> content.html
'<iframe width="200" height="113" src="https://www.youtube.com/embed/Ffu-2jEdLPw?feature=oembed" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>'

{% embed %}タグ

二つ目は{% embed %}タグを利用する方法です。こちらはテンプレート側で埋め込みたいコンテンツのURLを指定することで同じようにEmbedモデルのインスタンスとしてデータが登録されて、ページにコンテンツが表示されます。ページのバナーやヘッダーなどに埋め込みコンテンツを活用する場合にはこの方法を使うのが良いでしょう。

{% embed %}タグを利用するにはテンプレート内でwagtailembeds_tagsをロードする必要があるので忘れないようにしましょう。

{% load wagtailembeds_tags %}

{# YouTubeのコンテンツを埋め込み #}
{% embed 'https://www.youtube.com/watch?v=Ffu-2jEdLPw' %}

{# 変数からURLを指定することもできる #}
{% embed page.video_url %}

{# オプションで最大幅を指定することもできる #}
{% embed page.video_url max_width=500 %}

StreamFieldで利用する

様々なタイプのブロックを組み合わせて利用するStreamFieldの中にもEmbedBlockで埋め込みコンテンツを取り入れることができます。RichTextを利用しないような場面ではEmbedBlockを直接利用するのが良いでしょう。

# models.py

from wagtail.embeds.blocks import EmbedBlock


class MyStreamField(blocks.StreamBlock):
    ...
    embed = EmbedBlock()

Pythonから利用する

EmbedモデルはPythonのコードからも呼び出すことができます。Embedモデルのインスタンスのデータを加工したい場合や、Webサービスの機能の一部として利用する場合などにこの方法を使うと良いでしょう。

Wagtailのget_embed関数にURLを入力することでEmbedモデルのインスタンスを作成することができます。この関数にはmax_widthパラメータも指定することができ、埋め込みコンテンツの最大サイズを制限することができます。

from wagtail.embeds.embeds import get_embed
from wagtail.embeds.exceptions import EmbedException

try:
    embed = get_embed('https://www.youtube.com/watch?v=Ffu-2jEdLPw')
except EmbedException:
    # embedコンテンツが見つからない場合のエラーハンドリング
    pass

以上がWagtailでEmbedを利用する方法になります。様々なサービスのコンテンツを利用してメディアを一気にリッチにできるので、ぜひ積極的に利用しましょう。