Displaying custom post type by first letter through custom taxonomy

I’m trying to make a page on my WordPress website to display all kinds of food through 26 loops.

Every loop has to loop a letter of the alphabet, and on top of the page I have links that will link to the anchor boxes around the loops.

So what I want to be displayed is something like this:

NAV:

a b c d e …(and so on) … z

A

All items starting with the letter A

B

All items starting with the letter B

And so on..


After reading this topic: Display all posts starting with given letter? I decided to use diffrent terms for the letters.

For this I made a custom post type called ‘waaier’
In there I have a custom taxonomy called ‘waaier_abc’
And in there diffrent terms for each letter called ‘waaier_a’ , ‘waaier_b’ and so on

I think the most logical way to mage 26 loops beneath each other, because I want each letter in a diffrent div as well.

I tried this loop for it but it doesn’t display anything, also not the else statement..

<div class="waaier_a_object">
                    <?php query_posts(array('post_type' => 'waaier', 'waaier_abc' => $term->waaier_a ) ); ?>
                    <?php if ( have_posts() ) : while ( have_posts() ) : the_post(); ?>
                    <?php endwhile; else: ?>
                    <p><?php _e('Sorry, de letter a bevat nog geen inhoud.'); ?></p>
                    <?php endif; ?>
                </div>

Does anyone have an idea for an other loop too display terms from a certain post type OR to displaying posts with a certain first letter of a certain post type.

Sorry if my english is looking weird

Answers:

Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.

Method 1

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() . '" rel="nofollow noreferrer noopener">' . 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 . '" rel="nofollow noreferrer noopener">';
     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.


All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

0 0 votes
Article Rating
Subscribe
Notify of
guest

0 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
0
Would love your thoughts, please comment.x
()
x