「同じカテゴリの人気記事一覧」ウィジェットを自作する

同じカテゴリの人気記事一覧ウィジェット解説ページのアイキャッチ

このページでは「同じカテゴリの人気記事一覧ウィジェット」のサンプルプログラムの紹介と、作り方の解説を行います。

このウィジェットを利用することにより、表示中の投稿記事と同じカテゴリの人気記事の一覧をサイドバー等に表示できるようになります。

同じカテゴリの人気記事一覧の例

「同じカテゴリの人気記事一覧ウィジェット」作成プログラム

最初に「同じカテゴリの人気記事一覧ウィジェット」を作成するサンプルプログラムを載せておきます。

変更するファイルは2つです。

  • functions.php
  • style.css

特に functions.php はプログラム記述を失敗するとページが表示されなくなる可能性がありますので、必ずバックアップをとってから変更してください。

functions.php の変更

functions.php に下記を追記します。これだけで(まだ見た目は悪いですが)ウィジェットは作成できます。

functions.php
<?php
/**
 * アイキャッチを有効化
 * 新しいリサイズサイズを追加
 */
function my_enable_popular_thumbnail() {
	add_theme_support( 'post-thumbnails' );

	/* リサイズ時に 100 x 100 pxのサムネを作成するように設定 */
	add_image_size( 'popular-thumb', 100, 100, true );
}

add_action( 'after_setup_theme', 'my_enable_popular_thumbnail' );

/**
 * ページビュー数をカウントアップする関数
 */
function my_view_count_func() {
	/* この投稿記事の投稿 ID を取得 */
	$post_id = get_the_ID();

	/* 投稿記事以外はカウントしない */
	if ( ! is_single( $post_id ) ) {
		return;
	}

	/* ページビュー数を表すメタデータを追加 */
	if ( ! add_post_meta( $post_id, '_my_view_count', '1', true ) ) {
		/* 既にページビュー数を表すメタデータが追加されている場合 */

		/* まずはこの投稿記事のページビュー数を取得 */
		$view_count = get_post_meta( $post_id, '_my_view_count', true );
		/* ページビュー数を+1してメタデータを更新 */
		update_post_meta( $post_id, '_my_view_count', $view_count + 1 );
	}

}

add_action( 'wp_head', 'my_view_count_func' );

/**
 * Adds CategoryPopular_Widget widget.
 */
class MyCategoryPopular_Widget extends WP_Widget {

	/**
	 * ウィジェットの実体を作成
	 */
	public function __construct() {
		parent::__construct(
			'my_category_popular_widget',
			'カテゴリの人気記事'
		);
	}

	/**
	 * ウィジェットのフロントエンド表示
	 *
	 * @see WP_Widget::widget()
	 *
	 * @param array $args     ウィジェットの引数.
	 * @param array $instance データベースに保存されている設定値.
	 */
	public function widget( $args, $instance ) {

		/* 投稿記事以外は表示しない */
		if ( ! is_single( get_the_ID() ) ) {
			return;
		}
		/* ここからregister_sidebarに入力されたHTMLを出力 */

		/* before_widgetを出力 */
		echo $args['before_widget'];

		/* before_titleとafter_titleを出力 */
		if ( ! empty( $instance['title'] ) ) {
			/* タイトルが設定されている場合のみ出力 */
			echo $args['before_title'] . apply_filters( 'widget_title', $instance['title'] ) . $args['after_title'];
		}

		/* ここから記事一覧の表示 */
		$category = get_the_category( get_the_ID() );

		/* サブクエリの条件を作成 */
		$sub_args = array(
			/* カテゴリを現在表示している投稿記事のものに絞る */
			'category_name'  => $category[0]->category_nicename,
			/* 投稿記事を_my_view_countをキーとするメタデータの数に対して降順に整列 */
			'meta_key'       => '_my_view_count',
			'orderby'        => 'meta_value_num',
			'order'          => 'DESC',
			/* 整列後の投稿記事のデータを設定された表示数分取得 */
			'posts_per_page' => $instance['num'],
		);

		/* サブクエリを発行してデータベースからデータ取得 */
		$my_query = new WP_Query( $sub_args );

		/* 取得した投稿データをサブループで表示 */
		while ( $my_query->have_posts() ) {
			$my_query->the_post();

			$post_id = get_the_ID();
			/* サムネを表示するHTMLを取得 */
			$image = get_the_post_thumbnail( $post_id, 'popular-thumb' );
			/* タイトル取得 */
			$title = get_the_title( $post_id );
			/* リンク取得 */
			$link = get_the_permalink( $post_id );
			/* ページビュー数取得 */
			$view_count = get_post_meta( $post_id, '_my_view_count', true );

			/* 取得した情報を出力 */
			$output = '';
			$output = $output . '<a href="' . $link . '" class="my-card-link">';
			$output = $output . '<div class="my-card">';
			$output = $output . $image;
			$output = $output . '<div class="my-card-content">';
			$output = $output . '<div class="my-card-title">';
			$output = $output . $title;
			$output = $output . '</div>';
			$output = $output . '<div class="my-card-count">';
			$output = $output . $view_count . ' views';
			$output = $output . '</div>';
			$output = $output . '</div>';
			$output = $output . '</div>';
			$output = $output . '</a>';

			echo $output;
		}

		wp_reset_postdata();

		/* 最後にafter_widgetを出力 */
		echo $args['after_widget'];
	}

	/**
	 * ウィジェットの設定フォームを表示する関数
	 *
	 * @param array $instance : 元々の設定を持つインスタンス.
	 */
	public function form( $instance ) {
		/* 設定値が設定されていない時のデフォルト値設定 */
		if ( ! empty( $instance['title'] ) ) {
			$title = $instance['title'];
		} else {
			$title = '同じカテゴリの人気記事';
		}

		if ( ! empty( $instance['num'] ) ) {
			$num = $instance['num'];
		} else {
			$num = '5';
		}
		?>
		<!-- ウィジェットのタイトル設定フォームを表示 -->
		<p>
		<label for="<?php echo $this->get_field_id( 'title' ); ?>"><?php _e( 'タイトル:' ); ?></label>
		<input class="widefat" id="<?php echo $this->get_field_id( 'title' ); ?>" name="<?php echo $this->get_field_name( 'title' ); ?>" type="text" value="<?php echo esc_attr( $title ); ?>">
		</p>

		<!-- ウィジェットの表示記事数設定フォームを表示 -->
		<p>
		<label for="<?php echo $this->get_field_id( 'num' ); ?>"><?php _e( '表示数:' ); ?></label>
		<input class="widefat" id="<?php echo $this->get_field_id( 'num' ); ?>" name="<?php echo $this->get_field_name( 'num' ); ?>" type="text" value="<?php echo esc_attr( $num ); ?>">
		</p>
		<?php
	}

	/**
	 * ウィジェットの設定を更新する関数
	 *
	 * @param array $new_instance : 新しい設定を持つインスタンス.
	 * @param array $old_instance : 今までの設定を持つインスタンス.
	 */
	public function update( $new_instance, $old_instance ) {
		/* サニタイズ後の設定値を格納するための$instanceを作成 */
		$instance = array();

		/*
		 * instance['title']:タイトル
		 * instance['num']:表示数
		 */

		/* タイトルのサニタイズ */
		if ( ! empty( $new_instance['title'] ) ) {
			/*
				フォームに設定された文字列が空でない場合は
				wp_strip_all_tagsを実行後の文字列をタイトルの設定値に設定
			*/
			$instance['title'] = wp_strip_all_tags( $new_instance['title'] );
		} else {
			/* 空の場合は「新しいタイトル」をタイトルに設定 */
			$instance['title'] = '新しいタイトル';
		}

		/* 表示数のサニタイズ */
		if ( ! empty( $new_instance['num'] ) ) {
			/* フォームに設定された文字列が空でない場合 */
			if ( intval( wp_strip_all_tags( $new_instance['num'] ) ) > 0 ) {
				/* 文字列をint化した数値が0より大きい場合のみ、その文字列を表示数として設定 */
				$instance['num'] = wp_strip_all_tags( $new_instance['num'] );
			} else {
				/* 0より小さい場合はデフォルト値5を設定 */
				$instance['num'] = '5';
			}
		} else {
			/* フォームに設定された文字列が空の場合はデフォルトの5を設定 */
			$instance['num'] = '5';
		}

		return $instance;
	}
}

/**
 * 作成したウィジェットサブクラスを登録
 */
function my_register_category_popular_widgets() {
	register_widget( 'MyCategoryPopular_Widget' );
}

/* widgets_init に作成したウィジェットを登録する関数をフック */
add_action( 'widgets_init', 'my_register_category_popular_widgets' );
?>

style.css の変更

style.css に下記を追記します。これでウィジェットの見た目が整います。

style.css
.my-card {
    display: flex;
    align-items: center;
    box-shadow: 0 0 5px #888888;
    margin: 10px;
    padding: 10px;
    max-width: 90%;
    overflow: hidden;
    background-color: #fafafa;
}

a.my-card-link {
	text-decoration: none;
	color: #222222;
}

.my-card-title {
	font-size: 1.0em;
    margin-left: 20px;
}

.my-card-count {
    font-size: 0.8em;
    color: #ff8888;
    margin-left: 20px;
}

動作確認

最後にウィジェットを表示してみましょう。

ダッシュボードで「外観」→「ウィジェット」をクリックしてウィジェット設定画面に移ります。

左側にウィジェット一覧が表示されており、その中に「カテゴリの人気記事」というウィジェットが追加されているはずです。

これをウィジェットエリア(図ではサイドバーウィジェット)にドラッグ&ドロップします。

ウィジェットの設定れい

この後に適当な投稿記事のページを表示すると、ウィジェットエリアに下の図のような「同じカテゴリの人気記事一覧」が表示されるはずです。

同じカテゴリの人気記事ウィジェットの表示例

これが追加した「同じカテゴリの人気記事一覧」となります。

ウィジェット設定画面から、表示数とタイトルを設定できるようにしています。

同じカテゴリの人気記事ウィジェットの設定画面

注意点

ダッシュボードの「外観」に「ウィジェット」が表示されないという方は、下のページを参考にして、まずはテーマにウィジェットエリアの追加を行ってみてください。

ワードプレステーマの作り方⑤のアイキャッチ【ワードプレス】テーマの作り方⑤:ページにウィジェットを表示する

またサムネは投稿編集画面で登録したアイキャッチ画像に基づいて作成されます。投稿編集画面でアイキャッチ画像が登録できないという方は、まずは下のページを参考にして登録アイキャッチ画像の有効化(サポート)を行ってみてください。

アイキャッチ表示解説ページのアイキャッチ【ワードプレス】テーマの作り方⑨:アイキャッチ画像を表示する

サムネ画像が正方形にならないという場合は、まだ 100 x 100 px のサムネが作成されていないためだと思います。

上記プログラムを functions.php に追記&保存後、アイキャッチ画像を再度登録し直す(ファイル名を変更しておくと無難)と、強制的にサムネ作成が行われ、正常にサムネが表示されるようになるはずです。

「同じカテゴリの人気記事一覧ウィジェット」を作成する手順

この「同じカテゴリの人気記事一覧ウィジェット」を作成するために、下記のことを行っています。

  • ページビュー数をカウントする
  • 記事一覧に表示するサムネを作成する
  • ウィジェットを作成する
    • カウントしたページビュー数を利用してサブクエリを発行する
    • サブクエリ発行で取得した投稿データの情報とサムネイルを表示する
  • ウィジェットのスタイルを設定する

一つ一つに対して簡単に解説していきます。

スポンサーリンク

ページビュー数をカウントする

「カテゴリ人気記事一覧」は、カテゴリ内のページビュー数の多いページの一覧を表示するウィジェットですので、まずはそのページビュー数をカウントするようにしてやる必要があります。

ページビュー数のカウントアップ

このページビュー数はメタデータとしてデータベースに保存し、ページが閲覧されるたびに数字を1増やす形でカウントしています。

このページビュー数をカウントしているのは、プログラム内の my_view_count_func 関数です。さらに、この my_view_count_func を wp_head フックにフックすることで、ヘッダーが表示される際に my_view_count_func が実行され、ページビュー数がカウントされるようにしています。

メタデータについてや、ページビュー数をメタデータとして追加・更新・利用する方法やプログラムについては下記ページで解説していますので、こちらも合わせて読んでみてください。

メタデータ解説ページのアイキャッチメタデータとは?メタデータについて初心者向けにわかりやすく解説!

記事一覧に表示するサムネを作成する

「カテゴリ人気記事一覧」には投稿記事のタイトルとページビュー数に合わせて、その投稿記事に設定されたアイキャッチのサムネイルを表示したかったため、このサムネの作成も行うようにしています。

表示するサムネ

プログラム中でこのサムネ作成の設定を行っているのは my_enable_popular_thumbnail 関数です。100 x 100 px のサムネイル画像を作成するようにしています。

この my_enable_popular_thumbnail 関数を after_setup_theme にフックすることで、アイキャッチ画像のリサイズが行われる際に 100 x 100 px のサムネイル画像も同時に作成されるようになります。

アイキャッチ画像の設定については下記ページで、

アイキャッチ表示解説ページのアイキャッチ【ワードプレス】テーマの作り方⑨:アイキャッチ画像を表示する

サムネイルのリサイズについては下記ページで解説していますので、my_enable_popular_thumbnail で何をやっているかわからない場合は合わせて読んでみてください。

アイキャッチ画像表示の仕組みを解説するページのアイキャッチワードプレスのアイキャッチ画像表示・リサイズの仕組みを解説

ウィジェットを作成する

続いて「カテゴリ人気記事一覧」の本体となるウィジェットを作成します。

同じカテゴリの人気記事ウィジェットの表示例

ウィジェットは WP_Widget のサブクラスを実装することで作成することができます。

Wp_Widget のサブクラスは下記のように extends を用いて記述することで実装することができます。

class サブクラス名 extends WP_Widget

上記プログラムでは MyCategoryPopular_Widget という名前でサブクラスを作成しています。

各メソッドの役割等に関しては下記のウィジェット作成の解説ページをご覧いただければと思います。

ワードプレステーマの作り方⑥のアイキャッチ【ワードプレス】テーマの作り方⑥:ウィジェットを自作する

MyCategoryPopular_Widget は widget メソッド、form メソッド、update メソッドでそれぞれ下記が行えるように作成しています。

  • widget:投稿記事のサムネ・タイトル・ページビュー数を、ページビュー数順に設定された表示数分出力
  • form:タイトルと表示数の設定画面表示
  • update:タイトルと表示数の設定のアップデート(サニタイズ含む)

カウントしたページビュー数を利用してサブクエリを発行する

widget メソッドで行っていることをもう少し詳細に解説しておきます。

このメソッドでは、サブクエリを発行して投稿記事データを取得しています。

そのサブクエリは下記のようなものになります。コメントで詳細を記述していますので、コメントを読んでいただければどのようなクエリであるかは分かっていただけると思います。

/* サブクエリの条件を作成 */
$sub_args = array(
	/* カテゴリを現在表示している投稿記事のものに絞る */
	'category_name'  => $category[0]->category_nicename,
	/* 投稿記事を_my_view_countをキーとするメタデータの数に対して降順に整列 */
	'meta_key'       => '_my_view_count',
	'orderby'        => 'meta_value_num',
	'order'          => 'DESC',
	/* 整列後の投稿記事のデータを設定された表示数分取得 */
	'posts_per_page' => $instance['num'],
);

さらに下記でサブクエリを発行し投稿記事のデータ取得しています。

/* サブクエリを発行してデータベースからデータ取得 */
$my_query = new WP_Query( $sub_args );

これにより投稿記事のデータは「表示している投稿記事と同じカテゴリ」のものが「ページビュー数」が多い記事が設定された表示数分取得されます。

なので、下記のようにサブループ(have_posts・the_post ループ)を形成し、このサブループの中で投稿記事のデータを順次取得し、HTML として出力してやれば、「表示している投稿記事と同じカテゴリ」のものが「ページビュー数」が多い記事が設定された表示数分の情報を表示することができます。

/* 取得した投稿データをサブループで表示 */
while ( $my_query->have_posts() ){
	$my_query->the_post();
	/* 〜略〜 */
}

wp_reset_postdata();

サブクエリに関しては下記ページで解説していますので、詳しく知りたい方はこちらも参考にしてください。

クエリー解説ページのアイキャッチワードプレスのクエリとは?メインクエリとサブクエリの違いは?

サブクエリ発行で取得した投稿データの情報とサムネイルを表示する

サブループの中では各投稿記事のデータの「タイトル(リンク付き)」「サムネ」「ページビュー数」を出力しています。

これらの情報は下記で取得しています。

$post_id = get_the_ID();
/* サムネを表示するHTMLを取得 */
$image = get_the_post_thumbnail( $post_id, 'popular-thumb' );
/* タイトル取得 */
$title = get_the_title( $post_id );
/* リンク取得 */
$link = get_the_permalink( $post_id );
/* ページビュー数取得 */
$view_count = get_post_meta( $post_id, '_my_view_count', true );

あとはこれらの情報を HTML として出力しているだけです。

この辺りは下記ページに載せている「サムネ付き関連記事カード」とほぼ同じ作りにしていますので必要に応じてこちらも参考にしてください。

サムネ付き関連記事カード自作方法解説ページのアイキャッチワードプレスで「サムネ付き関連記事カード」を自作する

スポンサーリンク

ウィジェットのスタイルを設定する

最後にウィジェットのスタイルを設定して仕上げです。

何をしているかは style.css に全て載せていますので、ここでの詳細説明は省略します。

こちらも「サムネ付き関連記事カード」とほぼ同じ設定にしていますので、詳しく知りたい方は下記を参考にしてください。

サムネ付き関連記事カード自作方法解説ページのアイキャッチワードプレスで「サムネ付き関連記事カード」を自作する

まとめ

このページでは「同じカテゴリの人気記事一覧」を表示するウィジェットを自作する方法について解説しました。

サンプルプログラムはおそらくコピペするだけで使用することができます。

特に style.css についてはご自身の好みに合わせて変更して使用していただければと思います。

解説に関してはかなり簡単に済ましてしまいましたが、コメント等いただければ不明点や疑問点にお応えできますので、気軽にコメントしていただければと思います!

この「同じカテゴリの人気記事一覧」の表示と同じような方法+カスタムフィールドを利用して「オススメ投稿記事一覧」なども表示することが可能です。下記ページで紹介していますので、コチラも是非読んでみてください。

オススメ投稿記事一覧表示の解説ページのアイキャッチカスタムフィールドを利用して「オススメ投稿記事一覧」を表示する

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

ワードプレスの処理時間は約 0.193 秒です