0

I have CPT "Dealers" and a custom tax of "States" where each post in the CPT is associated to one state. The hope is to create the header for the state then list each post in that state taxonomy under it; and only show the state header if at least one post is associated with it.

All this does right now is display the STATE as the

h3 class="state"
tag and doesn't list the posts associated with the tax.

e.g.

STATE 1
STATE 2

It should be creating a div with the class of "dealer" for each post under the header of the state. e.g:

STATE 1
Post Title
Address
City, ST
800.555.1234
www.example.com

Post Title
Address
City, ST
800.555.1234
www.example.com

STATE 2
Post Title
Address
City, ST
800.555.1234
www.example.com

I'm using Advanced Custom Fields to call in the $street_address, etc. Here's the code I have right now.

Thoughts?

<?php
$states = get_terms( 'states' );
?>

<?php
foreach ( $states as $state ) {
    $state_query = new WP_Query( array( 
        'post_type' => 'dealers',
        'tax_query' => array(
             array(
                'taxonomy' => 'states',
                'field' => 'name',
                'terms' => $_GET['state'],
                'operator' => 'IN'
            )
        ) 
    ) );
?>
    <h3 class="state"><?php echo $state->name; ?></h3>
    <?php
    if ( $state_query->have_posts() ) : while ( $state_query->have_posts() ) : the_post(); 
        $id = get_the_ID();
        $street_address = get_field ('street_address', $id);
        $dealer_city = get_field ('dealer_city');
        $dealer_state = get_field ('dealer_state');
        $phone_number = get_field ('phone_number');
        $toll_free = get_field ('toll_free');
        $dealer_website = get_field ('dealer_website');

    ?>
        <div class="dealer">
            <h4 class="dealer_name"><?php the_title(); ?></h4>
            <p><?php echo $street_address; ?></p>
            <p><?php echo $dealer_city; ?>, <?php echo $dealer_state; ?></p>
            <?php if ( get_field('phone_number') ) { ?><p><?php echo $phone_number; ?></p><?php } ?>

        </div>

    <?php endwhile; endif; ?>

<?php 
wp_reset_postdata(); ?>

<?php } ?>

1 Answer 1

0

You are looping through all states and running a query on each iteration, but the query you are doing is nothing to do with the loop. You are checking for $_GET['state'], which would be the state passed over the query string.

 <?php
    foreach ( $states as $state ) {
        $state_query = new WP_Query( array( 
            'post_type' => 'dealers',
            'tax_query' => array(
                 array(
                    'taxonomy' => 'states',
                    'field' => 'name',
                    'terms' => $_GET['state'],
                    'operator' => 'IN'
                )
            ) 
        ) );
    ?>

So, you could just swap that out for $state - but then you still have a very inefficient method, as you're making 50 queries!

Instead, I would do a single query, then loop through the results, using get_the_terms( $post->ID, 'states' ) to get the state of every post. Instead of outputting directly, I would build an array. The following is very rough and untested:

    // start your loop here
  $states = get_the_terms( $post->ID, 'states' );
    $dealers[$states[0]->name][] = array(
        'dealer_name' => $post->post_title,
        'street_address' => get_field ('street_address', $post->ID),
        'dealer_city' => get_field ('dealer_city', $post->ID),
        // and so forth for all fields
    )
    // end your loop here

Only when that loop was complete and the array was built, would I then iterate through my new array to output the results. Something like:

<?php
$old_state = '';
foreach ( $dealers as $state => $dealer ) {
    if ( $state != $old_state ) {
        ?>
        <h3 class="state"><?php echo $state; ?></h3>
        <?php
        $old_state = $state;
    }
    ?>
    <div class="dealer">
        <h4 class="dealer_name"><?php the_title(); ?></h4>
        <p><?php echo $dealer['street_address']; ?></p>
        <p><?php echo $dealer['dealer_city']; ?></p>
        <!-- all the other fields... -->
    </div>
    <?
}
?>

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.