Wonderful! WordPress

get_children()で投稿にアップロードした画像を全て表示

投稿にはアップロードしたものの記事には挿入していない画像を、たとえば、単一記事テンプレート single.php 等で表示させたい場合など、それらの画像情報を取得するには・・・。

get_children() と wp_get_attachment_image_src()

get_children() を使ってその投稿にアップロードしてある全ての画像の情報を取得。
ループのなかで使用するときの一例。

<?php
$attachments = get_children( array( 'post_type'=>'attachment', 'post_mime_type'=>'image', 'post_parent'=>$post->ID, 'orderby'=>'menu_order' ) );

$capstr = array();

if ( ! empty( $attachments ) ) {
	foreach ( $attachments as $attachment ) {
		$image = wp_get_attachment_image_src( $attachment->ID, 'full' );
		$midimg = wp_get_attachment_image_src( $attachment->ID, 'medium' );
		echo "<a href=\" . $image[0] . "\"><img src=\"" . $midimg[0] . "\" width=\"500\" height=\"375\" class=\"aligncenter\" alt=\"*\" /></a>";

		if ( ! empty( $attachment->post_excerpt ) ) {
			echo "<p class=\"singlecaption\">" . $attachment->post_excerpt . "</p>";
			$capstr[] = $attachment->post_excerpt;
		}
	}
}

$tmpcont = get_the_content();
$tmpcont = ltrim( mb_substr( $tmpcont, mb_strrpos( $tmpcont, 'a>' ) + 2 ) );
$tmpcont = str_replace( '[/caption]', '', $tmpcont );
$tmpcont = str_replace( $capstr, '', $tmpcont );
$tmpcont = apply_filters( 'the_content', $tmpcont );
$tmpcont = str_replace( ']]>', ']]>', $tmpcont );

echo $tmpcont;
?>
PHP
CopyExpand

ちなみに、 wp_get_attachment_image_src() は配列にて返され、

  • [0]=>url
  • [1]=>width
  • [2]=>height

と、なっています。

$attachment->post_excerpt では、画像に設定した caption の文字列を取得することができます。ただ、通常の記事のなかで caption を表示する場合は、このサイトで実際に表示されている部分を見てみると、画像自体を'class="wp-caption aligncenter"'<div></div>の中に入れ、 caption の文字列も同じ div の中で、 'class="wp-caption-text"'<p></p>に入っています。

全く同じように再現する必要も無いようにに思いますので、ここはちょっと異なりますが独自の class を付けてスタイルを設定するようにしています。

19~26行目は画像を全て表示した後、記事の本文を表示しています。
記事の本文は get_the_content()関数 で得る事が出来、フィルターを通す必要があるので23、24行目はお決まりのパターンです。
20~22行目がこのサイト独自の本文を改良している処理になります。
20、21行目は記事の本文中に特定の画像だけ表示するようにしているので、それらの画像がダブって表示されないようにするための、画像以外の部分だけにする処理です。
ここの場合、いくつかの画像を表示するコードの後に、必要なら本文を入れているので画像に対するアンカータグの後の部分だけを取得しています。

wordpress のバージョン 3.4 から caption で指定した文字列も本文に表示されるようになってしまったようなので、 caption を一時的に入れておく配列 $capstr に14行目で取得し、22行目で本文から消しています。

・・・

2021/7/15 : 追記

ここからは、より速い処理をねらって、自サイトにおいて施しているもの。直にデータベースからデータを取得しているので、そのあたりの知識やら経験やらが無いなら、手を出すべき方法ではありません。念の為。

データベースから一括して情報を取得

アップロードされた画像は、投稿と同じように wp-posts テーブルにそれに関するデータが蓄えられています。post_type が、投稿であれば”post””page” などで、画像の場合はそれが”attachment” になります。
その画像レコードの post_parent の値が、親投稿レコードの ID の値と同じになっていて紐付けられているというわけです。
そして画像にキャプションがついている場合は、その画像レコードの post_excerpt のフィールドに、キャプションの文字列が入ってます。

で、画像に関してのデータは、wp-postmeta テーブルにもあって、このテーブルの画像に関するデータは、post_id がその画像レコードの ID と紐付けられています。そして meta_key フィールドの値が ”_wp_attachment_metadata” に、その画像のサムネイルの情報など含めてシリアライズされて保存されています。なのでそのデータを使うときにはデシリアライズして使うことになり、以下の如くになっています。

['width']1300
['height']750
['file']2016/04/1603120634_xwing.jpg
['sizes']['thumbnail']['file']1603120634_xwing-150x150.jpg
['sizes']['thumbnail']['width']150
['sizes']['thumbnail']['height']150
['sizes']['thumbnail']['mime-type']▸image/jpeg
['sizes']['medium']['file']1603120634_xwing-500x288.jpg
['sizes']['medium']['width']500
['sizes']['medium']['height']288
['sizes']['medium']['mime-type']▸image/jpeg
['sizes']['medium_large']['file']1603120634_xwing-768x443.jpg
['sizes']['medium_large']['width']768
['sizes']['medium_large']['height']443
['sizes']['medium_large']['mime-type']▸image/jpeg
['image_meta']['aperture']0
['image_meta']['credit']['image_meta']['camera']['image_meta']['caption']['image_meta']['created_timestamp']0
['image_meta']['copyright']['image_meta']['focal_length']0
['image_meta']['iso']0
['image_meta']['shutter_speed']0
['image_meta']['title']['image_meta']['orientation']0
PHP
CopyExpand

見ればわかるように、元ファイルからサムネイルまで必要な情報はキャプション文字列以外、全て揃っています。
と、いうことで、データベースから取得すればいいのは、この値と、あとは wp-posts テーブルにあるその画像のレコードが持っている post_excerpt の値ということになりますね。

それでは、さっそくその SQL をと。

<?php
$sql = <<< HERE
SELECT a.post_excerpt,b.meta_value FROM $wpdb->posts a,$wpdb->postmeta b
WHERE a.ID = b.post_id
AND a.post_type = 'attachment'
AND a.post_mime_type LIKE 'image/%'
AND a.post_parent = %d
AND b.meta_key = '_wp_attachment_metadata'
ORDER BY a.menu_order DESC
HERE;
				
	$attachments = $wpdb->get_results( $wpdb->prepare( $sql, $post->ID ) );
?>
PHP
CopyExpand

6行目の "a.post_mime_type" の行に関しては、取得する情報のメディアを画像ファイルに限定するもので、動画やら他のメディアをアップしていないのが確かであれば、この行は必要なし。指定する条件が少ないほうが処理はより高速になる。

そしてhtml 吐き出し部分は下に続く。
なお、下のコードは自サイトに使っているものから不必要な部分を削除して、それにともなって必要かと思われる部分を付け足したもので、実際に動かしてみたものではなく、もしかするとどこか問題があるかもしれないので、参考程度にしてくださいまし。

<?php
    $posttitle = $post->post_title;
    // 素のpost title は$post->post_title で取得できる。そして get_the_title() などの関数よりもたぶん高速

    foreach ( $attachments as $attachment ) {
        $attach_filename= '';
        $attach_excerpt = '';
        $midsize = array();

        $tmp_guid = ( array ) unserialize ( $attachment -> meta_value );
        $attach_filename = str_replace( array( '.JPG', '.jpg' ), '', $tmp_guid['file'] );

        $attach_excerpt = $attachment->post_excerpt;

        if ( isset ( $tmp_guid['image_meta']['title'] ) and $tmp_guid['image_meta']['title'] ) {
            $imgalt = $tmp_guid['image_meta']['title'];
        } else {
            $imgalt = $posttitle;
        }
        $midsize = array( $tmp_guid['sizes']['medium']['width'], $tmp_guid['sizes']['medium']['height'] );

        echo '<div><span data-img="' . $attach_filename . '.jpg" class="pimga"><img src="/wp-content/uploads/' . $attach_filename . '-' . $midsize[0] . 'x' . $midsize[1] . '.jpg" loading="lazy" width="' . $midsize[0] . '" height="' . $midsize[1] . '" class="aligncenter" alt="' . $imgalt . '" /></span>';

        if ( $attach_excerpt ) {
            echo '<p class="wp-caption-text">' . $attach_excerpt . '</p></div>';
        } else {
            echo '</div>';
        }
    }
?>
PHP
CopyExpand

以上です。では、では。

Leave a Reply!

JavaScript is necessary to send a comment.
You can edit and delete your comment if you input a edit key.
Edit key is necessary for attesting you when you edit and delete it.
The tag of HTML cannot be used in comment.
When you comment for the first time, it is displayed after the approval of the administrator.
Because I cannot speak English so much, it takes time to answer.
Required fields are marked *.

※Please enter more than 5 characters only alphabets.
※Edit or delete are possible for 2000 days after approval.

*

♠Simplistic Comment User Editable v4.0

♠When visitors leave comments on the site this site collect the data shown in the comments form, and also the visitor’s IP address and browser user agent string to help spam detection.
♠This site does not use cookie when visitors leave comments and commenter edit comment.
♠This site uses Akismet to reduce spam. Learn how your comment data is processed.

Comments feed

Trackback URL : https://strix.main.jp/wp-trackback.php?p=16291

Sanbanse Funabashi

Top

スクロールさせるか画像をクリックすると元に戻ります。