ogp.inc.php
はてなブログの「ブログカード」は魅力的でPukiwikiにも導入したいと思い、自分で見よう見まねでプラグインを作成して個人用のPukiwikiで利用していましたが、せっかくですのでこの外部のOGPを取得してブログカードとして表示するPukiwikiプラグインを公開することにしました。
外部のOGPを取得してブログカードとして表示するプラグイン
2021年12月からGitHubで公開することにしました。
- Pukiwiki 1.5.3および1.5.4RC、PHP 7.4〜8.1で動作確認しています。
- プラグイン本体はGPL v3です。
外部のサイトのHTMLに記載されたmetaタグからOGP情報を取得して、そのタイトル・description・URLおよびアイキャッチ画像のサムネイルをコンパクトなブログカードの体裁にして掲載するプラグインです。
OGPの取得を容易にするPHPライブラリ(opengraph.php)が提供されていて、これを利用すればPukiwikiにもブログカードを表示することができるようになります。使用するにはプラグイン本体(ogp.inc.php)のほかに、opengraph.phpをインストール(ダウンロードしてプラグインフォルダに設置)しておく必要があります。デフォルトのopengraph.phpはCookieを扱えず情報が取得できないことがあるので、当サイトでは一部改変したopengraph.phpを使っています。また、見栄えを良くするためのスタイルシートの改変も必要です。
使い方
- まず、opengraph.php を入手してpluginフォルダに設置します。
- ogp.inc.phpをpluginフォルダに設置します。
- cacheフォルダにogpのフォルダを作成し、書込み可能なパーミッションを与えます(666など)。
- スタイルシートは適宜調整して見栄えを良くします。参考までに、スタイルシートの一例も添付しています。
- #ogp(取得したいURL) を行頭に記載します。
- 第2引数以降にnoimgを入れることで画像を非表示にできます。(ver1.5以降)
更新履歴
ver1.0(2019.9.10)
ひとまずOGPを取得して表示する機能を実装しました。
現状ではPukiwikiにアクセスがあるたびに参照先サイトのOGPを取得しに行っている。アクセス数がそれほど多くない場合は負荷も無視できる程度であるが、もしアクセス数が非常に多いPukiwikiの場合はいちいち参照先にデータを取得しにゆくのは効率が悪い。何らかの方法でOGPデータや画像をキャッシュすることができればと思うが、現状では荷が重い(PHP技術的に)。
ver1.1(2019.9.17)
キャッシュ機能を実装しました。CACHE.DIRのogpというサブフォルダにキャッシュを配置します。またキャッシュ機能を実装したことでHTTPS外へのリンクを張った際に「安全でないサイト」と表示される問題も初回キャッシュ作成時以降は表示されなくなり、(ほぼ)解決しました。
しかし古いキャッシュを破棄する機能はまだ実装していません。また画像の拡張子を判断するステップを省略しているため、jpegもPNGも'.img'としています。主要ブラウザでは問題なく表示されるようですが、いずれ修正しなければならない。
また、URLを省略したOGPを提供するサイト(NCBI Pubmedなど)へのリンクを貼れるようにしました。
ver1.2(2019.11.10)
第2引数にampを入れることでimgタグをamp-imgに変更できるようにしました(ver1.5から再びAMP非対応になっています)。
AMP対応したサイトの場合はimgタグを使用することができません。そのためOGPプラグインが書き出すタグもimgではなくamp-imgタグを使用するようにしています。これにともなってスタイルシートも若干複雑になります。ver1.2対応のスタイルシートを使用してください。
ver1.3 (2020.5.2)
ファイル形式(GIF・PNGなど)を反映したキャッシュファイル拡張子になるようにしました。従来のキャッシュも利用できます。なお、ファイル形式を取得するためにgetimagesize()を使用しているため、PHPでGDがサポートされている必要があります。お使いのサーバーのPHPの設定をご確認ください。
ver1.31 (2020.5.5)
キャッシュ関連のバグを修正。
ver1.4 (2020.7.16)
画像が存在しない場合に画像を非表示(noimg)とするよう対応しました。こちらのサイトも参考にさせていただきました。ありがとうございました。画像がない場合や画像ファイルのサイズが'0'の場合はnoimgとなります。
ver1.5 (2020.7.24)
- WEBP画像があればWEBP画像を表示しなければfallbackするのに対応
- 複数の引数に対応(noimg,prefetch)
ver1.6 (2021.11.26)
- PHP 8.0でエラーが出ないよう微修正
- このバージョンからGitHubに公開しました。
- getimagesizeではなくexif_imagetypeを利用するようにしました。
ver1.7 (2023.1.13)
- 自己Pukiwiki内のOGPを取得しようとしたときにOGPプラグインでOGPを取得しようとしたページ同士で無限ループにならないように、User Agentでループ上のOGP取得防止を実装しました。仕組みは単純で、opengraphのUser Agentを指定し(ひとまず"Google Bot"にしています)、そのUser Agentでアクセスされた場合はOGP情報を取得しに行かないようにしている、つまりOGP情報の「孫参照」をしないようにしているということになります。
- 無駄な参照が減るので、動作は大幅に軽くなっていると思います。
- この機能を使用するためにはopengraph.phpもこれに対応したバージョンである必要があります。
- PHP 8.1での動作を確認
ver1.8 (2024.3.27)
グローバル変数でなくて良いのにグローバル変数を多用していた部分の適正化など、微修正を行いました。
サンプル
opengraph.phpの参考サイト
文字化け解消のために参考になったサイト
noimgの参考にさせていただいたサイト
今後の課題
faviconの問題
はてなブログのブログカードではURLの前に参照先サイトのfaviconを表示する機能がある。しかしopengraph.phpでは参照先サイトのfaviconを取得できない。opengraph.phpに依存しない方法でOGPを取得できれば、faviconの表示も可能になると思う。
OGPを提供していないURLを指定した場合に動作が非常に重くなる問題
追記:この問題はver 1.5でほぼ解決されました。
おそらくopengraph.phpが、参照先URLの存在しないOGPを探しに行ってその処理がtimeoutになるのを待っているのだと思われる。ogp.inc.phpを使用しているページ全体の動きが悪くなってしまうので、なんとかしたい。
HTTPSでないサイトへのブログカードを設置した場合に「安全ではない」となる問題
追記:この問題はver 1.1でほぼ解決されました。
SSL化(HTTPS化)しているサイトの場合は、サイト内でHTTPS化されていないURLへリンクを張ったりすると安全ではないというアラートが表示されてしまう。ブログカードでも同様で、HTTPS化されていないサイトへのリンクを張った場合には安全ではないというアラートが出てしまう。 →上記のとおり、キャッシュ機能を実装したver1.1でほぼ解決しました。
HTML5とCSS3の問題
現状ではCSS 2.1以上対応のスタイルシートでデザインを整えているが、HTML5とCSS3でレイアウトすればよりブラウザによる表示のばらつきは減らせそう。とくにCSS3のflexレイアウトができればスタイルシートはより簡単に置き換えられそう。
ファイル名にドットがあるとキャッシュが生成できない問題
追記:この問題はver 1.5でほぼ解決されました。
ファイル名に.(ドット)があるとキャッシュが再生できないようです。urlencodeしてみたりドットを%2Eにエンコードしてみたり色々と試してみてもダメなようです。ドットを含むファイル名に対してはfile()やfile_get_contents()が働かないのか…。
OGP画像がgzipやWebPの場合
一部のWordpress高速化プラグインなどではOGP画像ファイルが(見た目はjpg拡張子になっていても)中身が一部のブラウザにしか対応していないwebPファイルだったりgzip圧縮された画像ファイルになっている場合があります。この場合はキャッシュ画像が正しく表示できない問題があります。この問題はまだ解決していません。
当サイトでは、表示のおかしい箇所があった場合には当該ファイルをcache/ogpフォルダから探し出してローカルで手作業で普通のjpgファイルに変換し、同名のファイルとして同じフォルダに上書きするという力技でなんとか対処しています(スマートでない)。
OGPループの問題
追記:この問題はver 1.7でほぼ解決されました。(2023.1.13)
OGPプラグインに限りませんが、pukiwikiで他のページを読みにいくプラグインを使用する場合はループの問題に気をつけなければなりません。つまりページAのOGP情報を取得するプラグインを設置しているページBがあり、そのページAにページBのOGP情報を取得するプラグインを置いた場合などです。キャッシュが既にある場合は問題なく動作しますが、この状態でページAとページBのキャッシュを同時に削除すると、ページAとページBが同時に互いのページのOGP情報を取りに行こうとしてループが起こり、タイムアウトエラーとなります。
ver1.1以降の場合は、キャッシュがすでに生成されている場合はページBはページAに読み込みにゆかずにキャッシュを読むので、まずページBのキャッシュを生成させておいてからページAにページBへのリンクを書き込むという順序を追った作業で解決できます。すでにリンクが複雑に張り巡らされているpukiwikiでcache/ogpフォルダを空にするとこのループが発生することがあります。
旧版はこちら
OGP画像がog:imageではなくog:image:secure_urlで提供されるサイトへの対応
opengraph.phpでは取得できないクッキー必須サイトへの対応
この記事に対するコメント
このページには、まだコメントはありません。
添付ファイル: ogp.inc.php 698件 [詳細] ogp.1.3.1.inc.php 455件 [詳細] ogp.10.inc.php 540件 [詳細] ogp.css 845件 [詳細] ogp12.inc.php 486件 [詳細] opengraph.php 862件 [詳細] ogp11.css 468件 [詳細] ogp11.inc.php 561件 [詳細] ogp.1.5.inc.php 532件 [詳細]
更新日:2023-01-13 閲覧数:1715 views.