i'm facing a problem with my custom query and need your help.

I want to display all posts of a specific category and I find this snippet:

// get all the categories from the database
    $cats = get_categories(); 
    // loop through the categries
    foreach ($cats as $cat) {
        // setup the cateogory ID
        $cat_id= 0;
        // Make a header for the cateogry
        // create a custom wordpress query
        // start the wordpress loop!
        if (have_posts()) : while (have_posts()) : the_post(); 

This is working fine BUT if a posts is in more then one category then all other posts are displayed 2 and 3 times.

For Example: I want to list all Post of Category 0 There are 2 Posts - post 1 and post 2; post 1 is also in the category 1 Post 1 and Post 2 will be displayed twice in the frontend.

How can i fix this issue?

Thank you guys.


Don't use query_posts() - it breaks things.

There's no need to run a query for each category when you can create a single query to snag posts in any specified category simultaneously. This is both more efficient as well as a means to see you don't end up with duplicates.

Since you were using query_posts() to replace the main query, the correct solution then is to modify the main query in a pre_get_posts action hook - or completely replace it with a WP_Query instance of your own design. In particular, you'll need to use the category parameters - most likely category__in which allows you to specify an array of category ids.

All that in mind, your code doesn't make much sense - it obtains a list of every category, then queries the same category 0 as many times as there different categories. I.e., if there are 6 different categories, then that code queries category 0 for posts 6 times instead of querying each unique category.

Further, if you want to query every existing category for posts, there's no reason to include category query arguments at all - in omitting category query arguments, WordPress will perform a query for posts in any category.


By putting the query_posts (and the nested while (have_posts()) loop) inside your for loop, you are rerunning the loop and actually wrecking the main query, it's stated in the documentation for query_posts that you should look for any other way to modify the main loop.


You'd get better results using an action hook for the get_posts call and adjust the tax_query

function wpse257739_custom_categories_posts( $q ) {
  if ( $q->is_main_query() ) {
    $q->set( 'tax_query', array(
      'taxonomy' => 'category',
      'field' => 'slug',
      'terms' => array( 'category-one', 'category-2' ),
      'operator' => 'IN' // redundant
    ) );

add_action( 'pre_get_posts', 'wpse257739_custom_categories_posts` );

Full documentation details: https://codex.wordpress.org/Class_Reference/WP_Query#Taxonomy_Parameters

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.