1

I'm attempting to design a theme for which all posts are always visible in a grid layout, using index.php as my single template. Even accessing a URL matching a single post would display all posts, only with the one matching the URL being highlighted in some way.

This works like a charm on the homepage (http://example.com/), but if I try to access a post (http://example.com/mycategory/mypostname) it shows nothing.

I've tried setting up a pre_get_posts hook like so:

function preGetPosts( $query ) {
    if ( is_admin() || ! $query->is_main_query() )
        return;
    $query->set( 'posts_per_page', -1 );
    $query->set( 'name', "" );
    $query->set( 'category_name', "" );
    return;
}
add_action( 'pre_get_posts', 'preGetPosts' );

But then my page displays no post at all. I've tried figuring it out by showing the SQL request in my template:

<?php echo $GLOBALS['wp_query']->request; ?>

...and the resulting SQL request is fine:

SELECT wp_posts.* FROM wp_posts WHERE 1=1 AND wp_posts.post_type = 'post' ORDER BY wp_posts.post_date DESC

Even trying out the request in phpMyAdmin yields the correct list of all posts. I'm at a loss trying to understand what's preventing the loop from displaying these results.

Even the code that's hooked up to the loop_start action seems to be skipped entirely. Any ideas?

Thanks!

EDIT: if I dump $GLOBALS['wp_query'] in my template just before the loop, I see:

["post_count"] => int(0)
["found_posts"] => int(23)

There are indeed 23 posts that should be displayed... what's the difference between found posts and the post count?

EDIT: The full query dump:

object(WP_Query)#390 (48) {
  ["query"]=>
  array(3) {
    ["page"]=>
    string(0) ""
    ["name"]=>
    string(4) "sos3"
    ["category_name"]=>
    string(8) "mixtapes"
  }
  ["query_vars"]=>
  array(65) {
    ["page"]=>
    int(0)
    ["name"]=>
    string(0) ""
    ["category_name"]=>
    string(0) ""
    ["error"]=>
    string(0) ""
    ["m"]=>
    string(0) ""
    ["p"]=>
    int(0)
    ["post_parent"]=>
    string(0) ""
    ["subpost"]=>
    string(0) ""
    ["subpost_id"]=>
    string(0) ""
    ["attachment"]=>
    string(0) ""
    ["attachment_id"]=>
    int(0)
    ["static"]=>
    string(0) ""
    ["pagename"]=>
    string(0) ""
    ["page_id"]=>
    int(0)
    ["second"]=>
    string(0) ""
    ["minute"]=>
    string(0) ""
    ["hour"]=>
    string(0) ""
    ["day"]=>
    int(0)
    ["monthnum"]=>
    int(0)
    ["year"]=>
    int(0)
    ["w"]=>
    int(0)
    ["tag"]=>
    string(0) ""
    ["cat"]=>
    string(0) ""
    ["tag_id"]=>
    string(0) ""
    ["author"]=>
    string(0) ""
    ["author_name"]=>
    string(0) ""
    ["feed"]=>
    string(0) ""
    ["tb"]=>
    string(0) ""
    ["paged"]=>
    int(0)
    ["meta_key"]=>
    string(0) ""
    ["meta_value"]=>
    string(0) ""
    ["preview"]=>
    string(0) ""
    ["s"]=>
    string(0) ""
    ["sentence"]=>
    string(0) ""
    ["title"]=>
    string(0) ""
    ["fields"]=>
    string(0) ""
    ["menu_order"]=>
    string(0) ""
    ["embed"]=>
    string(0) ""
    ["category__in"]=>
    array(0) {
    }
    ["category__not_in"]=>
    array(0) {
    }
    ["category__and"]=>
    array(0) {
    }
    ["post__in"]=>
    array(0) {
    }
    ["post__not_in"]=>
    array(0) {
    }
    ["post_name__in"]=>
    array(0) {
    }
    ["tag__in"]=>
    array(0) {
    }
    ["tag__not_in"]=>
    array(0) {
    }
    ["tag__and"]=>
    array(0) {
    }
    ["tag_slug__in"]=>
    array(0) {
    }
    ["tag_slug__and"]=>
    array(0) {
    }
    ["post_parent__in"]=>
    array(0) {
    }
    ["post_parent__not_in"]=>
    array(0) {
    }
    ["author__in"]=>
    array(0) {
    }
    ["author__not_in"]=>
    array(0) {
    }
    ["posts_per_page"]=>
    int(-1)
    ["ignore_sticky_posts"]=>
    bool(false)
    ["suppress_filters"]=>
    bool(false)
    ["cache_results"]=>
    bool(true)
    ["update_post_term_cache"]=>
    bool(true)
    ["lazy_load_term_meta"]=>
    bool(true)
    ["update_post_meta_cache"]=>
    bool(true)
    ["post_type"]=>
    string(0) ""
    ["nopaging"]=>
    bool(true)
    ["comments_per_page"]=>
    string(2) "50"
    ["no_found_rows"]=>
    bool(false)
    ["order"]=>
    string(4) "DESC"
  }
  ["tax_query"]=>
  NULL
  ["meta_query"]=>
  object(WP_Meta_Query)#629 (9) {
    ["queries"]=>
    array(0) {
    }
    ["relation"]=>
    NULL
    ["meta_table"]=>
    NULL
    ["meta_id_column"]=>
    NULL
    ["primary_table"]=>
    NULL
    ["primary_id_column"]=>
    NULL
    ["table_aliases":protected]=>
    array(0) {
    }
    ["clauses":protected]=>
    array(0) {
    }
    ["has_or_relation":protected]=>
    bool(false)
  }
  ["date_query"]=>
  bool(false)
  ["request"]=>
  string(112) "SELECT   wp_posts.* FROM wp_posts  WHERE 1=1  AND wp_posts.post_type = 'post'  ORDER BY wp_posts.post_date DESC "
  ["posts"]=>
  &array(0) {
  }
  ["post_count"]=>
  int(0)
  ["current_post"]=>
  int(-1)
  ["in_the_loop"]=>
  bool(false)
  ["comment_count"]=>
  int(0)
  ["current_comment"]=>
  int(-1)
  ["found_posts"]=>
  int(23)
  ["max_num_pages"]=>
  int(0)
  ["max_num_comment_pages"]=>
  int(0)
  ["is_single"]=>
  bool(false)
  ["is_preview"]=>
  bool(false)
  ["is_page"]=>
  bool(false)
  ["is_archive"]=>
  bool(false)
  ["is_date"]=>
  bool(false)
  ["is_year"]=>
  bool(false)
  ["is_month"]=>
  bool(false)
  ["is_day"]=>
  bool(false)
  ["is_time"]=>
  bool(false)
  ["is_author"]=>
  bool(false)
  ["is_category"]=>
  bool(false)
  ["is_tag"]=>
  bool(false)
  ["is_tax"]=>
  bool(false)
  ["is_search"]=>
  bool(false)
  ["is_feed"]=>
  bool(false)
  ["is_comment_feed"]=>
  bool(false)
  ["is_trackback"]=>
  bool(false)
  ["is_home"]=>
  bool(false)
  ["is_404"]=>
  bool(true)
  ["is_embed"]=>
  bool(false)
  ["is_paged"]=>
  bool(false)
  ["is_admin"]=>
  bool(false)
  ["is_attachment"]=>
  bool(false)
  ["is_singular"]=>
  bool(false)
  ["is_robots"]=>
  bool(false)
  ["is_posts_page"]=>
  bool(false)
  ["is_post_type_archive"]=>
  bool(false)
  ["query_vars_hash":"WP_Query":private]=>
  string(32) "8932b0e7ba16b7a363737e0bb1065296"
  ["query_vars_changed":"WP_Query":private]=>
  bool(true)
  ["thumbnails_cached"]=>
  bool(false)
  ["stopwords":"WP_Query":private]=>
  NULL
  ["compat_fields":"WP_Query":private]=>
  array(2) {
    [0]=>
    string(15) "query_vars_hash"
    [1]=>
    string(18) "query_vars_changed"
  }
  ["compat_methods":"WP_Query":private]=>
  array(2) {
    [0]=>
    string(16) "init_query_flags"
    [1]=>
    string(15) "parse_tax_query"
  }
}
5
  • Often, the class on the body tag will give away what template file is being used. Is there anything of interest? Is their any HTML source at all, or is no output produced?
    – janh
    Commented Jan 24, 2018 at 16:20
  • I haven't been explaining very clearly, sorry. My only template is my index.php, built from scratch, and the <body> has no class. The output HTML is fine, it's showing what should be there when no post matches the query ("nothing here"). That's the weird thing: the SQL request looks fine, however have_post() seems to return false. Commented Jan 24, 2018 at 17:42
  • Are any other query_vars set in the wp_query? post_count is the number of posts actually being shown, and 0 makes sense, since you're not seeing any ;)
    – janh
    Commented Jan 24, 2018 at 18:15
  • You're right, at least post_count is consistent with what I'm seeing ^^ I've added the full query dump, can you see anything weird in there? Could it be a pagination issue caused by posts_per_page being -1 ? Commented Jan 24, 2018 at 18:31
  • ["is_404"]=> bool(true) that explains why no posts are shown. Looks interesting enough, I'll try to setup a simple install later and see if I can reproduce and (hopefully) solve it.
    – janh
    Commented Jan 24, 2018 at 18:41

2 Answers 2

1

I ended up using the request filter, just like in the documentation:

function filterRequest( $request ) {
    global $single_post_slug;

    $dummy_query = new WP_Query();  // the query isn't run if we don't pass any query vars
    $dummy_query->parse_query( $request );

    if( $dummy_query->is_single() && !$dummy_query->is_admin() )
    {
        $single_post_slug = $request['name'];
        $request['name'] = "";
        $request['category_name'] = "";
    }

    return $request;
}
add_filter( 'request', 'filterRequest' );

It might not be the cleanest way, but I get to store the original query's slug to use it later. And I can avoid effecting the admin. I'm afraid this might effect secondary queries though, so I'm expecting trouble down the line :\

0

Testing with a standard install and twentysixteen, the problem lies within WP::parse_request. With your pre_get_posts action in place, simply removing that completely from the equation worked for me:

add_filter("do_parse_request", function ($original_value, $query, $extra_vars) {
    $query->query_vars = array();
    return false;
}, 10, 3);

Setting $query->query_vars to an empty array is necessary because WP expects it and you'll get warnings otherwise.

You'll probably want to thoroughly test it to make sure it behaves as you require it to, but at a quick glance, it looked fine in my installation.

3
  • I just tried that solution and it has 2 drawbacks: 1) I can't tell the original query anymore from any info in the wp_query object 2) I get all sorts of weird issues in the admin doing this (recent posts show all posts, 'all posts' link now shows only the 3 last ones...) I was hoping for a more surgical solution. I'll look into why is404 gets triggered when I'm only removing the name/category_name filters from the query, thanks for pointing that out! Commented Jan 25, 2018 at 8:50
  • The side effects in wp-admin could easily be circumvented, I suppose, but the info is lost, yeah. You could possibly do something weird and call parse_request later on (removing the filter on its execution), it's a public function, but I have no idea what might come crashing down. For is_404, it's likely in that function, so I'd start there (wp-includes/class-wp.php). Good luck, and I'd love to learn how you solved it in the end.
    – janh
    Commented Jan 25, 2018 at 9:07
  • Ah, I just saw your comment after posting my answer. I've got something that could work. Thanks for taking the time to look into it @janh! Commented Jan 25, 2018 at 9:34

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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