0

I am using pre_get_posts() in the backend for a custom post type screen where all the records are usually displayed.

The action I have is showing only posts for today's date. This is working fine but when I try to use the default filter for different dates I get no data even though I know there is data. (removing the action shows all the data).

Is there a way I can use pre_get_posts but still filter/show previous dates?

add_action ( 'pre_get_posts',  'modify_query_get_apps_by_date' );

function modify_query_get_apps_by_date( $query ) {

    if ( is_admin() && $query->is_main_query() && $query->get( 'post_type' ) == 'apps' ) {
          $query->set( 'meta_query', [
              [
                  'key' => 'app_date',
                  'value' => date('d-m-Y'),
              ],
          ]);
    }
}
  • 1
    What is $query_vars ? Did you mean $query->get( 'post_type' ) ? – Sally CJ Feb 27 at 12:00
  • It was an alternative to s_post_type_archive( 'apps' ) which wasn't working. Sorry, that was meant to be $query->query_vars['post_type'] – user10980228 Feb 27 at 12:05
  • 1
    $query->query_vars['post_type'] = 'apps' uses a single equals sign, are you sure you want to use assignment? Did you mean = and not ==? I would also second Sallys comment that you should use ->get( instead, there's probably another method that's even more appropriate – Tom J Nowell Feb 27 at 12:10
  • Whether I use single or double the result is the same so it doesn't seem to be that. I am still seeing results for the current day which is what I want but I cannot filter by any other date. That just results in 0 results – user10980228 Feb 27 at 12:12
  • It should not be a single =, my understanding is that this changes all admin queries to only list posts of that type, it's a bug even if it's not the one you're asking about – Tom J Nowell Feb 27 at 12:13
2

The problem is that you always set the meta query, if you don't want it to apply in a particular situation, you need to check for that situation and account for it. Similar to how you're already checking with is_admin, or is_main_query, etc.

In this situation, you'll want to check the $_GET parameters to detect if the filter has been applied on the posts screen, and only set the meta query if it isn't present. In this case, I believe the parameter used is m, but there are several others in the URL to check against

Further notes:

  • When you get the filter working, you probably won't see the results you're expecting as that filter works on the publish date. If you're expecting to see applications filtered by date, you'll need to detect when a filter is happening and add a different meta query that queries app_date via those filter arguments, then undoes the default filter
  • Filtering posts via their post meta is expensive! Really, really expensive! Treat these as a rare thing you only do occasionally. I've seen major sites brought down by simple post meta queries, it puts a big strain on the database. That's why taxonomy tables were created, otherwise, categories and tags would be stored in post meta. If you can repurpose the publish date, that'll make a huge difference.
  • You're not using a standardised format for your date values. Not only that but they're ambiguous! Use YYY-MM-DD instead and follow the ISO standards agreed upon, and you'll get better compatibility
  • Consider specifying that your values are dates using 'type' => 'DATE'
  • You can make the function easier to read and modify by separating out those conditionals into guards and exiting early, e.g. if ( !is_admin() ){ return; }, this also makes debugging easier, and lets you test each check individually if things go wrong

There is also a bug in your code, that is unrelated to your issue, but still a bug. The code checks if the current query is for a particular post type, but because it uses an assignment operator = instead of a comparison operator ==, instead of checking if they match, it sets/assigns the value. As a result, all queries are now queries for apps. This is unrelated to the issue in your question.

| improve this answer | |
  • Thanks so much Tom for your suggestions and advice, I resolved the issue by adding a $_GET condition. Cheers! – user10980228 Feb 27 at 12:46

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.