0

I am trying to output a list of stockists in two columns from left to right, sorted alphabetically:

A | B

C | D

E | F

G | H

Currently, the code below is sorting half the posts alphabeticly and then starting half way through with the rest alphabeticly:

A | C

E | G

B | D

F | H

Any idea on where I am going wrong?

<?php 
query_posts(  array( 'order' => 'ASC' , 'orderby' => 'title' , 'posts_per_page' => -1 , 'post_type' => 'stockist_directory', 'regions' => 'metropolitan' ) );
if (have_posts()) : while(have_posts()) : $i++; if(($i % 2) == 0) : $wp_query->next_post(); else : the_post(); ?>

<div id="left-column">
<h1><?php the_title(); ?></h1>
  <?php the_field('shop_address'); ?><br/>
  <?php the_field('suburb'); ?>, <?php the_field('postcode'); ?><br/>
  Phone: <?php the_field('phone_number'); ?><br/>
  <a href="<?php the_field('website_address'); ?>">Website</a>
</div>

<?php endif; endwhile; else: ?>
<?php endif; ?>

<?php $i = 0; rewind_posts(); ?>

<?php if (have_posts()) : while(have_posts()) : $i++; if(($i % 2) !== 0) : $wp_query->next_post(); else : the_post(); ?>

<div id="right-column">

<h1><?php the_title(); ?></h1>
  <?php the_field('shop_address'); ?><br/>
  <?php the_field('suburb'); ?>, <?php the_field('postcode'); ?><br/>
  Phone: <?php the_field('phone_number'); ?><br/>
  <a href="<?php the_field('website_address'); ?>">Website</a>
  </div>
<?php endif; endwhile; else: ?>

<?php endif; ?>
1

Regarding the use of query_posts, as @epilektric said never use it. Use WP_Query instead.

Another consideration is to keep your code DRY.

What I suggest you is:

  1. Run the loop one time, and put the posts in a helper array, using 2 keys one for even one for odd.
  2. Cycle that array and output the markup with a function.

Example:

function post_data_output( $post ) {
  the_field('shop_address', $post->ID );
  echo get_field('suburb', $post->ID) . ','. get_field('postcode', $post->ID) . '<br/>';
  echo 'Phone:' . get_field('phone_number', $post->ID) . '<br/>';
  echo '<a href="' . get_field('website_address', $post->ID). '">Website</a>';
}

$args = array( 'order' => 'ASC' , 'orderby' => 'title' , 'posts_per_page' => -1 , 'post_type' => 'stockist_directory', 'regions' => 'metropolitan' );

$query = new WP_Query($args);

if ($query->have_posts()) :
  $ordered = array('even' => array(), 'odd' => array());
  while($query->have_posts()) : $query->the_post();
    global $post;
    $key =  ( $query->current_post % 2 == 0) ? 'even' : 'odd';
    $ordered[$key][] = $post;
  endwhile;
  wp_reset_postdata();
  echo '<div id="left-column">';
  if ( ! empty($ordered['odd']) ) { foreach( $ordered['odd'] as $apost ) {
    post_data_output($apost);
  } }
  echo '</div>';
  echo '<div id="right-column">';
  foreach( $ordered['even'] as $apost ) {
    post_data_output($apost);
  }
  echo '</div>';
endif;
  • Yes, a helper array! That's exactly what I was thinking if I were to adjust my answer to one div each. – epilektric Aug 20 '13 at 19:17
  • This works perfectly! Now just finishing the code of and want to add this - <br/> if( in_array( 'one', get_field('product_list') ) )echo '<img src="../images/one.png">' ; if( in_array( 'two', get_field('product_list') ) ) echo '<img src="../images/two.png">' ; if( in_array( 'three', get_field('product_list') ) ) echo '<img src="../images/three.png">' ; <br/> Where should I add it as if I had it in with the post_data_output it shows all three options when it should only show the selected. – user36867 Aug 21 '13 at 11:21
  • Never use relative urls for the images <img src="../images/three.png">' use instead <img src="<?php get_template_directory_uri(); ?>/images/three.png">'. After that, you have to put the $post->ID in the get_field function inside post_data_output: if( in_array( 'one', get_field('product_list', $post->ID) ) ) echo '<img src="' . get_template_directory_uri() . '/images/one.png">' @user36867 – gmazzap Aug 21 '13 at 11:42
1

That seems overly complex to sort the posts into columns. You should be able to achieve the results you want with a some simple logic.

  1. Get the index of the current post.
  2. Check the result of the modulus operator applied to the index.
  3. Assign the appropriate column class based on the modulus result.
<?php if (have_posts()) : ?>
    <?php while(have_posts()) : the_post();

        if ($wp_query->current_post % 2) {
            $column_class='left-column';
        } else {
            $column_class='right-column';
        }
    ?>

        <div id="<?php echo $column_class; ?>">
            <!-- your content goes here -->
            <h1><?php the_title(); ?></h1>
        </div>

    <?php endwhile; else: ?>

    <!-- no posts to display -->

<?php endif; ?>

Other Considerations

You should also consider not using query_posts(). The following adjustments should provide the same result.

Switch query_posts() for WP_Query.

$query = new WP_Query(  array( 'order' => 'ASC' , 'orderby' => 'title' , 'posts_per_page' => -1 , 'post_type' => 'stockist_directory', 'regions' => 'metropolitan' ) );

Then adjust The Loop to use $query. Also note that $wp_query->current_post has changed to $query->current_post.

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

        if ($query->current_post % 2) {
            $column_class='left-column';
        } else {
            $column_class='right-column';
        }
    ?>

After the loop reset the post data like this.

<?php wp_reset_postdata(); ?>
  • 1
    Your code output <div id="left-column"> and <div id="right-column"> a lot of times, OP want output one time each. – gmazzap Aug 20 '13 at 17:55
  • True, but based on the example A|B, C|D, ... I interpreted that to mean multiple times each. I may be wrong. – epilektric Aug 20 '13 at 18:03
  • Yes, @epilektric, the question text is a bit confusing, but I think code is clear. – gmazzap Aug 20 '13 at 18: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.