背景
WordPressで一般的にサムネイル(アイキャッチ)を表示する場合はメディアライブラリを利用します。
しかしながらメディアライブラリには通常の利用では表面化しませんが様々な制約が存在します。
メディアライブラリの制約
メディアライブラリには以下の制約が存在します。
- WordPressが稼働するサーバに画像ファイルをアップロードする必要がある。
- (標準設定)自動で3種類のサムネイルファイルが自動生成される。
- 画像1ファイルにつきwp_postsに1レコード作成される。
- 記事にサムネイルを設定するとwp_postmetaに1レコード作成される。
それぞれ詳細に見ていきましょう。
1.WordPressが稼働するサーバにファイルをアップロードする必要がある。
通常の利用方法であればメディアライブラリ機能で画像ファイルをアップロードします。サーバ負荷の低減や可用性向上のため異なるストレージに画像ファイルを配置することはできません。
AutoPostThumbnail等の自動でメディアライブラリに画像を設定するプラグインも存在しますがアップロード作業を自動化しているだけで画像ファイルの配置については変わりません。
2.(標準設定)自動で3種類のサムネイルファイルが自動生成される。
標準設定では3種類のサムネイルが自動で生成されます。オリジナルサイズと合わせて4種類のサイズを使い分けるのであれば問題ありませんが利用しないサイズのファイルは無駄になります。
3.画像1ファイルにつきwp_postsに1レコード作成される。
記事を投稿するとwp_postsに1レコード作成されますがメディアライブラリもこのテーブルで画像を管理してます。全記事にサムネイル画像を設定する場合はレコード数が記事数の2倍になります。
4.記事にサムネイルを設定するとwp_postmetaに1レコード作成される。
記事にサムネイルを設定すると記事とサムネイルの関連付けの為にwp_postmetaに1レコード作成されます。ただでさえwp_postmetaには多くのレコードが登録されますがさらに上乗せされます。
結局何が問題なの?
1日に1記事投稿するような一般な利用方法では問題ありません。しかしながらWEBをスクレイピングしてゴニョゴニョして鬼のように大量の記事を生成する場合は塵も積もって死活問題になります。
Herokuを無料プランで使う場合もリソースは節約したいですよね。
CloudFrontのように所定のストーレジにファイルを配置するCDNも存在します。
どうすればいいの?
フィルターフックを使ってWordPressに対してあたかもメディアライブラリが設定されているかのように振る舞います。ある意味WordPressを騙します。
1.get_post_metadata
get_post_metadataは指定のmeta_keyに対するpostmeta_idを返却する関数です。通常であればサムネイルを設定していないので0(またはnull)が返却されますが1以上の数値を返却することによってWordPressにサムネイルが設定されていると認識させます。
ここでは例としてpost_idを返却しています。
singleは呼び出し元で制御していたので無視して大丈夫です。
add_filter('get_post_metadata', 'my_get_post_metadata', 10, 4);
function my_get_post_metadata($postmeta_id, $post_id, $meta_key, $single) {
if ($meta_key == '_thumbnail_id') {
return $post_id;
}
return $postmeta_id;
}
2.image_downsize
image_downsizeは画像ファイルのURLとsizeに対する幅と高さを返却する関数です。通常であればサムネイルを設定していないので呼ばれることはありません。
前述のget_post_metadataで返却したpostmeta_idが使われます。例ではpost_idを設定したのでpost_idを条件に画像ファイルのURL、画像の幅、高さ、リサイズしているかを返却するようにします。
ここでは例として条件分岐せず固定の値を返却しています。
add_filter('image_downsize', 'my_image_downsize', 99, 3);
function my_image_downsize($out, $postmeta_id, $size) {
$out = array();
$out[] = 'http://exsample.com/hoge.jpg';
$out[] = 100;
$out[] = 200;
$out[] = false;
return $out;
}
この手法の良いところ
the_post_thumbnail等の標準のテンプレートタグがそのまま使えます。これが最大のメリットです。公開されているテンプレートやプラグインは標準のテンプレートタグを使うことが多いのでそのまま変更せずに使うことができます。
標準のテンプレートタグを使わない場合はこのような回りくどいことをせずにそのまま画像URLを記述する方が簡単です。
免責
WordPressバージョン4.7系でテストしましたがすべての機能で正常に動作することまでは確認していません。
問題が発生した場合に自力で解決できる方以外はスルーされることをお勧めします。