このような方向け
- WordPress投稿画面にYouTubeの動画URLそのまま貼り付けで生成されるiframeプレイヤーがとにかく扱いづらい
- かといって、YouTube動画の埋め込みコードを毎回コピペするのが面倒くさい
この問題に対し、以下を自動化する事で記事制作コストの低減を目指します。
- 自動生成されるiframeからwidthとheightの指定を取り除き
- iframeに特定のclassを持つ親要素を付与する
- レスポンシブ対応する
これで、投稿画面でYouTube動画URLをそのまま貼り付けてもレスポンシブ対応したプレイヤーが生成されます。
解決方針
WordPressの投稿画面でYouTubeの動画URLを直貼りすると、こんなhtmlが生成されます。
<p><iframe width="XXX" height="YYY" src="https://www.youtube.com/embed/V39lXlaj830?feature=oembed" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe></p>
これを以下のように自動変換します。
<div class="youtube"><iframe src="https://www.youtube.com/embed/V39lXlaj830?feature=oembed" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe></div>
- iframeタグから width=”XXX” と height=”YYY” を消し
- iframeの親要素に class=”youtube” を加える
CSSで iframe の親要素である p.youtube に対してプレイヤーをレスポンシブ対応するスタイリングを行っています(おまけで後述します)。
function.php
上記にあるhtmlを自動変換する処理を function.php に記述します。
//投稿画面のYouTubeのURL直貼りにclassを自動で加える
function youtube_tag_replace($content) {
$pattern = '#<p><iframe (.+?) src="https://www.youtube.com/(.+?)</p>#i';
$replace = '<div class="youtube"><iframe src="https://www.youtube.com/$2</div>';
return preg_replace($pattern, $replace, $content);
}
add_filter('the_content', 'youtube_tag_replace');
変数$1には width と height 表記を格納し、置換後は削除。
変数$2には youtube.com/ 以降の表記を格納し、置換後もそのまま流用。
#i はPHP正規表現のパターン修飾子のひとつで、マッチ部分の大文字と小文字を区別しないオプションを示します。
久しぶりに正規表現を使いました。
あと今回はじめて知ったのですが、PHPのデリミタはスラッシュ以外にも # や ~ が使えるらしく、スラッシュ以外で囲うとスラッシュをいちいちエスケープしなくて良いという嬉しいメリットがありました。今回は # を使いました。
注意点1
URLを貼る行の上と下に、それぞれ改行を入れて下さい。
URLを貼った行の直前や直後の行に文章があると、
でくくられずに前後に
が付きますので、パターンにマッチしなくなります。
注意点2
動画アップロード者により貼り付けが許可されていない動画は、そもそもURLそのまま貼り付け自体に対応していないので無効(ただURLのテキストが載るだけ)となります。
この場合はしかたなくembedコードを貼り付けるしかありません。
基本的には以上です。
おまけ. YouTubeプレイヤーをレスポンシブ対応させるCSS
もうすっかりスタンダードになっている気がしますが、備忘も兼ねて掲載しておきます。
.youtube {
padding-bottom:56.25%;
position:relative;
overflow:hidden;
}
.youtube iframe {
position:absolute;
top:0;
left:0;
width:100%;
height:100%;
}
CONVERSATION