はてなブログを利用・購読している人ならお馴染みのブログカードは、ブログの記事にカード形式の格好良いリンクを表示する機能です。こんな感じ。
記事タイトルや概要、アイキャッチ画像をひとまとめに表示してくれるのですが、これを WordPress でもやってみようという企画です。はてなの oEmbed API を利用します。
リンクの貼り方
WordPress の投稿画面のテキストエディタに次の形式でリンクを貼ります。
1 | <iframe src="http://hatenablog.com/embed?url=(リンクを貼りたい URL)"></iframe> |
テキストエディタではこうなります。
当ブログで表示してみるとこうなります。
ここからはスタイルシートを編集していきます。
CSS の編集
この方法は、はてなが出力したブログカード用の HTML ファイルを、iframe タグを使って自分のページに埋め込んでいるのですが、HTML5 から iframe 要素で指定できる属性が変更されたことを念頭に置いてスタイル指定をしてください。一例として、当ブログの設定をさらしてみます。
1 2 3 4 5 6 7 | iframe.blog-card { width: 80%; height: 155px; border: 0; margin: 0 0 1.7rem; display: block; } |
ネットで「wordpress ブログカード」などと検索すると、次のようなソースがでてくると思います。
1 | <iframe src="http://hatenablog.com/embed?url=(リンクを貼りたい URL)" frameborder="0" scrolling="no"></iframe> |
かつてはこのような記述が主流でしたが、frameborder 属性は HTML5 で廃止されましたので、「border: 0;」で対応します。今のところ、どのブラウザでも問題ありませんが、早めに対応しておきました。ちなみに、scrolling 属性も廃止されていますが、今回のブログカードに関係なかったので、特に指定し直していません。
「display: block;」により iframe 要素をブロック要素に指定。iframe は Inline FRAME の略であることからわかるようにインライン要素なので、文字が回りこまないようにするための措置です。テキストエディタで前後の文章に改行を挟めば回り込みを防げるので、なくても大丈夫です。
テキストエディタに貼り付けるリンクの形式を以下のように変更し、
1 | <iframe class="blog-card" src="http://hatenablog.com/embed?url=(リンクを貼りたい URL)"></iframe> |
スタイルの指定は完了でぃす。
すでに貼りつけちゃってるリンクはどうしよう?
最初からブログカードに対応していればこのような問題は起こりませんが、後から「うちのブログにもブログカード使いたい」ということもあるかもしれません。
一番確実な方法は、ひとつひとつ手作業で記事を修正することですが、プログラマたるもの楽をするために全力を尽くすべきなのであります。
WordPress にはフックという機能がありまして、今回は記事の本文を表示する「the_content」部分に add_filter 関数を使って介入します。リンクのみの行の HTML ソースを確認すると、
1 | <p><a href="○○○○○">(リンクの文字列)</a></p> |
このような構成になっていますので、この行を正規表現で抜き出し、ブログカード用の iframe に置き換えてやります。この場合、下のような文章中に含まれているリンクは置き換わりません。
以下のソースコードを function.php に追記します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | // 本文中のリンクをブログカードに変更する function link_to_blogcard($the_content) { // 投稿ページもしくは固定ページのとき if (is_singular()) { // リンクのみの行を全て $target に取得 preg_match_all('/^(<p>)(<a.+?>).+?(<\/a>)(<\/p>)$/im', $the_content, $target); // マッチしたリンクひとつひとつにループをまわす foreach ($target[0] as $tmp) { // Aタグからhref属性を取得 preg_match("|<a href=\"(.*?)\".*?>(.*?)</a>|mis", $tmp, $matches); $url = $matches[1]; // リンクをブログカードに置換 $the_content = preg_replace('{'.preg_quote($tmp).'}', '<iframe class="blog-card" src="http://hatenablog.com/embed?url='.$url.'"></iframe>', $the_content, 1); // メインクエリのグローバル変数を復元 wp_reset_postdata(); } } // 置換後のコンテンツを返す return $the_content; } // 本文表示をフック add_filter('the_content', 'link_to_blogcard'); |
A タグから href 属性を抜き出す部分のソースが汚いですがご容赦下さい。いずれはもっとシンプルに書き直したい。
先ほどのリンクがブログカードに置き換わりました。
今後の方針
「wordpress ブログカード」などで検索してもらうとわかるのですが、はてなの API を使ってブログカードを表示するこの方法は、リンクを貼られたサイトのリファラを見ると hatenablog.com になっているので、こちらがリンクを貼ったことを相手に伝えることができないという欠点があります。
以前、はてなの API を利用せず OGP ライブラリを使ってブログカードを表示しようと PHP ソースを書いたことがあるのですが、相手サイトの OGP を取得・取得した OGP をブログカードに加工・WordPress の記事を表示し終わるまでにとても時間がかかり、実用に耐えませんでした。ブログカードが表示されるまで本文がまったく表示されないのは致命的です。
これを解決するのに思いついた方法がふたつありまして、
- 画像の遅延ロードのように、ブログカード以外の本文は先に表示しておいて、ブログカードは必要な情報がそろってから表示させる
- 初回アクセスの場合のみ OGP ライブラリなどでブログカードに必要な情報を相手サイトから取得し自分のサーバに保存、初回以降は自分のところに保存した情報を使ってブログカードを表示する
というのを思いつきました。いずれ作ってみたいと思います。
Comment