Displaying custom post type by first letter through custom taxonomy

What I can say on your code:

  • 26 loops are really a lot for a page, that page will load very
    slowly, unless you setup some cache
  • Please, do not use query_posts it is very
    poor performant when called once, 26 times is performance hell
  • If you set the taxonomy only to show this page, you do not need that that taxonomy at all

What I suggest:

Perform only one query using WP_Query instance

$args = array(
   'post_type' => 'waaier',
   'posts_per_page' => -1
);
$query = new WP_Query($args);

This query will return all the posts of waaier type.

After that you can start the loop saving all posts in a helper array to order them by letter just taking first letter fo the post:

$by_letter = array();
while( $query->have_posts() ) { $query->the_post();
  global $post;
  $letter = substr($post->post_name, 0, 1);
  if ( ! isset($by_letter[$letter]) ) $by_letter[$letter] = array();
  $by_letter[$letter][] = $post;
}
wp_reset_postdata();

After this loop, you will have the array $by_letter filled with the posts orderd by letters, so you can loop this array to show posts:

if ( ! empty( $by_letter ) ) {

  ksort($by_letter); // order the array

  // fill the array with letters have no posts
  $by_letter = fill_by_letter_array( $by_letter );

  display_letters_anchors( array_keys( $by_letter ) );

  foreach( $by_letter as $letter => $posts ) {
  ?>
    <div id="waaier_<?php echo $letter; ?>" class="waaier_<?php echo $letter; ?>_object">
    <?php
    if ( ! empty($posts) ) {
      foreach ( $posts as $post ) {
        setup_postdata($post);
        // just an example of post output
        echo '<p><a href="' . get_permalink() . '">' . get_the_title() . '</a></p>';
      }
    } else {
       echo '<p>' . __('Sorry, de letter a bevat nog geen inhoud.') . '</p>';
    }
    ?>
    </div>
  <?php
  }
  wp_reset_postdata();
}

In this code I’ve used the 2 functions display_letters_anchors and fill_by_letter_array, first to show the links to every letter div, second to fill the array for letters that have no posts.

That functions (can be putted in functions.php) should be something like:

function display_letters_anchors( $letters ) {
   if ( empty($letters) ) return;
   echo '<ul class="waaier_letters_list">';
   foreach ( $letters as $letter ) {
     echo '<li><a href="#waaier_' . $letter . '">';
     echo strtoupper($letter) . '</a></li>';
   }
   echo '</ul>';
}

function fill_by_letter_array( $by_letter ) {
  $keys = range('a', 'z');
  $values = array_fill(0, count($keys), array());
  $empty = array_combine($keys, $values);
  return wp_parse_args( $by_letter, $empty);
}

This is more performant: only one query instead of 26, and you do not need to setup the right taxonomy for the post letter, everything is done automatically.

Leave a Comment