Advanced Custom Fieldsで「真/偽」を使ったときのmeta_queryの指定

WordPressのカスタムフィールドを作れるプラグインAdvanced Custom Fieldsの「真/偽」を使って、「チェックした記事は一覧に表示させない(meta_queryで除外する)」方法を調べるのにけっこう時間がかかったので、備忘録として。




その答えは、こうだ!!!

$param = array(
	'posts_per_page' => '3',
	'post_type' => 'news',
	'meta_query' => [
		[
			'key' => 'check_flag',
			'value' => '0',
			'compare' => '='
		],
	],
);

これで、「”check_flag”にチェックが入っていない記事」だけが表示されます。

しかし、ここで要注意なんですが、既にある程度記事がある段階で真/偽フィールドを追加した場合、このままだとうまく除外できません

なぜかというと、上記は具体的には「値がfalse(0)である記事のみ表示させる」という意味なんですが、なんと真/偽フィールドを追加する前から存在している記事は、チェックをしていない場合に入ってる値はfalseではなくNULLだからなんですね。
そもそも値が入っていないのです。

だから、そういった場合は上記に加え「NULLのやつも表示」って書く必要があります。

$param = array(
	'posts_per_page' => '3',
	'post_type' => 'news',
	'meta_query' => [
		'relation' => 'OR',
		[
			'key' => 'check_flag',
			'value' => '0',
			'compare' => '='
		],
		[
			'key' => 'check_flag',
			'compare' => 'NOT EXISTS'
		]
	],
);

これでよし。

 

おまけで、「”check_flag”にチェックが入っている記事」だけ表示したい場合はこう。

$param = array(
	'posts_per_page' => '3',
	'post_type' => 'news',
	'meta_query' => [
		[
			'key' => 'check_flag',
			'value' => '1',
			'compare' => '='
		]
	],
);

まぁ、こっちは公式に書いてるんですけどね。

 

ついでにもう一つ、ちょっと応用編。

例えばindex.phpとかarchive-news.phpで、WP_QUERYを使っていない場合。(条件なしで普通にループさせている場合。)
こうなると、もし上記を実装するとなるとWP_QUERYを書かなきゃいけなくなって、カテゴリーページとか年別アーカイブも作って同じように実装して…ってやらなきゃいけないので、めちゃくちゃめんどくさいですよね。

そんなときは、functions.phpで以下のようにやっちゃいましょう。

add_filter( 'parse_query', 'custom_parse_query' );
function custom_parse_query( $query ) {
  if ( is_admin() || is_singular() ) { // 管理画面とsingleは除く
    return false;
  }

  $check_flag_array = array(
    'relation' => 'OR',
    array(
      'key' => 'check_flag',
      'value' => '0',
      'compare' => '='
    ),
    array(
      'key' => 'check_flag',
      'compare' => 'NOT EXISTS'
    )
  );
  if ( get_query_var( 'post_type' ) == 'news' ) { //post_typeを指定
      $query->set( 'meta_query', $check_flag_array );
  }
}

これで、「post_typeがnewsの一覧(query)」で、同様の条件を指定することができます。

もしnews以外も同じ条件を指定したい場合は、post_typeを増やすだけです。
※$query->is_main_query()も入れないと、index.phpで適応されないみたいです。

add_filter( 'parse_query', 'custom_parse_query' );
function custom_parse_query( $query ) {
  if ( is_admin() || is_singular() ) { // 管理画面とsingleは除く
    return false;
  }

  $check_flag_array = array(
    'relation' => 'OR',
    array(
      'key' => 'check_flag',
      'value' => '0',
      'compare' => '='
    ),
    array(
      'key' => 'check_flag',
      'compare' => 'NOT EXISTS'
    )
  );
  if ( get_query_var( 'post_type' ) == 'news' || get_query_var( 'post_type' ) == 'post' || get_query_var( 'post_type' ) == 'seminar' || get_query_var( 'post_type' ) == 'business' || $query->is_main_query() )
}

これでぐっと楽になりました。
しかもなんと、RSSフィードにも表示されないみたいです!

 

以上、現場からでした。

 

よかったらこっちもどうぞ

WordPress functions.phpを関数ごとに分割して管理しやすくする話

コメント

“Advanced Custom Fieldsで「真/偽」を使ったときのmeta_queryの指定” への1件のフィードバック

  1. 通りがかりのアバター
    通りがかり

    $check_flag_array = array(
    ‘relation’ => ‘OR’,
    array(
    ‘key’ => ‘check_flag’,
    ‘value’ => ‘0’,
    ‘compare’ => ‘=’
    ),
    array(
    ‘key’ => ‘check_flag’,
    ‘compare’ => ‘NOT EXISTS’
    )
    );

    ORにすると、件数が増えると重くなるので、

    $check_flag_array = array(
    array(
    ‘key’ => ‘check_flag’,
    ‘value’ => ‘1’,
    ‘compare’ => ‘!=’
    ),
    );
    としたほうがいい

コメントを残す

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