[Snow Monkey Blocks] 最近の投稿ブロックでフィルタリングしたい場合

こんにちは。昨日の夜からすごい寒かったのですが、やはり雪降るフラグだったのですね。
藤沢でもいっときは「え?これ積もるの?」みたいなぼたん雪が舞っていて、万が一のために、家に帰っておいたほうがいいのだろうかと悩みました(帰らないで正解でした)

さて、あれほどウィジェットを愛用していて、ウィジェットなしでは生きられない「No Widget.No Life 」な感じだったのですが、Snow Monkey Blocksを使い始めてからというものトップページ作成において、ウィジェットをほとんど使わなくなりました。(使うのフェイド切り替えタイプのスライドショー入れたいときだけになってます)

そんなこんなで、「最近の投稿」の一覧もウィジェットではなく、もれなくブロックのほうで表示するようになっています。そんな中、案件で○○のカテゴリの最新投稿○件表示したい(見た目は最近の投稿ブロックでok)といった要望がありまして、対応したので、どういった対応したのかを備忘をかねてお伝えします!

Snow Monkey Blocks の最近の投稿ブロックでのフィルタリングの方法

過去、最近の投稿ウィジェットでは、フィルターフックでこのカテゴリだけ表示するといってフィルタリングをやったことがあったので、同じような手順でフックできるのかな?って気軽な感じでやってみました。

無理でした。

BlockのIDってなんだろう?? HTMLタグに吐き出されているIDでいけるのかな??ってやってみたのですが、なにも反応せず。

Snow Monkey Blocksのコードみれば、hook名とかIDとかの指定とかなにかわかるんじゃないか?と思い調査。(ちなみに私はあまり能力ないので調査と豪語しておきながらapply_filters()という部分を探して、どことなく推理してみるぐらいの感じです)

うん!わからない!

わからないので フォーラムできいてみることにした

この業界に足を突っ込んで結構な年月が流れておりますが、今回がWordPress関連のフォーラムデビューです。無駄にドキドキしながら、Snow Monkeyのフォーラムで質問してみました。

詳しくは上記を見てください。という感じですが、すでに同じようなトピックありました orz
自分の調査能力のなさ具合がひどいぞ!

驚愕の事実 ブロックを識別するものがない

ブロックを識別するものが現状ないらしい
oh…!!

なんかね。ブロックエディタ便利だし(だって段落から見出しにするのMarkdownで一発だし)当然そういうのあると思ってた。そしたらない!
信じられなくてぐぐってみたが小学生英語能力で読解できるような感じな文章だと、やはり「できるぜ!」的なのが見当たらない。

が、投稿・ページ内にブロックが1つだけの場合は対応できるぞ

こちらのコメントで解説されているコードで、とりあえず「最近の投稿 ウィジェット / ブロック」のフィルターフックを発動させて、フックの実行関数内でif文でこのページのときのみって感じにしてしまえば、いけるそうです!
これはこれで朗報! is_〜が使えるなら、けっこう汎用性がある気がする。

そして見出しには1つだけとか言っちゃったけど、そのページに複数最近の投稿があっても、全部同じ条件でフィルタリングしてもいいなら、何個でもいける!(そんなことあるのかわからないけど)

同じページに複数ブロックがあり、それぞれ違うフィルタリングをしたい場合

このブロックと指定する方法がないため、ブロックだけでどうこうするのは諦めました。
ブロックと同じ見た目・機能のウィジェットがあるのでそちらを利用していきたいと思います。

トップページの場合 かつ メインコンテンツの一番上・一番下に最近のお知らせを表示したい場合

素直にウィジェットの「ホームページ上部」「ホームページ下部」のウィジェットエリアにて「SnowMonkey:最近の投稿」を追加してしてしまえばOK!まあ楽。まあ素敵!

トップページじゃない、あるいは任意の場所に最近の投稿入れたい場合

ブロックみたいに、任意の場所に入れたいときありますよね〜。私もこのケースにぶち当たりました。

オリジナルのウィジェットエリアを追加して、それをショートコードで呼び出す

適切な方法かはわかりませんが、これだと色々手直ししやすいなって思ってるので、私はこの方法で実装しました。

// --- トップページ用:フィルタリングした最近の投稿ウィジェット ---
//専用のウィジェットを作成
add_action(
	'widgets_init',
	function(){
		register_sidebar(array(
			'id'            => 'home_recent_post_01',
			'name'          => 'お知らせ1',
			'description'   => '上部のお知らせ用のウィジェットエリアです',
			'before_widget' => '<div id="%1$s" class="home_news_widget">',
			'after_widget'  => '</div>',
			'before_title'  => '<h2 class="home_news_widget_title">',
			'after_title'   => '</h2>',
		));
		register_sidebar(array(
			'id'            => 'home_recent_post_02',
			'name'          => 'お知らせ2',
			'description'   => '下部のお知らせ用のウィジェットエリアです',
			'before_widget' => '<div id="%1$s" class="home_news_widget">',
			'after_widget'  => '</div>',
			'before_title'  => '<h2 class="home_news_widget_title">',
			'after_title'   => '</h2>',
		));
	}
);

//任意のウィジェットを呼び出すショートコード
function view_home_news_widget($atts) {
	extract(shortcode_atts(array(
		'widget_id' => '',
	), $atts));
	$html = '';
	if( is_active_sidebar( $widget_id ) ) {
		ob_start();
		dynamic_sidebar($widget_id);
		$content = ob_get_clean();
	}
	return $content;
}
add_shortcode('view_home_news_widget', 'view_home_news_widget');

フィルタリングしたい最近の投稿分、ウィジェットエリアを最初に宣言してしまって、それを呼び出すショートコードを作る(引数で呼び出したいウィジェットエリアを取得する形)

そうするとウィジェットの設定画面で新しくエリアができるので、そこに各々「最近の投稿」ウィジェットを設定します。

その後、実際に最近の投稿を呼び出したいページ(投稿)の編集画面を表示し、ショートコードブロックを追加します

[view_home_news_widget widget_id={設定したウィジェットエリアのID}]

保存したあとに、とりあえずブロックをいれた箇所に最近の投稿ウィジェットが表示されていることを確認します。

最近の投稿 ウィジェットをフィルタリングするためのコードを追加

//最近の投稿ウィジェットのフィルタリング
//上部 - exmapleカテゴリのみ
add_filter( 'snow_monkey_recent_posts_widget_args_{ID値}', function( $query_args ) {
	$query_args['category_name']  = 'example';
	return $query_args;
} );

//下部 - exampleカテゴリ以外
add_filter( 'snow_monkey_recent_posts_widget_args_{ID値}', function( $query_args ) {
	$query_args['category__not_in']  = array(5); //category idが5だけ除外
	return $query_args;
} );

ウィジェットのIDは、実際にウィジェットを設置したページを表示して、ウィジェットの親divにidがあるので、そちらの末尾の数字で大体いける!
なんか過去それでいけなかったことがあったときは、ウィジェットの編集画面で、そこのソースからidをみつけていけました。
ひょっとしたら簡単に分かる方法がもっとどこかにあるかもしれないので、そしたら私に教えてください。お礼に袖の下(飴ちゃんとか)あげますので!どうかよしなに!!

最後にちゃんとフィルタリングが効いているか確認すればOK!

最後に

これまでと同様、もっと簡単で良い対応方法があるような気がしてたまらないので、(そしてだいたいそれは1日足らずで見つかる)、そしたらちょっと落ち込んでここから逃げ出して、巡り巡ってマグロ漁船に乗り込み、マグロ採って帰ってくるので、マグロ食べてください(壮大なストーリー)