Skip Navigation

[Resolved] Exclude posts with enabled checkbox from View

This support ticket is created 6 years, 6 months ago. There's a good chance that you are reading advice that it now obsolete.

This is the technical support forum for Toolset - a suite of plugins for developing WordPress sites without writing PHP.

Everyone can read this forum, but only Toolset clients can post in it. Toolset support works 6 days per week, 19 hours per day.

Sun Mon Tue Wed Thu Fri Sat
8:00 – 12:00 8:00 – 12:00 8:00 – 12:00 8:00 – 12:00 8:00 – 12:00 - -
13:00 – 17:00 13:00 – 17:00 13:00 – 17:00 13:00 – 17:00 13:00 – 17:00 - -

Supporter timezone: America/New_York (GMT-04:00)

Tagged: 

This topic contains 9 replies, has 2 voices.

Last updated by Christian Cox 6 years, 6 months ago.

Assisted by: Christian Cox.

Author
Posts
#694093

I'm trying to use the View Query Filter to exclude posts which has an enabled checkbox.

The custom field when enabled is "wpcf-exclude-from-listings" with a value of "1".

When not enabled the custom field is non-existent.

So far so good, but I can't figure out how to only show posts which have the "wpcf-exclude-from-listings" custom field set.

Needless to say, I don't want to populate all the posts with this custom field.

So the query should be something like "select posts that doesn't have the wpcf-exclude-from-listings custom field" or rather "select posts that doesn't have the wpcf-exclude-from-listings custom field set to 1".

I read this thread -> https://toolset.com/forums/topic/excluding-ceratin-posts-from-a-view/ <- but still can't figure out what they did to make it work as I've tried to do this on my own already.

#694712
Screen Shot 2018-04-19 at 4.16.17 PM.png

I would try the configuration shown in the attached screenshot - select posts where the custom field value is a number that is different from the constant value "0". An unchecked checkbox will be interpreted as "0", but a checked checkbox will be interpreted as different from "0".

#696467

This doesn't work.

I need a query filter rule that includes posts that don't have this particular custom field at all.

To be able to do as you mentioned, all posts must be populated with the custom field we're filtering on.

Please advise.

#710557

To be able to do as you mentioned, all posts must be populated with the custom field we're filtering on.
Sorry, I don't think I understand exactly what you mean by "populated", can you explain in more detail so I can get some context?

#710595

By "populated" I mean that the posts must have the custom field added, while I want to filter on posts that has a different custom field value or not this custom field at all. Seems like the compare NOT EXISTS is not around in the View query filter, while it's available in the regular wp_query?
https://codex.wordpress.org/Class_Reference/WP_Meta_Query#Accepted_Arguments

#711758

I think you'll need a more complex custom query here, because if you use the "NOT EXISTS" comparison then all the posts where the checkbox is present but not checked will appear in the results. For example this custom query modification does not work:

add_filter( 'wpv_filter_query', 'or_cb_not_exists',10,3 );
function or_cb_not_exists( $query_args, $views_settings, $view_id) {
  $view_ids = array( 419 );
  if (in_array($view_id, $view_ids)){
    $args = array(
      'relation' => 'OR',
      array(
        'key' => 'wpcf-cb',
        'compare' => 'NOT EXISTS'
      ),
      array(
        'key' => 'wpcf-cb',
        'type' => 'NUMERIC',
        'value' => 1,
        'compare' => '='
      )
    );

    $query['meta_query'] = isset($query['meta_query']) ? $query['meta_query'] : [];
    $query['meta_query'][] = $args;
  }
  return $query_args;
}

The results include all of the CPTs where the checkbox exists as an option but is not checked, as well as all the CPTs where the checkbox does not exist as an option. So I think another approach is necessary here. Are the posts without the checkbox as an option all in some single post type, or is there any other logic that can be used to know whether or not you have added the checkbox option to that post?

#723889

I want to add a checkbox to ordinary blog posts. If it's checked the post should be excluded from a couple of Views.

Using the default settings, I can see in the database that if the checkbox is enabled the post meta key is added, and when unchecked the key is gone.

Knowing this, a filter that excludes all posts that have a certain post meta key should be succifient, no matter the actual value of the post meta key.

One thing that might complicate things though is that I already use the wpv_filter_query for other purposes (e.g. including posts from one category into another), so the whole query have to be merged correctly. I was hoping to find an option for EXISTS/NOT EXISTS in the View Query Filter.

#728149
exclude.png

I see, unfortunately EXISTS / NOT EXISTS will not help you here, because there is no way to differentiate between an unchecked checkbox and a non-existent checkbox. One option is the "post__not_in" parameter, which can be accomplished in code or with a Post ID Query Filter.
https://codex.wordpress.org/Class_Reference/WP_Query#Post_.26_Page_Parameters

Add to your View a post ID Query Filter that excludes a list of posts by ID, passed in by a shortcode attribute. I'm attaching a screenshot here that shows an example of this Query Filter (exclude.png).

To generate a list of Post IDs you want to exclude, you can create a View of Posts filtered by the checkbox custom field. The results will be a comma-separated list of IDs of posts you want to exclude from the other View. In the wpv-loop tags of the Loop Output editor of the new View, place the following code to generate a list of post IDs:

[wpv-item index=1][wpv-post-id][wpv-item index=other],[wpv-post-id]

The results will be something like 1,2,3,4,5 - a list of Post IDs to exclude from the first View. To strip all the unnecessary markup from this list of IDs, please add the following code to your functions.php file:

add_filter( 'wpv_filter_wpv_view_shortcode_output', 'prefix_clean_view_output', 5, 2 );

function prefix_clean_view_output( $out, $id ) {
  $ids = array( 12345, 67890 );
  if ( in_array( $id, $ids )) {
    $start = strpos( $out, '<!-- wpv-loop-start -->' );
    if (
      $start !== false
      && strrpos( $out, '<!-- wpv-loop-end -->', $start ) !== false
    ) {
      $start = $start + strlen( '<!-- wpv-loop-start -->' );
      $out = substr( $out , $start );
      $end = strrpos( $out, '<!-- wpv-loop-end -->' );
      $out = substr( $out, 0, $end );
    } else {
      $start = strpos( $out, '>' );
      if ( $start !== false) {
        $out = substr( $out, $start + 1 );
        $end = strpos( $out, '<' );
        $out = trim(substr( $out, 0, $end ));
      }
    }
  }
  return $out;
}

Replace 12345,67890 with the ID of this View. If you need to use this technique for more than one View, add a comma-separated list of those IDs here. This code will make the comma-separated list of IDs usable by the Query Filter in View #1.

Finally use a shortcode attribute to pass View #2 into the filter of View #1:

[wpv-view name="view-slug-1" ids="[wpv-view name='view-slug-2']"]

Let me know if you think this would work in your case, or if not, why.

#737926

Thanks for putting effort into resolving this matter.

The first code snippet you provided with NOT EXISTS works when I do a quick test. Well, $query needs to the changed to $query_args. In fact, only the part with NOT EXISTS is needed, since all posts which have the custom field should be excluded. Unchecked checkboxes in posts are the same as no custom field, i.e. NOT EXISTS.

So far so good, but I still need to do more testing for different types of Views and also using different languages (WPML).

I wonder how to best combine your filter/query modification with another active wpv_filter_query. E.g. I need to add this for the same View ID:

$query_args['tax_query']['relation'] = 'OR';
	  	$query_args['tax_query'][] = array(
            array(
                'taxonomy' => 'category',
                'field' => 'term_id',
                'terms' => '17'
            )
        );

Maybe I can sort it out on my own, but would like your input if possible. Also, when applying different filter/query mods to multiple Views, should I run them under the same function within if-statements (and just use one wpv_filter_query hook for everything) or do it some other way?

#742898

I wonder how to best combine your filter/query modification with another active wpv_filter_query.
I would add this code to the same callback function.

Also, when applying different filter/query mods to multiple Views, should I run them under the same function within if-statements (and just use one wpv_filter_query hook for everything) or do it some other way?
It doesn't matter much from a performance perspective. Multiple hooks gives you the ability to name the callback functions something recognizable, which is arguably easier to maintain. You have the ability to apply different priorities to affect order of execution when you use different hooks, and you have the ability to programmatically add_filter or remove_filter as needed with multiple hooks.