投稿内の最初の画像をアイキャッチにする
WordPressの記事一覧などで**『アイキャッチ画像が設定されていればそれを取得し、設定されていなければ投稿内の最初の画像を取得』**する方法は、調べればすぐ出てくる。
→ WordPressで記事内の最初の画像をアイキャッチ代わりに使う方法
function.php
function catch_that_image() {
global $post, $posts;
$first_img = '';
ob_start();
ob_end_clean();
$output = preg_match_all('//i', $post->post_content, $matches);
$first_img = $matches [1] [0];
if(empty($first_img)){ //Defines a default image
$first_img = "http://detarame.moo.jp/wp/wp-content/themes/whbk5/images/default.jpg";
}
return $first_img;
}
>
```php:example.php
<?php if (has_post_thumbnail()) : ?>
<?php the_post_thumbnail('thumbnail'); ?>
<?php else : ?>
<img src="<?php echo catch_that_image(); ?>" alt="<?php the_title(); ?>" />
<?php endif ; ?>
しかし、このやり方では投稿内の画像サイズの設定もそのまま反映されてしまうため、サイズ設定の指定や出し分けができない上に、レスポンシブにきちんと対応できないのが一番の難点。
「CSSでwidth
とheight
をパーセント指定にしたら?」と言われるかもしれないところだが、
自分のブログならそれでもいいが成果物としてクライアントに納品する場合、投稿内の画像のサイズ設定や元サイズなんて指定できないため、
幅が100~200px程度のアイコンのような画像が投稿内の最初の画像だった場合、width: 100%;
とかにしてると、画像が酷くぼやけて見えてしまう。
CSSでの表示はmax-width
の指定のみにとどめ、wp_get_attachment_image
を使ってサイズを指定し、さらにsrcset
とsizes
でデバイスごとに適切に表示画像を出し分けたい。
そのためには、
- 投稿内の画像から画像IDを取得
-
wp_get_attachment_image
で出力 -
srcset
とsizes
を指定する
という手順を踏んで出力する必要がある。
投稿内の画像からIDを取得
投稿ビジュアルエディタで、メディアライブラリから画像を挿入した場合、以下のコードになる。
<img class="wp-image-*** size-(画像サイズ)" src="(画像url)" alt="***" width="***" height="***" />
wp-image-***
というクラスが付与されるが、***部分がIDなので、それを引っ張ってくればよい。
preg_match_all( '/<img.+class=[\'"].*wp-image-([0-9]+).*[\'"].*>/i', $post->post_content, $matches );
これで、投稿内の画像IDを$matches
で取得できる。
srcset
とsizes
を指定
srcset
とsizes
は、WordPress4.0以降ならそれぞれwp_get_attachment_image_srcset
とwp_get_attachment_image_sizes
という関数が用意されているので、それを使う。
wp_get_attachment_image_srcset() | Function | WordPress Developer Resources
wp_get_attachment_image_sizes() | Function | WordPress Developer Resources
この関数、なぜか日本語の情報が異常に少なく(それどころか日本語記事だとsrcsetとsizesを削除する方法ばっかり出てくる)、日本語訳のリファレンスすらない。
投稿画像をテーマ内で呼び出してかつレスポンシブ対応させる場合は、ほとんど必須と言ってもいいと思うのだけど…
wp_get_attachment_image_srcset
とwp_get_attachment_image_sizes
どちらも( $attachment_id, $size, $image_meta )
の3つの引数を取る。
リファレンスによると以下の通り。
パラメータ | 説明 | 初期値 |
---|---|---|
$id |
画像のID | (なし) |
$size |
画像のサイズ。'medium' などの登録されている画像サイズ( add_image_size で追加したものも含む)か、幅と高さの数値の配列(単位はpxになる)のどちらか。 |
'medium' |
$image_meta |
wp_get_attachment_metadata() で返される画像のメタ情報。…らしい。 |
null |
基本的には、IDと画像サイズを指定すれば、それに対応したsrcset
(sizes
)の値を出力してくれる、という認識でよい。
$image_meta
が正直かなり謎で、コードを追う限り実際の返り値には一切影響していないように見えるため全く必要なさそうなんだが、一体何なんだろうか……今回のコードではnull
のままでも問題なく動作したので説明を省くことにする。
で、wp_get_attachment_image
なら属性値を好きに追加することができるので、
上記関数で取得した値をそれぞれ配列で指定してあげればOK。
実際に出力
function.phpに、下記を追記する。
// $get_size: 取得する画像のサイズ
// $altimg_id: 代替画像のID。(画像はあらかじめメディアライブラリからアップロードしておく)
// nullの場合、投稿内に画像が無ければ何も出力しない
function catch_thumbnail_image($get_size = 'thumbnail', $altimg_id = null) {
global $post;
$image = '';
$image_get = preg_match_all( '/<img.+class=[\'"].*wp-image-([0-9]+).*[\'"].*>/i', $post->post_content, $matches );
$image_id = $matches[1][0];
if( !$image_id && $altimg_id ){
$image_id = $altimg_id;
}
$image = wp_get_attachment_image( $image_id, $get_size, false, array(
'class' => 'thumbnail-image',
'srcset' => wp_get_attachment_image_srcset( $image_id, $get_size ),
'sizes' => wp_get_attachment_image_sizes( $image_id, $get_size )
) );
if( empty($image) ) {
$image = '';
}
return $image;
}
出力したい場所に以下のコードを挿入。
<?php
$catch_thumbnail_size = 'thumbnail';
if(has_post_thumbnail()){
the_post_thumbnail($catch_thumbnail_size);
} else {
echo catch_thumbnail_image($catch_thumbnail_size);
}
?>
これで、
- アイキャッチ画像が設定してある場合はそれを取得し出力
- アイキャッチは無いが投稿内に画像がある場合は、そのうちの1番最初の画像を取得し出力
- それも無い場合は代替画像を出力 or 何もしない
という動作を
- 投稿内画像のサイズ設定に影響されない
- 自由に出力サイズを指定
-
srcset
とsizes
も出力し、デバイスサイズに合わせた画像を表示させる
という条件で実現できる。