Creating a query that displays terms by letter, using a foreach

I am trying to create a query that displays all terms in a taxonomy by letter.

Here is the code I have so far, for a single letter:

Read More
<?php $args = array('name__like' => "a", 'order' => 'ASC');
    $terms = get_terms('pa_manufacturer', $args);
    if ( !empty( $terms ) && !is_wp_error( $terms ) ) {
        $count = count($terms);
        $i=0;
        $term_list = '<ul class="my_term-archive">';
        echo '<h2 class="term-letter">A</h2>';
        foreach ($terms as $term) {
            $i++;
            $term_list .= '<li><a href="' . get_term_link( $term ) . '" title="' . sprintf(__('View all post filed under %s', 'my_localization_domain'), $term->name) . '">' . $term->name . '</a></li>';
            if ($count != $i) {
                $term_list .= '';
            }
            else {
                $term_list .= '</ul>';
            }
        }
        echo $term_list;
    }
    ?>

The problem is that currently, I need to fill out the “name__like” part manually, along with the h2 term-letter.

I’d like to return each letter of the alphabet in one query, changing the name__like and h2 text dynamically.

Otherwise I’d need to do a query for each letter and have 25 of them which is not exactly efficient.

I haven’t had much luck doing this actually so I am hoping to get some advise or help.

Can anyone help out?

Thanks

Related posts

Leave a Reply

2 comments

  1. The name__like parameter of get_terms was changed in WordPress 3.7. It does not retrieve term names with a specified first letter anymore, but retrieves a term name if it has the specified letter any where in the name

    Also, if you are going to try to run your code 26 times, you are going to have issues with page load times

    Here is my approach and the test results

    Test results: 1 query in 0.01074 seconds.

    Test output: (Please note, my test site is in Afrikaans, all names is term names)

    enter image description here

    Here is the code that makes it happen

    $terms = get_terms('pa_manufacturer');
    
    if ( !empty( $terms ) && !is_wp_error( $terms ) ){    
    $term_list = [];    
    foreach ( $terms as $term ){
        $first_letter = strtoupper($term->name[0]);
        $term_list[$first_letter][] = $term;
    }
    unset($term);
    
    echo '<ul class="my_term-archive">';
    
        foreach ( $term_list as $key=>$value ) {
            echo '<h2 class="term-letter">' . $key . '</h2>';
    
            foreach ( $value as $term ) {
                echo '<li><a href="' . get_term_link( $term ) . '" title="' . sprintf(__('View all post filed under %s', 'my_localization_domain'), $term->name) . '">' . $term->name . '</a></li>';
            }
        }
    
    echo '</ul>';
    }
    

    HOW THE CODE WORKS

    The best approach here is to get all the terms in one go to avoid unnecessary db hits. You can now pass the result from get_terms through a foreach loop.

    Here you are going to resort your terms. First thing to do is to create a new array, $term_list, get the first letter of each term name, and then assign this letter as a key in the new array. The values for each key will hold an array of the term info

    This new array will ten be used to display term names under each letter as you can see in the image above.

  2. Try something like that (might need tweaking – written without testing)

      <?php $args = array('order' => 'ASC');
      $terms = get_terms('pa_manufacturer', $args);
      if ( !empty( $terms ) && !is_wp_error( $terms ) ) {
        $count = count($terms);
        $i=0;
        $term_list = '<ul class="my_term-archive">';
        $letter = "A";
    
        foreach ($terms as $term) {
            $i++;
    
            if($letter !== strtoupper($term->name[0]) {
             $letter= strtoupper($term->name[0]);
             echo "<h2 class="term-letter">{$letter}</h2>";
            }
            $term_list .= '<li><a href="' . get_term_link( $term ) . '" title="' . sprintf(__('View all post filed under %s', 'my_localization_domain'), $term->name) . '">' . $term->name . '</a></li>';
            if ($count != $i) {
                $term_list .= '';
            }
            else {
                $term_list .= '</ul>';
            }
        }
        echo $term_list;
    }
    ?>`