Get the first letter of taxonomy and display only if it is a new letter

393 views Asked by At

I am trying to build an alphabet index of my taxonomies. I am pulling the first letter of the term and displaying it on the page. However, I only want the first letter to display if it is a new letter. So that I can group all the a's together and then the b's and so on. I thought I could do this use a post counts, but it only works for the first and second post. Any additional posts outputs the first letter. Any help would be greatly appreciated thanks!

$post_type = 'book';

// Get all the taxonomies for this post type
$taxonomies = get_object_taxonomies( array( 'post_type' => $post_type ) 
);

foreach( $taxonomies as $taxonomy ) :

 // Gets every "category" (term) in this taxonomy to get the respective 
    posts

    $terms = get_terms( $taxonomy );
    $count = 0;

    foreach( $terms as $term ) :
            $count++;
    $current_letter = '';
    if ($count == 1) :
    $title_letter1 = strtoupper(substr($term->name,0,1));
    if ($title_letter1 != $current_letter) {
    echo "<h3>$title_letter1</h3>";
    $current_letter = $title_letter1;
    }
    ?>
    <?php echo $term->name; ?>

    <?php elseif ($count >= 2) :
    $title_letter2 = strtoupper(substr($term->name,0,1));
    if ($title_letter2 != $title_letter1 and $title_letter2 != 
    $current_letter ) {
    echo "<h2>$title_letter2 </h2>";
    $current_letter = $title_letter2;
    }?>
    <?php echo $term->name; ?></div>

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

There are 1 answers

0
FluffyKitten On

The main problem is that you are resetting the $current_letter for every new term, so you are losing the value when you are trying to check for it in this line. You need to move it outside the foreach loop - see code below.

The rest of the code is probably working, but its hard to tell especially with the if ($title_letter2 != $title_letter1 and $title_letter2 != $current_letter ) conditional check. Just a tip on writing your code so its easier to debug: Basically less is better :-) because its easier to change and easier to debug because there are fewer things to go wrong!

You can simplify the code to remove repetition and unnecessary variables that introduce the need for additional checks:

foreach( $taxonomies as $taxonomy ) :

    $terms = get_terms( $taxonomy );
    $count = 0;
    $current_letter = ''; // move this outside of the loop so you don't reset it every time

    foreach( $terms as $term )
        $count++;

        // you need to do this regardless of the count, so just do it once here
        $title_letter = strtoupper(substr($term->name,0,1));

        if ($count == 1):
            if ($title_letter != $current_letter) 
                echo "<h3>$title_letter</h3>";

        elseif ($count >= 2):
            if ($title_letter != $current_letter ) 
                echo "<h2>$title_letter </h2>";
        endif;

        // you need to do this regardless of the count, so just do it once here
        $current_letter = $title_letter;
        echo $term->name;

    endforeach;

endforeach;

Notes:

  • You also don't need 2 separate variables for the letter - in fact, including a 2nd variable means that you had to add an extra check in your if statement in count >=2
  • Its also good practice not to repeat what you are doing (its called the DRY principle in programming - Don't Repeat Yourself). For example, the code under count==1 and count >=2 is doing exactly the same thing except for how it is displaying the letter.

I hope it doesn't sound like I'm criticising your existing code because I'm not, but I needed to simplify it just to see what was wrong, and is was much easier to do when there was less code needed to do the same thing!

Getting in the habit of using the DRY & KISS Software principles principles might help you (or us!) with troubleshooting any future problems you might post.

Hope this helps :)