Remove Duplicate Term Names From Bricks Terms Query Loop

Updated on 2 Aug 2024

Consider this scenario:

CPT: Offer
Custom taxonomy: Offer Type

Sample offer types:

Output of Bricks terms query loop for the Offer Type taxonomy:

Remember that terms are ordered by name in ascending order by default.

This Pro tutorial shows how to exclude terms with duplicate names from a Bricks terms query while keeping the first occurrence of a term name and excluding any subsequent terms with the same name.

This can be useful when you want to ensure unique term names are displayed, perhaps to avoid confusion or to clean up the presentation of terms in a particular terms query loop.

After implementing the tutorial:

Step 1

Set up your terms query loop.

Step 2

Add the following in child theme‘s functions.php (w/o the opening PHP tag) or a code snippets plugin:

<?php

add_filter( 'bricks/terms/query_vars', function( array $query_vars, array $settings, string $element_id ): array {
    // Make sure we are targeting the correct terms query
    if ( $element_id !== 'qxtwkm' ) {
        return $query_vars;
    }

    // Get all terms for the taxonomy. Sample $query_vars: https://d.pr/i/88l3F0
    $taxonomy = isset( $query_vars['taxonomy'][0] ) ? $query_vars['taxonomy'][0] : 'category';

    $all_terms = get_terms( [
        'taxonomy' => $taxonomy,
        'hide_empty' => false,
    ] );

    if ( ! is_array( $all_terms ) || empty( $all_terms ) ) {
        return $query_vars;
    }

    // Create arrays to store term names, their corresponding IDs, and duplicates
    $term_names = [];
    $duplicate_ids = [];

    // Check for duplicate term names
    foreach ( $all_terms as $term ) {
        if ( isset( $term_names[$term->name] ) ) { // if the term name is already in $term_names array
            // This is a duplicate term name
            $duplicate_ids[] = $term->term_id;
        } else { // a new term name, add to $term_names array with the term name as the key and the term ID as the value
            $term_names[$term->name] = $term->term_id;
        }
    }

    // Add the duplicate term IDs to the exclude list
    if ( ! empty( $duplicate_ids ) ) {
        if ( isset( $query_vars['exclude'] ) && is_array( $query_vars['exclude'] ) ) { // not really needed but a good practice
            $query_vars['exclude'] = array_merge( $query_vars['exclude'], $duplicate_ids );
        } else {
            $query_vars['exclude'] = $duplicate_ids;
        }
    }

    return $query_vars;
}, 10, 3 );

Replace qxtwkm with the Bricks ID of the query loop-enabled element.

Update

If the terms query is nested inside a posts query, you want to limit the terms to terms of the current post being looped through. In this case replace

$all_terms = get_terms( [
    'taxonomy' => $taxonomy,
    'hide_empty' => false,
] );

with

$post_terms = get_the_terms( get_the_ID(), $taxonomy );

and change $all_terms to $post_terms in the foreach loop.