1

I'm trying to use a custom field of "State" to list all the city pages for available locations. I'm able to get the right results, in the (alphabetical by state) right order with this code:

<?php
            // query
            $the_query = new WP_Query(array(
                'post_type'         => 'page',
                'posts_per_page'    => -1,
                'meta_key'          => 'state_full',
                'orderby'           => 'meta_value',
                'order'             => 'ASC'
            ));

        ?>
        <?php if( $the_query->have_posts() ): ?>
        <ul> 
            <?php
                while( $the_query->have_posts() ) : $the_query->the_post(); 

                       $state = get_field('state_full');

            ?>
            <?php echo $state ?>
            <li>
                <a href="<?php the_permalink(); ?>"><?php the_title(); ?></a>
            </li>
            <?php endwhile; ?>
        </ul>
        <?php endif; ?>

But the content shows up like

  • STATE A City A
  • STATE A City B
  • STATE A City C

When I want

  • STATE A
  • City A
  • City B
  • City C

I've seen similar questions on StackExchange but haven't been able to translate those answers to what I need, since my PHP skills are very limited. Still, if this question has been adequately answered elsewhere, my apologies.

I can't change the URLs for the location pages or change the templates of the pages, and they are all first-level pages without children.

0

What you want to do is create a variable that keeps track of the 'current' state, then for each post in the loop check if its state is the same as the current state. If it is not then output it and update the current state to the new state. This will have the effect of only outputting the state name in front of the first post with that state.

if ( $the_query->have_posts() ) :
    /**
     * Create the variable to keep track of the current State in the loop.
     */
    $current_state = null;

    echo '<ul>';
        while( $the_query->have_posts() ) : $the_query->the_post();
            $state = get_field( 'state_full' );

            /**
             * If the state of the current post is different to the current state
             * then output the new state and update the current state.
             */
            if ( $state !== $current_state ) {
                echo '<li><strong>' . $state . '</strong></li>';
                $current_state = $state;
            }

            echo '<li><a href="' . get_the_permalink() . '">' . get_the_title() .  '</a></li>';
        endwhile;
    echo '</ul>';
endif;

I tweaked your code a little bit so it's pure PHP without opening and closing tags, but that's just because it makes it a bit easier to see the logic of the changes I made. You can output the markup however you like.

  • I'm now running into an issue where the provided code allows any page containing the fields to show up in the list, even when the field is empty. Essentially, if I save a page that has the custom field available, it gets added to the list. Do you know where I could put an "if not empty" equivalent in this code? – hellosisyphus Aug 2 '18 at 20:25

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.