Question:

Output unique taxonomy terms of posts inside a loop

Sophia: 5 days ago

I'm trying to dynamically populate a dropdown list of taxonomy terms (state is the taxonomy used) of a custom post type (product) on a search form.

I can dynamically build the dropdown on it's own, but I'm trying to set it up so that if multiple products are tagged with the same state the state term will only appear once on the dropdown.

My code:

$state_tax_args = array(
    'post_type' =>  'products',
    'orderby'   =>  'name',
    'order'     =>  'ASC',
    'tax_query' => array(
        array(
            'taxonomy' => 'product-line',
            'field'    => 'slug',
            'terms'    => $pl_slug  //assigned at page start
        ),
    ),
);

$state_tax_query = new WP_Query( $state_tax_args );
$i=0;
if ( $state_tax_query->have_posts()) {
  $states = array();
  while ( $state_tax_query->have_posts()){ $state_tax_query->the_post();
    $state_terms = wp_get_post_terms( get_the_id(), 'state', array('orderby' => 'name', 'order' => 'ASC', 'fields' => 'all') );
    foreach($state_terms as $st){
        $term = get_term( $st );
        $states[$i] = $term->slug ;
        $i++;
    }   // end foreach
  } //  end while

  $state_results = array_unique($states);
  print_r($state_results);

} // end if
wp_reset_query();

For testing purposes, I'm just printing the array before actually implementing the dropdown build, but right now all that's being output is Array ( [0] => ).

Edit: To clarify a few things...

The data hierarchy on my site is as follows:

I have a custom post type of products that has three custom taxonomies attached to it: product-line, state, and carrier (insurance stuff, yay!). When I originally query the posts, I'm querying them by product-line, because the product-line term pages are where my search form lives.

Once I've queried the posts by product-line, I pull out their other two taxonomy terms (state and carrier) to dynamically create a dropdown for each so that if a carrier doesn't offer a product in that product-line, the carrier doesn't appear on the dropdown (and the same for state). Then, when a user searches for a product, the variables are passed (state and carrier from the form itself, and product-line from the page the search is executed from), the form is processed to build a query and return the results via AJAX.

Again, building the dropdowns works, but it outputs each term of carrier and state as many times as it appears on a product - I'm trying to make it output unique values, thus my confusion at the current Array ( [0] => ) output.

Answer:
Zoey: 5 days ago

Figured it out!

$state_tax_args = array(
    'post_type' =>  'products',
    'orderby'   =>  'name',
    'order'     =>  'ASC',
    'tax_query' => array(
        array(
            'taxonomy' => 'product-line',
            'field'    => 'slug',
            'terms'    => $pl_slug // provided at page load
        ),
    ),
);

$state_tax_query = new WP_Query( $state_tax_args );
// counter to build array
$i=0;

if ( $state_tax_query->have_posts()) {

  $state_term_list='<select class="form-control" id="inputStateSelect" placeholder="State" name="stateSelect">';
  $state_term_list.='<option value="">...</option>';

  $states = array();

  while ( $state_tax_query->have_posts()){ $state_tax_query->the_post();
    $state_terms = wp_get_post_terms( get_the_id(), 'state', $args = array('orderby' => 'name', 'order' => 'ASC', 'fields' => 'all'));
    foreach($state_terms as $state_term){
        $states[$i] = $state_term->name;
        $i++;
    } //  end foreach
  } //  end while

  //  kill the dupes
  $state_results = array_unique($states);

  //  alphebatize
  asort($state_results);

  //  build option list
  foreach($state_results as $state_result){
    $state_term_list.='<option value="' . $state_result . '">' . $state_result . '</option>';
  }

  $state_term_list.='</select>';

  echo $state_term_list;

} // end if
wp_reset_query();

That said, if I'm doing this just bonkers inefficiently, I'm always open to suggestions :)