REST APIを使って外部サイトのアイキャッチ画像付き新着投稿一覧をショートコードで表示させる方法

公開日:2024(令和6)年4月8日/最終更新日:

WordPressのREST APIを使用してサイトをカスタマイズするための情報ページ

【景品表示法に基づく表記】ページ内のコンテンツには、商品プロモーションが含まれています



WordPressでいろいろな情報を取得できるREST API。外部サイトの新着情報を取得して表示する方法として一番簡単なのはRSSブロックを使用する方法ではあるものの、タイムラグがある、一定時間キャッシュされて更新されない、ブロックの設定に依存しているので当然ながら表示できる情報が限られているので、自由度は少ないと思います。

そこで今回は自身の勉強も兼ねて、REST APIを使って外部サイトから新着投稿の情報を取得して一覧表示する方法を紹介していきます。

なお、REST APIを使ったデータ取得の方法の基本や、単一の投稿をカード形式で表示する方法については以下のページを参照ください(本ページではこの辺りが理解されている前提で進めていきます)。

上記のページでは、目的のサイトの単一投稿の内容をカード表示させるという目的での手法を紹介していますが、REST APIを使って情報を取得して表示させるケースとしては、本ページのように一覧として表示させる方がメジャーな使い方かも知れませんね。

また、これから外部のサイトの情報を取得しようという主旨の内容には反しますが、これを読んで「REST APIって使う側はいいけど使われる側は恐ろしいかも」と感じる方は以下のページを参考に制限をされるといいと思います。

それでは始めましょう。

本ページで掲載しているコードは、以下に了承した上で使用ください

  • コードは商用・非商用問わず自由に使っていただいて構いませんが、コード追加による不具合やトラブルが発生しても当方では一切責任を負いません
  • コードは有効化しているテーマのfunctions.php、style.cssなどへ追加することで機能します。それらのファイルへの変更を行うことに不安のある方は使用しないでください
  • コードは本ページの公開日時点で私の環境において動作したものです。WordPressバージョン他環境の違いによって動作しないことがあります
  • コードは、セキュリティ、コードの正確さなどにおいて完全なものではありません。中には紹介するコードを簡略化するために省略している部分があるものもありますので、ご自身でコードを十分に検証し、必要な部分の編集を行った上で使用するようにしてください
  • 掲載しているのは参考コードです。自身の環境に合わせるための編集はご自身で対応いただく必要があります(コメント欄等から質問いただいても基本回答は致しません)
  • 掲載しているコードの転載を禁じます(SNSで紹介いただいたり、本ページへのリンクを張っていただくことは大歓迎です)

投稿一覧の表示サンプル

百聞は一見に如かずということで、以下が本ページの内容を参考に実装した場合の表示サンプルです。

見た目(スタイル)は適当に設定しているので調整する必要があります

QA Analytics QA Analytics

情報を取得して一覧表示させる手順

外部サイトの情報をREST APIを使って取得し、一覧表示させる

まあ、詳しい情報はいいから、とりあえず表示させてみたいという方が多いでしょうから、早速以下に情報を取得して一覧表示させるためのサンプルコードを紹介します。

言うまでもないと思いますが、有効化しているテーマのfunctions.phpへ追加して使用します

function pwcn_api_post_list_sc( $atts ){
/*** ショートコードパラメーターの設定 ***/
$atts = shortcode_atts(
	array(
		'home_url' => '',
		'posttype' => '',
		'num' => '',
		'cache-second' => '',
	),$atts);

//トップページのURL
	if(!empty($atts['home_url'])){
		$home_url = esc_url($atts['home_url']);
	}else{
		$home_url = '';
	}

//投稿タイプ
	if(!empty($atts['posttype'])){
		$posttype = esc_html($atts['posttype']);
	}else{
		$posttype = esc_html('posts');
	}

//表示数
	if(!empty($atts['num'])){
		$per_page = absint($atts['num']);
	}else{
		$per_page = absint('5');
	}

//キャッシュ時間
	if(!empty($atts['cache-second'])){
		$cache_second = absint($atts['cache-second']);
	}else{
		$cache_second = absint(60 * 60 * 24);
	}

//パラメーターの中に含まれがちな「/」を削除する
	$slug = rtrim(ltrim($posttype, '/'), '/');//前後の「/」を削除
	$home_url = rtrim($home_url, '/');//末尾の「/」を削除

/*** 投稿データの取得 ***/
//一応一日キャッシュを効かせるようにする
//apiを叩く
	$api_url = $home_url.'/wp-json/wp/v2/'.$posttype.'?per_page='.$per_page;

// データを取得する前に、キャッシュがあるかチェック
	$cached_data = get_transient( 'pwcn_api_post_list_cache' );

	if ( false === $cached_data || $atts['cache-second'] == '0') {
	// キャッシュがない場合、またはcache-secondパラメーダが0のときはAPIからデータを取得
		$response = wp_remote_get( $api_url );
	// 取得した情報を配列に格納
		$posts = json_decode( wp_remote_retrieve_body( $response ), true );

	// データをキャッシュする (デフォルトは一日)
		if($atts['cache-second'] == '0'){
			//cache-secondパラメーターが0だったらキャッシュを削除
			delete_transient( 'pwcn_api_post_list_cache' );
		}else{
			//cache-secondパラメーターが0以外か、未入力ならキャッシュを追加
			set_transient( 'pwcn_api_post_list_cache', $posts, $cache_second );
			
		}
	} else {
	//キャッシュがある場合はキャッシュを使用
		$posts = $cached_data;
	}

/*** リストを出力 ***/
//初期値を設定
	$html = '';

//前後のタグを設定
	$list_before ='<div class="pwcn_api_list">';
	$list_after = '</div>';

/* 取得した分の情報を回す */
if ( ! empty( $posts ) ) {
	foreach ( $posts as $post ) {
		/* 投稿の情報 */
			$output_title = $post['title']['rendered'];
			$output_excerpt = $post['excerpt']['rendered'];
			$output_link = $post['link'];

			//日付
			$api_pub_date = $post['date'];
			$formatted_pub_date = wp_date(
				get_option('date_format'),
				strtotime($api_pub_date)
			);

			$api_mod_date = $post['modified'];
			$formatted_mod_date = wp_date(
				get_option('date_format'),
				strtotime($api_mod_date)
			);

			//日付のHTMLを生成
			$date_html = '';
			$date_html .= '<p class="pwcn-list-date">';
			$date_html .= '<span>公開日:'.$formatted_pub_date.'</span>';
			$date_html .= '<span>&nbsp;/&nbsp;</span>';
			$date_html .= '<span>更新日:'.$formatted_mod_date.'</span>';
			$date_html .= '</p>';


		/* アイキャッチ画像 */
		/* 投稿の情報にある画像のIDを画像のapiに渡して情報を取得 */
		//投稿のアイキャッチ画像のIDを取得
			$featured_media_id = $post['featured_media'];
		// アイキャッチ画像のURLを取得
			$image_url = '';

		//アイキャッチ画像のIDがあれば画像情報を取得
		if(isset($featured_media_id)){
			//キャッシュデータの確認
			$cached_data = get_transient( 'pwcn_api_post_list_image_cache' );

			//キャッシュがあるか、パラメーターの値が0かで判断
			if ( false === $cached_data || $atts['cache-second'] == '0') {
				$media_response = wp_remote_get(
					$home_url.'/wp-json/wp/v2/media/'.$featured_media_id
				);
				$media_data = json_decode(
					wp_remote_retrieve_body( $media_response ), true
				);

					if($atts['cache-second'] == '0'){
					//cache-secondパラメーターが0だったらキャッシュを削除
					delete_transient( 'pwcn_api_post_list_image_cache' );
					}else{
					//cache-secondパラメーターが0以外か、未入力ならキャッシュを追加
					set_transient(
						'pwcn_api_post_list_image_cache',
						$media_data,
						$cache_second
					);
					}
			}else{
			//キャッシュがあればそれを返す
				$media_data = $cached_data;
			}

			//"medium"サイズの情報を取得
				$medium_size_info = $media_data['media_details']['sizes']['medium'];

			//"medium"サイズのURLと幅・高さを取得
				$medium_size_url = $medium_size_info['source_url'];
				$medium_size_width = $medium_size_info['width'];
				$medium_size_height = $medium_size_info['height'];

			//アイキャッチ画像のHTMLを生成
				$image_data = '<img src="'.$medium_size_url.'" width="'.$medium_size_width.'" height="'.$medium_size_height.'"   alt="REST APIを使って外部サイトのアイキャッチ画像付き新着投稿一覧をショートコードで表示させる方法|Personal WP Customization Notes (PWCN)">';
		}

		//出力する情報をまとめる
		$html .= '<a href="'.$output_link.'" target="_blank">';
		$html .= '<div class="pwcn_list_inner">';
		$html .= '<div class="pwcn_list_fimage">';
		$html .= $image_data;
		$html .= '</div>';
		$html .= '<div class="pwcn_list_content">';
		$html .= '<h3>' . $output_title . '</h3>';
		$html .= $date_html;
		$html .= '<p>' . $output_excerpt . '</p>';
		$html .= '</div>';
		$html .= '</div></a>';
	}
}

/*** HTMLとして出力 ***/
	return $list_before.$html.$list_after;
}
add_shortcode('pwcn-rest-post-list','pwcn_api_post_list_sc');

コードを追加したら、以下のショートコードを任意の場所へ挿入します。

[pwcn-rest-post-list home_url="" posttype="" num="" cache-second=""]

一応、ショートコード内で各種の指定ができるようにしていますので、以下のようにして設定します。

パラメーター設定未指定の場合
home_url目的のサイトのURLを入力します
posttype目的の投稿タイプのスラグを入力します
※よく分からない場合には空のままにします
posts
num表示数を数字で指定します5(件)
cache-secondキャッシュ時間を秒単位で指定します86400(1日)

目的のサイトでREST APIへの接続制限がされているサイトでは情報取得できず何も表示されません(ちなみに当サイトでは制限をしていますので当サイトのURLで試しても何も表示されません)

即時レスポンスにするとサーバーに負荷がかかったり、表示時間がかかったりすることから、キャッシュ(情報の一時保管)をするようにしています。
これにより、各種パラメーターの値を変更しても即時反映されませんので、即時に切り替えたい時は「cache-second」パラメーターを「0」(ゼロ)に設定して保存しなおしてください

ここではひとまずコードの詳しい解説割愛して、スタイルコードの例を先に紹介します。詳細を知りたい方は、後述する「ショートコードプログラムの内容」をご覧ください。

スタイルを調整する

表示された一覧をいい感じ?に表示させるためのスタイルコード例です。本サイト、かつパソコン画面でそれなりに表示されるようにしたサンプルなので、出力されるタグのクラスを追加したりするなど、サイトに合わせてご自身で調整してください。

.pwcn_api_list a {
    text-decoration: none;
}

.pwcn_list_inner {
    display: flex;
    gap: 8px;
    padding: 8px;
    border: 1px solid #eee;
    margin: 10px 0px;
}

.pwcn_list_content h3 {
    font-size: var(--wp--preset--font-size--large);
    font-weight: bold;
    margin: 8px 0px;
}

p.pwcn-list-date {
    font-size: var(--wp--preset--font-size--small);
    text-align: right;
}

.pwcn_list_fimage img {
    width: 180px;
    height: auto;
    max-height:120px;
    object-fit:cover;
    margin-top: 1rem;
}

ショートコードプログラムの内容

最後に、今回紹介した長いショートコードプログラムの大まかな流れについて触れておきます。

  1. パラメーター付きショートコードを機能させるプログラムを作成
  2. URL、件数等に応じて、REST APIを使って情報を取得(キャッシュの処理含む)
  3. 2の情報から、「タイトル」「公開日」「更新日」「抜粋」「アイキャッチ画像のID」を取得
  4. 3のアイキャッチ画像のIDから、再度REST APIを使って画像情報を取得(キャッシュの処理含む)
  5. 3~4の内容をforeachで回して、件数分だけ情報をまとめる
  6. まとまった情報を出力する

ざっとこんな感じの仕様になっています。

コード中に目いっぱいコメントを入れていますので、各処理の内容や流れは分かると思います。



Lolipop ServerMoshimo Ad x-serverMoshimo Ad

WordPressのREST APIを使用してサイトをカスタマイズするための情報ページ
REST APIを使って単一の投稿からデータを引き出して表示する方法