My categories are basically authors, and I would like to create a function to list them according to their surname. For example I'd like to have something like:
E:
- Heinz Erhardt
- Albert Einstein
- Eminem
The problem is, I also have authors with only one name (like "Eminem") which I would also like to be sorted according to the letter E.
The only way I know of to do this in wordpress is with the get_terms
function and the name__like
.
function getAuthors(){
$args = array(
'name__like' => 'E',
);
return get_terms('category', $args );
}
this creates the sql query which only lists categories with an "E" in it:
AND t.name LIKE %E%;
I however need something like:
AND t.name NOT LIKE '% %' AND t.name LIKE E% OR t.name LIKE '% E';
I tried to change the code in the get_terms function in the core file where the query is set up (taxonomies.php, line 1809). However I wasn't successfull and I wouldn't like to change something in the core files.
How can I customize the query passed by the name__like
? Are there other better ways I can achieve my goal?
--- EDIT ---
I used TheDeadMedic's solution and was able to list categories according to a specific letter by using for example get_terms( 'my_taxonomy', 'surname=E' );
However this surname
argument doesn't work if I want to use the get_terms
function multiple times on one page (for example in a loop - if I'd like to create A-Z headings and display the according sorted categories below the headings).
Here's the function I'm trying to execute. The problem is that it just keeps listing the categorys for surname=A
under every heading.
function getAuthors()
{
$letters = range('A', 'Z'); // create Alphabet array
foreach ($letters as $letter) {
echo '<h4>' . $letter . '</h4>';
$args = array(
'surname' => $letter
);
$cats = get_terms('category', $args);
foreach ($cats as $cat) {
echo "<ul>";
echo "<li>" . $cat->name . "</li>";
echo "</ul>";
}
}
}
The name__like
argument seems to work in the loop though.
My categories are basically authors, and I would like to create a function to list them according to their surname. For example I'd like to have something like:
E:
- Heinz Erhardt
- Albert Einstein
- Eminem
The problem is, I also have authors with only one name (like "Eminem") which I would also like to be sorted according to the letter E.
The only way I know of to do this in wordpress is with the get_terms
function and the name__like
.
function getAuthors(){
$args = array(
'name__like' => 'E',
);
return get_terms('category', $args );
}
this creates the sql query which only lists categories with an "E" in it:
AND t.name LIKE %E%;
I however need something like:
AND t.name NOT LIKE '% %' AND t.name LIKE E% OR t.name LIKE '% E';
I tried to change the code in the get_terms function in the core file where the query is set up (taxonomies.php, line 1809). However I wasn't successfull and I wouldn't like to change something in the core files.
How can I customize the query passed by the name__like
? Are there other better ways I can achieve my goal?
--- EDIT ---
I used TheDeadMedic's solution and was able to list categories according to a specific letter by using for example get_terms( 'my_taxonomy', 'surname=E' );
However this surname
argument doesn't work if I want to use the get_terms
function multiple times on one page (for example in a loop - if I'd like to create A-Z headings and display the according sorted categories below the headings).
Here's the function I'm trying to execute. The problem is that it just keeps listing the categorys for surname=A
under every heading.
function getAuthors()
{
$letters = range('A', 'Z'); // create Alphabet array
foreach ($letters as $letter) {
echo '<h4>' . $letter . '</h4>';
$args = array(
'surname' => $letter
);
$cats = get_terms('category', $args);
foreach ($cats as $cat) {
echo "<ul>";
echo "<li>" . $cat->name . "</li>";
echo "</ul>";
}
}
}
The name__like
argument seems to work in the loop though.
- 3 FYI, you should never change any core files, not only because it makes the unicorns angry, but also because if an update is made all of your work goes away. – David Gard Commented Feb 18, 2015 at 11:55
2 Answers
Reset to default 5Use the terms_clauses
filter, which passes all the various components of the query (fields, join, where, orderby, order & limits), and implement your own "search" argument:
function wpse_178511_get_terms_fields( $clauses, $taxonomies, $args ) {
if ( ! empty( $args['surname'] ) ) {
global $wpdb;
$surname_like = $wpdb->esc_like( $args['surname'] );
if ( ! isset( $clauses['where'] ) )
$clauses['where'] = '1=1';
$clauses['where'] .= $wpdb->prepare( " AND t.name LIKE %s OR t.name LIKE %s", "$surname_like%", "% $surname_like%" );
}
return $clauses;
}
add_filter( 'terms_clauses', 'wpse_178511_get_terms_fields', 10, 3 );
Put in use:
get_terms( 'my_taxonomy', 'surname=E' );
look to this argument that get like in name
$get_terms_default_attributes = array (
'taxonomy' => 'category', //empty string(''), false, 0 don't work, and return empty array
'orderby' => 'name',
'order' => 'ASC',
'hide_empty' => true, //can be 1, '1' too
'include' => 'all', //empty string(''), false, 0 don't work, and return empty array
'exclude' => 'all', //empty string(''), false, 0 don't work, and return empty array
'exclude_tree' => 'all', //empty string(''), false, 0 don't work, and return empty array
'number' => false, //can be 0, '0', '' too
'offset' => '',
'fields' => 'all',
'name' => '',
'slug' => '',
'hierarchical' => true, //can be 1, '1' too
'search' => '',
//this part
'name__like' => '',
'description__like' => '',
'pad_counts' => false, //can be 0, '0', '' too
'get' => '',
'child_of' => false, //can be 0, '0', '' too
'childless' => false,
'cache_domain' => 'core',
'update_term_meta_cache' => true, //can be 1, '1' too
'meta_query' => '',
'meta_key' => array(),
'meta_value'=> '',
);