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"
  }
}
  • 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 Jan 24 '18 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. – Themushroomsound Jan 24 '18 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 Jan 24 '18 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 ? – Themushroomsound Jan 24 '18 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 Jan 24 '18 at 18:41
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 :\

|improve this answer|||||
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.

|improve this answer|||||
  • 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! – Themushroomsound Jan 25 '18 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 Jan 25 '18 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! – Themushroomsound Jan 25 '18 at 9:34

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.