Search code examples
phploopswordpress-theming

Looping through taxonomy items within $query is combining terms from each post


The issue can be seen here on the Approach page.

Under each Current Research Focus there's a list of Researchers, Partners and Funders. Each of these is a custom taxonomy that is being looped through to display the associated names for each custom post. Researchers and Partners seem to be fine, but Funders seems to add the results from every Current Research item on the page. So by the time you get to the last Current Research item, it's got a list of every funder from all the Current Research items before it.

The loops for Researchers, Partners and Funders are the same, but the results are the different. I assume this is the result of my lack of experience with php. What could be going on?

Here's my code for the results portion of the page:

while ($query->have_posts())
    {
            $query->the_post();

            global $post;
            $topic = wp_get_object_terms( $post->ID, 'topic', array('taxonomy' => 'topic') );
            ?>

            <div class="current-research-container">
                <div class="current-research-body">
                    <div class="current-research-header">
                        <h5 class="current-research-focus">current research focus</h5>
                        <div class="current-research-topics-container">
                            <?php
                            foreach($topic as $topics) {
                                $color = get_field('topic-color', 'topic' . '_' . $topics->term_id);
                                echo '<a class="current-research-button" style="border-color:' . $color . ';"href="' . get_category_link($topics->term_id) . '">' . $topics->name . '</a>';
                            }  ?>
                        </div>

                    </div>
                        <h4><?php the_title(); ?></h4>
                        <p class="current-research-bio"><?php echo get_field('research_text'); ?></p>

                        <?php
                        $terms_author = get_the_terms( $post->ID, 'authors' );

                        if ($terms_author) {
                            $terms_author_str = array();
                            echo '<p class="taxonomy-data"><strong>Researchers </strong>';
                                foreach($terms_author as $term_author) {
                                    $terms_author_str[] = $term_author->name;
                                }
                            echo implode(", ",$terms_author_str);
                        }

                        $terms_partner = get_the_terms( $post->ID, 'partners' );

                        if ($terms_partner) {
                            $terms_partner_str = array();
                            echo '<p class="taxonomy-data"><strong>Partners </strong>';
                                foreach($terms_partner as $term_partner) {
                                    $terms_partner_str[] = $term_partner->name;
                                }
                                echo implode(", ",$terms_partner_str);
                        }

                        $terms_funder = get_the_terms( $post->ID, 'funders' );

                        if ($terms_funder) {
                            echo '<p class="taxonomy-data"><strong>Funders </strong>';
                                foreach($terms_funder as $term_funder) {
                                    $terms_funder_str[] = $term_funder->name;
                                }
                                echo implode(", ",$terms_funder_str);
                        } ?>

                    </div>
                <?php $image = get_field('current-research-image');


                if( !empty( $image ) ): ?>
                <div class="current-research-inner-right current-research-image-container">
                    <div class="img-ratio-box img-treatment">
                     <div class="img-ratio-box-inside">
                            <img class="" src="<?php echo esc_url($image['url']); ?>">
                     </div>
                    </div>
                </div>
                <?php endif; ?>
            </div>
        <?php
    }

Solution

  • As noted in the comment, the $terms_funder_str just needs to be reset on each loop iteration using $terms_funder_str = [].

    However, if you wanted to guard against this type of change in the future you could introduce an array and loop over things:

    $taxonomies = [
        'authors' => 'Researchers',
        'partners' => 'Partners',
        'funders' => 'Funders',
    ];
    
    foreach ($taxonomies as $taxonomy => $displayName) {
        if ($terms = get_the_terms($post->ID, $taxonomy)) {
            $termNames = [];
            echo '<p class="taxonomy-data"><strong>'.esc_html($displayName).'</strong>';
            foreach ($terms as $term) {
                $termNames[] = $term->name;
            }
            esc_html_e(implode(', ', $termNames));
        }
    }
    

    Also, although I'm not personally a big fan of this (for no good reason, to be clear), you can remove your loop and switch it over to wp_list_pluck which makes the code even shorter.

    $taxonomies = [
        'authors' => 'Researchers',
        'partners' => 'Partners',
        'funders' => 'Funders',
    ];
    
    foreach ($taxonomies as $taxonomy => $displayName) {
        if ($terms = get_the_terms($post->ID, $taxonomy)) {
            echo '<p class="taxonomy-data"><strong>'.esc_html($displayName).'</strong>';
            esc_html_e(implode(', ', wp_list_pluck($terms, 'name')));
        }
    }