• Resolved dozerua

    (@dozerua)


    Hello,
    I am doing some page with filters and spotted interesting bug (is it a bug??) related to quering articles (posts).

    In my case I want to output default “post” articles and my custom post type “blog”.

    In test environment I have 100+ post articles and 8 blog articles.

    I tried query_posts() and pagination gets messed up.
    Also pagination gets messed up with wp_query.

    Well, maybe I am doing something wrong.

    If I output only single post type, all works fine.

    My args look like this:

    'post_type' =>  array('post', 'blog'),
    'post_status' => 'publish',
    'posts_per_page' => 6,

    I am doing it with AJAX, so my query is in functions.php.

    I copied results to gsheets and marked titles which were repeating. I can tell that this is not related to offset. This is related to merged post types. So if I have 2 blog articles only, two “posts” articles are repeated.
    If I have 8 blog articles, table looks a little horrible ??

    What am I doing wrong?

    If there any hack for multi post type?

    I have the most recent wordpress version.

    Regards

Viewing 10 replies - 1 through 10 (of 10 total)
  • Moderator bcworkz

    (@bcworkz)

    Avoid using query_posts(), it causes unnecessary additional queries. Usually the best way to customize a query is to modify the main, default query through the “pre_get_posts” action. Set the query vars as desired and pagination should work correctly.

    The main reason to use get_posts() or a new WP_Query is when you are still using the default main query as intended and you wish to make an additional, separate query. Usually such queries would not be paginated, since pagination normally belongs to the main query. But if do want to paginate a secondary query, use paginate_lnks(), other pagination functions will not work correctly.

    You’ll see many examples that use $paged query var as the requested page to query for. Using $paged in a secondary query can be problematic because it rightfully belongs to the main query, not the one you’re trying to paginate. I recommend creating your own custom pagination query var to manage which page to query for. Use the “query_vars” filter to whitelist your custom query var.

    Thread Starter dozerua

    (@dozerua)

    @bcworkz , thank you for your answer.

    I am not sure what can be hard for wordpress if initially I request only post type, sorting, page, posts per page.

    I assume that is basic request. I even tried to get_posts with just post types and paged.

    But I will try modyfing main query. Not sure if that will help.

    Thread Starter dozerua

    (@dozerua)

    I tried “pre_get_posts” on default posts page (literally set some page to be posts page in settings), set my own parameters and results are still messed up.

    add_action( 'pre_get_posts', 'get_posts_search_filter' );
    function get_posts_search_filter( $query ){
    
    	if ( $query->is_main_query() ) {
    		$query->set( 'post_type', [  'post', 'blog' ] );
    		$query->set( 'ignore_sticky_posts', '1' );
    		$query->set('status', 'publish');
    	}
    }

    Also I noticed that results are messed up even if I try to do array of categories in that query.

    What can be an issue?

    I did clean fresh setup on subdomain, imported posts which I have with default wordpress importer, modified pre get posts, check results – messed up.

    What is going wrong?

    Regards

    Moderator bcworkz

    (@bcworkz)

    Did you comment out the query_posts() code after adding the action callback? If not, you’re not seeing the results of the main query.

    If you have done so, it could be some other code is also altering the query vars to cause unexpected behavior. On the template, echo out the global $wp_query->request value, the SQL used for the query. Something in the query should be evident as the cause of unexpected behavior. The nature of the deviation might be a clue towards the root cause.

    Thread Starter dozerua

    (@dozerua)

    @bcworkz I tried on many new instances. This is literally 2020 template, main page. The only custom code added is pre_get_posts() to functions.php

    Nothing custom.

    So tonight I did other fresh wordpress setup, added 100 dummy posts with plugin.
    Posts appear fine if no pre_get_posts() set.

    If I add filter, pagination gets messed up. Cache is disabled on server. And website shows different articles on every page reload.

    https://posts.placemeonline.com/

    Check it please.
    I tried in private tab.
    Functions.php has this text:

    add_action( 'pre_get_posts', 'get_posts_search_filter' );
    function get_posts_search_filter( $query ){
    		$query->set('category__in', [ '1']);
    }

    Wordpress is 6.0.3

    Moderator bcworkz

    (@bcworkz)

    There shouldn’t be “index.php/” in permalinks. Check your home and site URL settings and your permalink setting.

    You need to always check a condition prior to setting anything in “pre_get_posts”. Usually at least if ( $query->is_main_query()):. Numerous other posts queries can pass through this action that are unrelated to whatever you’re trying to do. There are a few “hidden” post types (and “page” type) which don’t even have a category relationship where “category__in” would even make sense. This could also be the cause of random posts displaying on page 2. Prior to setting a category requirement, you should also be verifying the query is for a post type that uses categories.

    Requiring category 1 for all posts requests could be causing posts navigation links (next/previous posts from single post pages) to not work correctly. You may need to also check if ( ! $query->is_single()):.

    Thread Starter dozerua

    (@dozerua)

    @bcworkz

    Okay, thank you for your help so far.

    Report is:
    1) I tried on fresh wordpress setups on 2 different servers
    2) No other plugins are enabled
    3) The only piece of custom code is in functions.php (in 2020 parent theme)

    add_action( 'pre_get_posts', 'get_posts_search_filter' );
    function get_posts_search_filter( $query ){
    		
    	if ( $query->is_main_query() ) {
    		$query->set('category__in', [ '1']);
    	}
    
    }

    4) I updated permalink, not sure if that could cause issues
    5) Articles are shown on default wordpress posts page, which is set by default in “Settings” -> “Readings”

    Your homepage displays Your latest posts

    What do I do now? Is it a problem with me?
    Can you test it in your environment, please?

    For making dummy posts I used “Allimport pro plugin” before (with csv import) and for the most recent instance I used “WP Dummy Content Generator”, which was disabled after work was done. WordPress installation files are different (I tried on server’s installation option and tried uploading files from wordpress website).

    In all cases articles are messed up. If I output everything (disable limit on amount of posts) then order is correct and no repeating articles.

    Regards

    Moderator bcworkz

    (@bcworkz)

    I tried to replicate your site’s configuration on my test site as best I can, using you code snippet. Pagination works fine. However, I did not import or generate any content. I used my existing content. While it seems unlikely, it is possible creating dummy posts via plugin somehow corrupted your DB.

    Is your installation more or less up to date? (6.1 just dropped, but any 6.0.x should be fine for this investigation) I tested on 6.0.3.

    You might try looking at the query used for the second page by using the Query Monitor plugin. If the query is correct for the situation, I’m inclined to think either your WP installation or the DB itself is somehow corrupted. You could try yet another new test installation, this time manually creating some dummy content. You needn’t create more than a half dozen posts to test if you set posts per page to 2 or 3.

    Thread Starter dozerua

    (@dozerua)

    @bcworkz
    thank you for your help. Issue was found.

    Basically on my csv import or dummy posts ( I assume ) posts had only different dates while time was always same (12:00am). So if I have 10 posts posted at 11/11/2011 and at 12:00am all, on page reload wordpress was showing them in random order.

    By making double filtering, for example ‘orderby’ => ‘date ID’, everything appears fine and no repeats.
    I, actually, expected that wordpress makes it default but no ??

    Learned this lesson, now is fine with pre_get_posts() and also with query_posts().

    Thank you again. I did articles manually and understood that time matters.

    Moderator bcworkz

    (@bcworkz)

    You’re welcome.

    Hmmm… Different dates, same times should still order correctly, the post creation date/time data is all in one field. If the current system time is assigned upon auto-creation, there could be a good number of posts with the exact same time since granularity is only to the second, no decimal fractions are saved.

    I would have expected secondary ordering by ID even without specifying it, not random order for the same time stamp. I guess I don’t understand DB operations as well as I thought I did ??

    Anyway, I’m glad you found the issue.

Viewing 10 replies - 1 through 10 (of 10 total)
  • The topic ‘Quering array of post types & pagination’ is closed to new replies.