WordPressの投稿ページの「最近の投稿」に同じカテゴリのものだけを表示

前回に引き続き、見に来た人が興味のない別のコンテンツが「最近の投稿」に表示されないようにする方法の模索です。ググっても出てきません。分析していきます。成功すればが出れば最初の方に結論を書きます。テーマ=lightning用のものです。

結論:テーマのlightningのPHPコードsidebar-contents-post.phpを修正する

まずは過程なんてどうでもいい人のために簡潔に結論を書く。
lightningで1投稿ページのサイドバーの「最近の投稿」にその投稿記事と同じカテゴリのものだけを表示する方法はこれだ。ちなみに、カテゴリートップページのサイドバーも同じカテゴリーのものだけになる。

ファイルは
/opt/bitnami/wordpress/wp-content/themes/lightning/_g3/template-parts/sidebar-contents-post.php

表示している記事と同じカテゴリーに絞るコードの修正

/same categoryのため新規変数を追加する
$cats   = get_the_category(); //categoryは配列で入る
$cat_id = $cats[0]->term_id;  //一つ目のcategory ID

//test
//echo $cat_id; echo ':';echo($cats[0]->name);echo '</p>';
//var_dump($cats[0]);echo '</p>';
//var_dump(get_the_category()[0]);echo '</p>';//続けてかいてもよし

$post_loop = new WP_Query(
	array(
		'post_type'              => 'post',
	        'cat'                    => $cat_id,//add for restruct same category
		'posts_per_page'         => 10,
		'no_found_rows'          => true,
		'update_post_meta_cache' => false,
		'update_post_term_cache' => false,
	)
);
?>

ピンク蛍光ラインを引いたところを追記します。

  1. 表示している記事のカテゴリーを取得します。カテゴリーは複数あるのですが、
  2. 今回は1つ目のカテゴリーのみ$cats[0]のidを取得します。
  3. ループする条件のところにカテゴリーの指定'cat'を追加してそれに先程取得したカテゴリーのidをセットします。

下の方に「最近の投稿」を「[カテゴリー名]のカテゴリーの最近の投稿」と書き換えるやり方も書いてあるので最後まで見てください。

初動:前回の記事で得た情報からlightning/__g3当たりを探ってみる。

このファイルが怪しい。
/opt/bitnami/wordpress/wp-content/themes/lightning/_g3/template-parts/sidebar-contents-post.php
ファイル名からは「投稿時のサイドバーの内容」と読み取れる。
これが入り口ですね。

 * 投稿タイプ post 用のサイドバーです。
 * しかし、サイトバーウィジェットエリア(投稿)にウィジェットかブロックが配置されている場合、
 * このファイルは読み込まれなくなります。

上記コメントが冒頭にありまして、なるほどまず、ブラウザでのlightningの設定でなんとかならないかなと探していたらあったサイドバーウィジェットの話です。使い方がさっぱりわかりませんでした。指定したらここの処理は無効となるようです。

$post_loop = new WP_Query(
	array(
		'post_type'              => 'post',
		'posts_per_page'         => 10,
		'no_found_rows'          => true,
		'update_post_meta_cache' => false,
		'update_post_term_cache' => false,
	)
);
?>

この辺は設定ですね。whileの引数に渡っているのでwhileの条件なんでしょうね。10記事分表示すると、少なくしたいときはここの数を修正するんですね。試しにここの数を5に変更して記事を読み込み直したら反映されてました。ここが入り口に間違いない。

その次は…

<?php if ( $post_loop->have_posts() ) : ?>
<aside class="widget widget_media">
<h4 class="sub-section-title"><?php echo __( 'Recent posts', 'lightning' ); ?></h4>
<div class="vk_posts">
	<?php
	while ( $post_loop->have_posts() ) :
		$post_loop->the_post();

		$options = array(
			'layout'                     => 'media', // card , card-horizontal , media
			'display_image'              => true,
			'display_image_overlay_term' => true,
                   〜略〜
		);
		wp_kses_post( VK_Component_Posts::the_view( $post, $options ) );

endwhile;
	?>

関数の定義みたい。中を見ると、投稿がある分、ループしている感じ。「php echo __( 'Recent posts'」とあるのでこれでしょう。日本語化ってどうやってるんでしょうね?lightning-ja.poに英語-日本語テーブルがあるのでこれでなんとかしているみたい。
おそらく、投稿記事がある分ループして、wp_kses_post( VK_Component_Posts::the_view( $post, $options ) );で記事を表示かな。
この辺で該当記事があればと条件を入れる?前記事と違って標準の関数でやるやらないを設定すればいいだけではなさそうですね。

ポイントはWP_Query()

WP_Queryをぐぐると、いろんな機能があって、特に記事のループで色々指定できるみたい。
https://wpdocs.osdn.jp/%E9%96%A2%E6%95%B0%E3%83%AA%E3%83%95%E3%82%A1%E3%83%AC%E3%83%B3%E3%82%B9/WP_Query
雰囲気でいうと、最初に出てきたパラメータ設定のところで「カテゴリー」を指定できれば良さそう。

このサイトのところに「カテゴリーのパラメータ」がヒントになりそうです。

あるカテゴリーに関連付けられた投稿を表示する。
cat (整数) - カテゴリー ID を使用します。
category_name (文字列) - カテゴリーのスラッグ(カテゴリ名ではありません)を使用します。
category__and (配列) - カテゴリー ID を使用します。
category__in (配列) - カテゴリー ID を使用します。
category__not_in (配列) - カテゴリー ID を使用します。

https://wpdocs.osdn.jp/%E9%96%A2%E6%95%B0%E3%83%AA%E3%83%95%E3%82%A1%E3%83%AC%E3%83%B3%E3%82%B9/WP_Query

ふむふむ。固定でカテゴリーのパラメータを出すならカテゴリーのスラッグとか使えば楽に限定できそうですね。

コンマで続けて羅列して複数指定もできるようです
$query = new WP_Query( 'category_name=fishing,camp' );

いいですね。今回の目的は、表示している記事のカテゴリーと同じもの。表示している記事のカテゴリーIDを取得して渡せば良いと。

表示している記事のカテゴリーIDを取得

ぐぐりました。ありがとうございます。
https://www.nowte.net/wordpress/wordpress-get-category-data/

現在表示している記事の1番目のカテゴリースラッグを表示

<?php
$cat = get_the_category();
$cat = $cat[0];
echo $cat->slug; ?>

https://www.nowte.net/wordpress/wordpress-get-category-data/

カテゴリーは1つしか指定しないようにしているのでこれで行けるかな?
※これcat[配列]が途中で別物cat(配列じゃない)に変わっているな。気持ち悪。

現在表示している記事のカテゴリーを複数表示

<?php
$cats = get_the_category();
foreach($cats as $cat){
echo $cat->cat_name;
echo $cat->slug; }
?>

https://www.nowte.net/wordpress/wordpress-get-category-data/

複数取得することもできそう。セットする方も複数設定できそうだったので、こっちのほうが確実かな?でも複雑になりそう。

修正するコード

/opt/bitnami/wordpress/wp-content/themes/lightning/_g3/template-parts/sidebar-contents-post.php
冒頭に出てきたやつです。今回は前のwordpressの知識があったのでたどり着くのは早かった。今回はすべてビンゴ。ただしPHPのコードを書くのにハマった。

修正1:表示している記事と同じカテゴリーに絞る

/same categoryのため新規変数を追加する
$cats   = get_the_category(); //categoryは配列で入る
$cat_id = $cats[0]->term_id;  //一つ目のcategory ID  例)2:web構築日記

//test
//echo $cat_id; echo ':';echo($cats[0]->name);echo '</p>';
//var_dump($cats[0]);echo '</p>';
//var_dump(get_the_category()[0]);echo '</p>';//続けてかいてもよし

$post_loop = new WP_Query(
	array(
		'post_type'              => 'post',
	        'cat'                    => $cat_id,//add for restruct same category  0 is all
		'posts_per_page'         => 10,
		'no_found_rows'          => true,
		'update_post_meta_cache' => false,
		'update_post_term_cache' => false,
	)
);
?>

ピンク蛍光ラインを引いたところを追記します。
黄色蛍光ラインは調査のためのコードです参考までに、ブラウザに表示されます。

  1. 表示している記事のカテゴリーを取得します。カテゴリーは複数あるのですが、
  2. 今回は1つ目のカテゴリーのみ$cats[0]のidを取得します。
  3. ループする条件のところにカテゴリーの指定'cat'を追加してそれに先程取得したカテゴリーのidをセットします。


PHPは変数の始まりに$を付けるのが慣れてなく、$cat_id=cats[0]->term_idのようにcatsに$を付け忘れて少々ハマりました。でもメンバーには$を付けないのは$に何か意味あるのかな?

修正2:「最近の投稿」の表示を「[カテゴリー名]のカテゴリーの最近の投稿」と表示

「最近の投稿」の表示を[カテゴリー名]のカテゴリーの最近の投稿」と表示したい。

<h4 class="sub-section-title"><?php echo __( 'Recent posts', 'lightning' ); ?></h4>

修正1のちょっと下、ループ処理の直前に上記のような記述があります。これはhtmlに「Recent posts」=「最近の投稿」を出力しているところです。これがゴニョゴニョして日本語の「最近の投稿」になると思うのですが、面倒なのでその仕組みは無視して、直接書き出します。
やりたいのは「最近の投稿」の前に固定文字「カテゴリー:」+ [カテゴリー名]+「の」を追加して出力したいです。

<h4 class="sub-section-title">
    「
    <?php echo($cats[0]->name); /*この辺追加*/ ?>
    」のカテゴリーの
    <?php echo __( 'Recent posts', 'lightning' ); ?>
</h4>

1行じゃ見づらいので改行して付け足します。文字はそのまま、そして[カテゴリー名]は先程学習したとおり、PHPで出力<?php ?>の間にコードを記述します。文字の出力はecho。そして、先程のカテゴリーの情報=cats[]の変数がそのまま使えます。名前の変数は'neme'、外いろいろ変数あるので遊んでみてください。

以上で完成です。

結果:できた

1ページ分の投稿記事

ちなみにカテゴリーのTOPページもそうなった。同じものを使っているのだろう。

もししたら、うちだとカテゴリーの親ページで趣向はまとまっているので、カテゴリーの親ページのものを出しても良いかも。それも同じように投稿記事のカテゴリーの情報に親IDがあったので、それとその子カテゴリーのIDを全部をIDだけの配列にして渡すのかな?また次回!

コメントを残す