Take the 2-minute tour ×
WordPress Development Stack Exchange is a question and answer site for WordPress developers and administrators. It's 100% free, no registration required.

In version 3.6.1 and below this worked. After updating WordPress to version 3.9.1, my category list is broken

In version 3.6.1, my category list looked like this

A|B|C

(A)    (B)    (C)
Apple  Bat    Cat

After upgrading to version 3.9.1, it looks like this

A|B|C

(A)    (B)    (C)
Apple  Apple  Apple
Bat    Bat    Bat
Cat    Cat    Cat

This is the code that worked in 3.6.1. Can anyone suggest a solution to make this work in version 3.9.1?

<?php 
$a = array('name__like' => "a", 'order' => 'ASC', 'title_li' => '0', 'use_desc_for_title' => '0');
$b = array('name__like' => "b", 'order' => 'ASC', 'title_li' => '0', 'use_desc_for_title' => '0');
?>
<div class="menu-alpha">
<ul>
<li><a href="#A">A</a></li>
<li><a href="#B">B</a></li>
</ul>
</div>


<div id="left-side">
<div class="alpha"><a name="A">A</a></div>
<ul>
<?php wp_list_categories($a); ?>
</ul>
<div class="alpha"><a name="B">B</a></div>
<ul>
<?php wp_list_categories($b); ?>
</ul>
share|improve this question

2 Answers 2

You are using wp_list_categories() function with the parameter name__like but this parameter is not valid for this function (I don't think your code works as you describe in WP 3.6+). You can use get_terms. For example:

 <?php

 function cyb_get_categories_list_name_like($letter) {

     $categories = get_terms( 'category', array('name__like' => $letter) ) ;

     $list = '';  

     if( !empty( $categories ) && !is_wp_error( $categories ) ) {

         $list = '<ul>';

         foreach( $categories as $cat ) {
              $list .= '<li><a href="'.get_term_link($cat).'">'.$cat->name.'</a></li>';
         }

         $list = '</ul>';

     }

     return $list;

 }

 <div class="menu-alpha">
      <ul>
           <li><a href="#A">A</a></li>
           <li><a href="#B">B</a></li>
      </ul>
 </div>

 <div id="left-side">
      <div class="alpha"><a name="A">A</a></div>
      <?php cyb_get_categories_list_name_like('a'); ?>
      <div class="alpha"><a name="B">B</a></div>
      <?php cyb_get_categories_list_name_like('b'); ?>
 </div>

 ?>

As Pieter Goosen pointed, it is need a filter to make the name__like parameter match only the first letter of the term:

 //Credit here @s_ha_dum
 function old_style_name_like_wpse_123298($clauses) {
      remove_filter('term_clauses','old_style_name_like_wpse_123298');
      $pattern = '|(name LIKE )\'%(.+%)\'|';
      $clauses['where'] = preg_replace($pattern,'$1 \'$2\'',$clauses['where']);
      return $clauses;
 }
 add_filter('terms_clauses','old_style_name_like_wpse_123298');
share|improve this answer
    
When you added this part $categories = get_terms( 'category', array('name__like' => $letter) ) ; where is says category do i add something there? Take note am still new at the whole WordPress code part. –  Constantino_A_ Jun 14 at 7:26
    
"category" is passed to get the terms from the "category" taxonomy, which is one of the Wordpress core taxonomies. –  cybmeta Jun 14 at 9:43

ANSWER REVISITED

I have just done the same type of answer on SO and took another route that is way faster than my original answer. I thought it would be nice to revisit this answer and post my new approach for benefit of this site.

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.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.