タグ: WP基礎

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

    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を関数ごとに分割して管理しやすくする話