User_FTW
User_FTW

Reputation: 524

Don't return duplicate title in WordPress loop

I have this standard loop for returning titles of a custom post type:

    <ul>
    <?php 
        $args = array(
        'post_type'         => 'food_types',
        'posts_per_page'    => -1
        );
        $query = new WP_Query($args);
        while ($query->have_posts()) : $query->the_post(); ?>
        <li><?php echo the_title();?></li>
        <?php endwhile;
        wp_reset_postdata();
    ?>
    </ul>

The problem is that there are often posts with the same title.

I need my loop modified so that there is only one instance of any given post title returned in the loop.

For example, if there are posts with these titles...

Tomato
Orange
Orange
Apple
Apple
Egg
Banana
Banana

...then the loop should only return this:

Tomato
Orange
Apple
Egg
Banana

I hope that makes sense.

Upvotes: 2

Views: 2060

Answers (3)

Dan
Dan

Reputation: 987

If you are only worried about fruit names, it may make sense to create a separate data set for it and not even bother looping all posts and removes the burden of tracking names inside the loop.

Edit: It makes sense to move this functionality into a function so you can easily reuse it anywhere.

// functions.php
function getFruits() {
    $query = new WP_Query([
        'post_type'       => 'food_types',
        'posts_per_page'  => -1
    ]);

    // When to use wp_reset_postdata(): https://wordpress.stackexchange.com/a/144344/145214
    wp_reset_postdata();

    // Extracts out just post_titles and makes new array
    $fruits = array_column( $query->posts, 'post_title'); // PHP7+

    // Gets unique values
    $fruits = array_unique( $fruits );

    return $fruits;
}

// template
$fruits = getFruits();

// Then all you have to do is loop that list
foreach($fruits as $fruit) : ?>

    <li>
        <?= $fruit ?>
    </li>

<?php endforeach;

Upvotes: 2

D.B.
D.B.

Reputation: 1782

Is duplication in the database ok, if not, then you might want to run a script to remove duplicates, as it can result in a performance hit.

If there are not too many items in the list, then a quick solution for your current code could simply to add each title to an array, and then continue the while loop if the item was previously added.

Use: https://www.php.net/manual/en/function.array-push.php and https://www.php.net/manual/en/function.in-array.php

So something like this.. NB: this is just in concept... I did not test the code.:

<ul>
<?php 
    $args = array(
    'post_type'         => 'food_types',
    'posts_per_page'    => -1
    );
    $query = new WP_Query($args);
    $list = array();
    while ($query->have_posts()) : $query->the_post(); 
    if(in_array(get_the_title(), $list)){ continue; }
    $list[] = get_the_title();
    ?>
    <li><?php echo get_the_title();?></li>
    <?php endwhile;
    wp_reset_postdata();
?>
</ul>

*Modified to use get_the_title() as you explained in comments

Upvotes: 0

Jaydip Nimavat
Jaydip Nimavat

Reputation: 649

the_title() does not require to echo. check:

<ul>
    <?php 
    $args = array(
        'post_type'         => 'food_types',
        'posts_per_page'    => -1
    );

    $query = new WP_Query($args);
    while( $query->have_posts() ) : $query->the_post(); ?>
        <li><?php the_title();?></li>
    <?php endwhile;
     wp_reset_postdata(); ?>
</ul>

Upvotes: 0

Related Questions