get_terms()
概述
get_terms() 是 WordPress 中用于检索指定分类法(taxonomy)或分类法列表中的术语(terms)的核心函数。它基于 WP_Term_Query 类构建,支持丰富的参数和过滤器,允许开发者自定义查询条件和输出格式。
关键要点
- 函数签名:get_terms( $args = array(), $deprecated = '' ),其中 $args 参数数组支持多种配置选项,如 taxonomy、hide_empty、orderby 等。
- 返回值:根据 $args['fields'] 的值,可能返回 WP_Term 对象数组、整数数组、字符串数组、计数字符串或 WP_Error 对象(当请求无效分类法时)。
- 参数传递:自 WordPress 4.5.0 起,推荐使用数组格式传递参数,taxonomy 应作为 $args 数组中的键值提供,例如 array( 'taxonomy' => 'post_tag', 'hide_empty' => false )。
- 过滤器:支持多个过滤器,包括 'get_terms'(过滤找到的术语)、'list_terms_exclusions'(过滤排除条件)和 'get_terms_orderby'(过滤 ORDER BY 子句),允许在查询前后进行自定义处理。
- 错误处理:如果请求的分类法无效,函数将返回 WP_Error 对象,开发者应检查返回值以避免错误。
- 向后兼容:支持旧版参数格式(第一个参数为 taxonomy 字符串或数组,第二个参数为 $args),但推荐使用新格式。
代码示例
$terms = get_terms( array(
'taxonomy' => 'post_tag',
'hide_empty' => false,
) );注意事项
- 默认情况下,hide_empty 为 true,只显示已分配给文章(posts)的术语;对于附件(attachments)等非文章对象,需设置 hide_empty 为 false 以显示所有术语。
- 在检查返回值时,应同时验证非空和非 WP_Error,例如 if ( ! empty( $terms ) && ! is_wp_error( $terms ) ),以确保代码健壮性。
- 自 WordPress 6.9 起,'include' 和 'exclude' 参数不再接受 'all' 作为值,应省略这些参数或使用其他有效值。
Retrieves the terms in a given taxonomy or list of taxonomies.
Description
You can fully inject any customizations to the query before it is sent, as well as control the output with a filter.
The return type varies depending on the value passed to $args['fields']. See WP_Term_Query::get_terms() for details. In all cases, a WP_Error object will be returned if an invalid taxonomy is requested.
The ‘get_terms’ filter will be called when the cache has the term and will pass the found term along with the array of $taxonomies and array of $args.
This filter is also called before the array of terms is passed and will pass the array of terms, along with the $taxonomies and $args.
The ‘list_terms_exclusions’ filter passes the compiled exclusions along with the $args.
The ‘get_terms_orderby’ filter passes the ORDER BY clause for the query along with the $args array.
Taxonomy or an array of taxonomies should be passed via the ‘taxonomy’ argument in the $args array:
$terms = get_terms( array(
'taxonomy' => 'post_tag',
'hide_empty' => false,
) );
Prior to 4.5.0, taxonomy was passed as the first parameter of get_terms().
{@internal The $deprecated parameter is parsed for backward compatibility only.}
Parameters
$argsarray|stringoptional-
Array or string of arguments. See WP_Term_Query::__construct() for information on accepted arguments.
Default:
array() $deprecatedarray|stringoptional-
Argument array, when using the legacy function parameter format.
If present, this parameter will be interpreted as$args, and the first function parameter will be parsed as a taxonomy or array of taxonomies.
Default empty.
Source
function get_terms( $args = array(), $deprecated = '' ) {
$term_query = new WP_Term_Query();
$defaults = array(
'suppress_filter' => false,
);
/*
* Legacy argument format ($taxonomy, $args) takes precedence.
*
* We detect legacy argument format by checking if
* (a) a second non-empty parameter is passed, or
* (b) the first parameter shares no keys with the default array (ie, it's a list of taxonomies)
*/
$_args = wp_parse_args( $args );
$key_intersect = array_intersect_key( $term_query->query_var_defaults, (array) $_args );
$do_legacy_args = $deprecated || empty( $key_intersect );
if ( $do_legacy_args ) {
$taxonomies = (array) $args;
$args = wp_parse_args( $deprecated, $defaults );
$args['taxonomy'] = $taxonomies;
} else {
$args = wp_parse_args( $args, $defaults );
if ( isset( $args['taxonomy'] ) ) {
$args['taxonomy'] = (array) $args['taxonomy'];
}
}
if ( ! empty( $args['taxonomy'] ) ) {
foreach ( $args['taxonomy'] as $taxonomy ) {
if ( ! taxonomy_exists( $taxonomy ) ) {
return new WP_Error( 'invalid_taxonomy', __( 'Invalid taxonomy.' ) );
}
}
}
// Don't pass suppress_filter to WP_Term_Query.
$suppress_filter = $args['suppress_filter'];
unset( $args['suppress_filter'] );
$terms = $term_query->query( $args );
// Count queries are not filtered, for legacy reasons.
if ( ! is_array( $terms ) ) {
return $terms;
}
if ( $suppress_filter ) {
return $terms;
}
/**
* Filters the found terms.
*
* @since 2.3.0
* @since 4.6.0 Added the `$term_query` parameter.
*
* @param array $terms Array of found terms.
* @param array|null $taxonomies An array of taxonomies if known.
* @param array $args An array of get_terms() arguments.
* @param WP_Term_Query $term_query The WP_Term_Query object.
*/
return apply_filters( 'get_terms', $terms, $term_query->query_vars['taxonomy'], $term_query->query_vars, $term_query );
}
Hooks
Changelog
| Version | Description |
|---|---|
| 4.8.0 | Introduced 'suppress_filter' parameter. |
| 4.5.0 | Changed the function signature so that the $args array can be provided as the first parameter.Introduced 'meta_key' and 'meta_value' parameters. Introduced the ability to order results by metadata. |
| 4.4.0 | Introduced the ability to pass 'term_id' as an alias of 'id' for the orderby parameter.Introduced the 'meta_query' and 'update_term_meta_cache' parameters. Converted to return a list of WP_Term objects. |
| 4.2.0 | Introduced 'name' and 'childless' parameters. |
| 2.3.0 | Introduced. |
Skip to note 26 content
kopernik1elfka
All get_terms attributes with default values:
(I try default from this article and it didn’t work. This works.)
$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' => '', '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'=> '', );Skip to note 27 content
ancawonka
As of WordPress 4.6.1, here’s the array that’s returned (to add to Leo’s helpful note above)
array(1) { [0]=> object(WP_Term) (11) { ["term_id"]=> //int ["name"]=> //string ["slug"]=> //string ["term_group"]=> //int ["term_taxonomy_id"]=> //int ["taxonomy"]=> //string ["description"]=> //string ["parent"]=> //int ["count"]=> // int ["filter"]=> //string ["meta"]=> array(0) { // presumably this would be some returned meta-data? } } }Skip to note 28 content
mitch827
If parent => 0 is passed, only top-level terms will be returned
$terms = get_terms( array( 'taxonomy' => 'tax_name', 'parent' => 0 ) );Skip to note 29 content
CdWritted
Get categories and subcategories by custom taxonomies:
$taxonomies = get_terms( array( 'taxonomy' => 'taxonomy_name', 'hide_empty' => false ) ); if ( !empty($taxonomies) ) : $output = '<select>'; foreach( $taxonomies as $category ) { if( $category->parent == 0 ) { $output.= '<optgroup label="'. esc_attr( $category->name ) .'">'; foreach( $taxonomies as $subcategory ) { if($subcategory->parent == $category->term_id) { $output.= '<option value="'. esc_attr( $subcategory->term_id ) .'"> '. esc_html( $subcategory->name ) .'</option>'; } } $output.='</optgroup>'; } } $output.='</select>'; echo $output; endif;Skip to note 30 content
Khoi Pro
Working with Advanced Custom Fields (field type: Taxonomy, output: Object) for filtering taxonomies.
Case: Create a filter with main categories defined by ACF field, and all another should belongs to *others*.
Solution:
// Define Featured Category IDs first $featured_category_ids = array(); // It must be output WP_Object $featured_categories = get_field('main_category_filters'); // Creating loop to insert IDs to array. foreach( $featured_categories as $cat ) { $featured_category_ids[] = $cat->term_id; } // Now, if Featured Categories are match, add their IDs via 'exclude' if( $featured_categories ) { $args = array( 'taxonomy' => 'event_cat', 'parent' => 0, 'exclude' => $featured_category_ids ); } else { // If no featured, just display all terms $args = array( 'taxonomy' => 'event_cat', 'parent' => 0 ); } // Starting query terms now $other_categories = get_terms($args);Skip to note 31 content
znowebdev
Get all post categories ordered by count.
String syntax:
$categories = get_terms( 'category', 'orderby=count&hide;_empty=0' );Array syntax:
$categories = get_terms( 'category', array( 'orderby' => 'count', 'hide_empty' => 0, ) );Get all the links categories:
$my_links_categories = get_terms( 'link_category', 'orderby=count&hide;_empty=0' );List all the terms in a custom taxonomy, without a link:
$terms = get_terms( 'my_taxonomy' ); if ( ! empty( $terms ) && ! is_wp_error( $terms ) ){ echo '<ul>'; foreach ( $terms as $term ) { echo '<li>' . $term->name . '</li>'; } echo '</ul>'; }List all the terms, with link to term archive, separated by an interpunct (·):
$args = array( 'hide_empty=0' ); $terms = get_terms( 'my_term', $args ); if ( ! empty( $terms ) && ! is_wp_error( $terms ) ) { $count = count( $terms ); $i = 0; $term_list = '<p class="my_term-archive">'; foreach ( $terms as $term ) { $i++; $term_list .= '<a href="' . esc_url( get_term_link( $term ) ) . '" alt="' . esc_attr( sprintf( __( 'View all post filed under %s', 'my_localization_domain' ), $term->name ) ) . '">' . $term->name . '</a>'; if ( $count != $i ) { $term_list .= ' · '; } else { $term_list .= '</p>'; } } echo $term_list; }Skip to note 32 content
Siobhan
Get all post categories ordered by count.
String syntax:
$categories = get_terms( 'category', 'orderby=count&hide;_empty=0' );Array syntax:
$categories = get_terms( 'category', array( 'orderby' => 'count', 'hide_empty' => 0 ) );Skip to note 33 content
Md Aminur Islam
Custom Taxonomy and Sub Category Lists.
Your can use this to create list table also.
$taxonomies = get_terms( array( 'taxonomy' => 'product_cat', //Custom taxonomy name 'hide_empty' => false ) ); if ( !empty($taxonomies) ) : foreach( $taxonomies as $category ) { if( $category->parent == 0 ) { //remove uncategorized from loop if( $category->slug == 'uncategorized' ){ continue; } //Parent category information echo esc_html__($category->name, 'text-domain'); echo esc_html__($category->description, 'text-domain'); echo esc_html__($category->slug, 'text-domain'); echo esc_html__($category->count, 'text-domain'); //Sub category information foreach( $taxonomies as $subcategory ) { if($subcategory->parent == $category->term_id) { echo esc_html__($subcategory->name, 'text-domain'); echo esc_html__($subcategory->description, 'text-domain'); echo esc_html__($subcategory->slug, 'text-domain'); echo esc_html__($subcategory->count, 'text-domain'); } } } } endif;Skip to note 34 content
rezapr2
List terms limit to those matching a specific metadata key and metadata value
$terms= get_terms( array( 'taxonomy' => 'taxonomy name', 'meta_key' => 'metadata key', 'meta_value' => 'metadata value' ) );Skip to note 35 content
ctousignant
Meta Query using a custom field, and then ordering using a different custom field.
$terms = get_terms( array( 'taxonomy' => 'tax_slug', 'hide_empty' => false, 'meta_query' => array( [ 'key' => 'meta_key_slug_1', 'value' => 'desired value to look for' ] ), 'meta_key' => 'meta_key_slug_2', 'orderby' => 'meta_key_slug_2' ) );Skip to note 36 content
Utsav Singh Rathour
Get list of terms that match a certain meta_key
$args = array( 'hide_empty' => false, 'meta_query' => array( array( 'key' => 'project_status', 'value' => 'New', 'compare' => '=' ) )); $projects = get_terms( 'Projects', $args );Skip to note 37 content
samjco
If `get_terms` doesnt works for some odd reason with custom taxonomy not showing registered, try using `WP_Term_Query`:
$term_query = new WP_Term_Query( array( 'taxonomy' => 'regions', // <-- Custom Taxonomy name.. 'orderby' => 'name', 'order' => 'ASC', 'child_of' => 0, 'parent' => 0, 'fields' => 'all', 'hide_empty' => false, ) ); // Show Array info echo '<pre>'; print_r( $term_query->terms ); echo '</pre>'; //Render html if ( ! empty( $term_query->terms ) ) { foreach ( $term_query->terms as $term ) { echo wp_kses_post( $term->name ) . ", "; echo esc_html( $term->term_id ) . ", "; echo esc_html( $term->slug ) . ", "; echo "<br>"; } } else { echo 'No term found.'; }Get all args from here: https://developer.wordpress.org/reference/classes/WP_Term_Query/__construct/
Skip to note 38 content
Esteban
If you want to `get_terms() ` by `post_type`, here’s a way to do it:
// First, get the post IDs $my_ids = get_posts( array( 'post_type' => 'my_post_type', 'posts_per_page' => -1, 'fields' => 'ids', ) ); // Then pass the the array of IDs to get_terms() $terms = get_terms( array( 'taxonomy' => 'my_taxonomy', 'object_ids' => $my_ids, 'hide_empty' => true, ) );Skip to note 39 content
kalor
Order by parent term ID – not documented, but also works.
$categories = get_terms( 'category', array( 'orderby' => 'parent', ) );Skip to note 40 content
ramon fincken
As per https://core.trac.wordpress.org/ticket/41813 if you use this to in combination with a custom taxonomy which is used for media/attachments. You may find that all works well except the count of the terms when using get_terms ( which returns nothing ).
To fix this you may need to use this call in register_taxonomy
'update_count_callback' => '_update_generic_term_count',( https://core.trac.wordpress.org/ticket/41813#comment:8 )
Skip to note 41 content
Habib
Get All Terms id and name in a array for make dropdown select:
function custom_get_term_lit( $taxonomy = 'category' ) { $terms = get_terms( [ 'taxonomy' => $taxonomy, 'hide_empty' => false, ] ); if ( ! empty( $terms ) && ! is_wp_error( $terms ) ) { return wp_list_pluck( $terms, 'name', 'term_id' ); } return false; } $category = custom_get_term_lit('custom-taxonomy-id'); echo "<select name='category' id='category-dropdown'>"; foreach ( $category as $cat_id => $cat_name ) { echo "<option value='" . esc_attr( $cat_id ) . "'>" . esc_html__( $cat_name, 'text-domain' ) . "</option>"; } echo "</select>";Skip to note 42 content
elnajar1
list categories( or custom taxonomy ) and subcategory in organazid way
//parent category (then child(category) and subchild, then posts in each category ) $parent_ID = 0; //-level_one_clilds- $level_one_clilds = get_terms( array( 'taxonomy' => 'lecture_category', 'parent' => $parent_ID , 'depth' => 1, 'hide_empty' => false ) ); foreach( $level_one_clilds as $level_one_clild ): echo $level_one_clild->name . "<hr>" ; //--level_tow_clilds-- $level_tow_clilds = get_terms( array( 'taxonomy' => 'lecture_category', 'parent' => $level_one_clild->term_id, 'depth' => 1, 'hide_empty' => false )); foreach( $level_tow_clilds as $level_tow_clild ): echo "- " . $level_tow_clild->name . "<hr>" ; //---level_three_clild --- $level_three_clilds = get_terms( array( 'taxonomy' => 'lecture_category', 'parent' => $level_tow_clild->term_id, 'depth' => 1, 'hide_empty' => false )); foreach( $level_three_clilds as $level_three_clild ): echo "-- " . $level_three_clild->name . "<hr>" ; endforeach ; //level_three_clild endforeach ; //level_tow_clild endforeach ; //level_one_clildsSkip to note 43 content
rottenschnitzel
If you have a term assigned to something else than a post, here is a warning:
'hide_empty'is default true so it only shows terms assigned to posts. So if you get an empty Array returned be aware that terms (e.g. categories) assigned to attachments for example are not shown by default unless you use'hide_empty' => false:$wpdocs_categories = get_terms( array( 'taxonomy' => 'category', 'hide_empty' => false, 'name__like' => 'foo' ) );Skip to note 44 content
princeofabyss
Be very careful as the code below:
$terms = get_terms( array( 'taxonomy' => 'class_languages', 'hide_empty' => false, ) );can return valid terms, but can also return a
WP_Errorif, for example, the taxonomy is invalid…Therefore this check alone isn’t enough to save you from bugs in your code:
if ( ! empty( $terms ) ) { // whatever code }Instead, better to use the one below:
if ( ! empty( $terms ) && ! is_wp_error( $terms ) ) { // whatever code }Skip to note 45 content
jon
Categories and Tags are the two pre-defined Taxonomies. The Taxonomy Name, when included as an element ‘taxonomy’ of the array specified as the first parameter $args, has a value of ‘category’ for Categories and ‘post_tag’ for Tags.
'taxonomy' => 'category'<br />'taxonomy' => 'post_tag'
Skip to note 46 content
tonydjukic
Using ‘include’ => ‘all’ worked through to version 6.8.3, you could apply that argument and still get the correct results returned, however as of version 6.9 ‘all’ isn’t accepted as a value for the ‘include’ and ‘exclude’ arguments.
$authors = get_terms( array( 'taxonomy' => 'book_authors', 'hide_empty' => false, 'orderby' => 'ID', 'include' => 'all' ) ); //returns empty array</p><p>$authors = get_terms( array( 'taxonomy' => 'book_authors', 'hide_empty' => false, 'orderby' => 'ID' ) ); //returns all terms
Skip to note 47 content
Marco
Loop through taxonomy and list all subcategories.
$taxonomy = 'my_taxonomy'; function listTaxonomies($taxonomy,$term_id = '0') { $output = ''; $args = array( 'taxonomy' => $taxonomy, 'parent' => $term_id ); $categories = get_terms($args); if($categories) { $output.= '<div style="padding-left:2em;">'; foreach( $categories as $category ) { $output.= esc_attr( $category->name ) . ' (' . $category->slug . ')<br>'; $output.= listTaxonomies($taxonomy,$category->term_id); } $output.= '</div>'; } return $output; } listTaxonomies($taxonomy);Skip to note 48 content
Mehedi Foysal
Get all child taxonomy of a parent taxonomy
function get_child_taxonomies( $taxonomy_name, $termId, $args = array() ) { $defaults = array( 'taxonomy' => $taxonomy_name, 'orderby' => 'name', 'order' => 'ASC', 'hide_empty' => true, 'child_of' => $termId, ); $args = wp_parse_args( $args, $defaults ); $taxonomies = get_terms( $args ); if ( empty( $taxonomies ) || is_wp_error( $taxonomies ) ) { return false; } return $taxonomies; }Skip to note 49 content
Ulugov
Get Terms filtered by first letter
$authors = get_terms('book-authors', array('name__like' => $first_l)); function custom_tax_query( $pieces, $taxonomies, $args ) { if ( 'book-authors' == $taxonomies[0] ) { $pieces['where'] = str_replace("LIKE '%", "LIKE '", $pieces['where']); } return $pieces; }Skip to note 50 content
Asgaros
Get terms ordered by value of meta-key:
$terms = get_terms( 'taxonomy_name', array( 'meta_key' => 'custom_meta_key', 'orderby' => 'custom_meta_key' ) );