2

I need a query to show all posts in the site but not repeat the ones with same tag, I mean only show one post with the same tag.

My current query is

    <?php
        $paged = (get_query_var('paged')) ? get_query_var('paged') : 1;
        $args = array(
        'post_type' => array('post'),
        'posts_per_page' => 30,
        'paged' => $paged,
        'order' => 'ASC',
        'orderby' => 'name' 
        );
        query_posts($args);
    ?>

How can I show only post with the same tag?

Thanks!

4
  • 2
    This won't be achievable with a single WP_Query. You'd need to first get a list of tags, then loop through those and query a single post for each one. So for 30 posts you'd need 30 queries. Aug 28, 2018 at 14:04
  • I guess there is some way to exclude posts with the same tag id and show only the first one,,,
    – Mr.CAT
    Aug 28, 2018 at 14:13
  • 1
    Well, there isn't. Aug 28, 2018 at 14:13
  • @Mr.CAT not everything can be done in a single step, this is a multiple step operation. Nor should you be using query_posts, pretend that function does not exist and use get_posts or WP_Query instead, they take exactly the same parameters, but they eliminate a lot of the issues query_posts has for free. Also if your goal is to modify what WP shows, use the pre_get_posts filter, it's a huge performance boost over what you're doing, and completely eliminates pagination issues
    – Tom J Nowell
    Aug 28, 2018 at 14:17

2 Answers 2

1

You can try something like this:

<?php

$tags_array   = get_tags();
$news_query  = new WP_Query;

foreach ( $tags_array as $tags ) :
    $news_query->query( array(
        'cat'                 => $tags->term_id,
        'posts_per_page'      => 1,
        'no_found_rows'       => true,
        'ignore_sticky_posts' => true,
    ));

    ?>

    <h2><?php echo esc_html( $tags->name ) ?></h2>

    <?php while ( $news_query->have_posts() ) : $news_query->the_post() ?>

            <div class="post">
                <?php the_title() ?>
                <!-- do whatever you else you want that you can do in a normal loop -->
            </div>  

    <?php endwhile ?>

<?php endforeach ?>
1
  • 2
    I would avoid using ->query and create a new object each time, it avoids any "transference" or muddying from reusing the query object. Don't forget the reset post data call either, or the if statement to check if any posts were found. Otherwise this answer looks promising
    – Tom J Nowell
    Aug 28, 2018 at 14:19
-1

I think @Castiblanco has the right answer, with maybe a little tweaking? His solution should certainly work, but I would do it just a tiny bit differently, like this:

    <?php

    $tags_array   = get_tags();

    foreach ( $tags_array as $tags ) :
        $args( array(
        'cat'                 => $tags->term_id,
        'posts_per_page'      => 1,
        'no_found_rows'       => true,
        'ignore_sticky_posts' => true,
    ));
    query_posts($args);
    if (have_posts()) : 
    ?>

    <h2><?php echo esc_html( $tags->name ) ?></h2>

    <?php while (have_posts()) : the_post();  ?>

        <div class="post">
            <?php the_title() ?>
            <!-- do whatever you else you want that you can do in a normal loop -->
        </div>  

    <?php endwhile ?>

<?php endforeach ?>

The reason I'd do it this way is just to simplify the query and create a new object rather than using ->query also as previously noted be sure to reset postdata and if there are other loops on the page be sure to reset the query using wp_reset_query() after your endwhile.

2
  • Please don't use query_posts(), it's a bad idea, see this post to know why. So basically this doesn't improve anything. It only worsen an already bad solution. This is what the doc. says about it: "This function will completely override the main query and isn’t intended for use by plugins or themes".
    – Fayaz
    Aug 29, 2018 at 10:08
  • Thank you @Fayaz - that post was very helpful. My understanding was that the OP wanted to override the main query (or replace it), but even so it seems like new WP_Query is still the best way to go. Given that, it seems like it still makes sense to do the new query after getting the list of tags and separating them with the foreach.
    – Trisha
    Aug 30, 2018 at 16:30

Your Answer

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

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