get_categories()WP 2.1.0

Gets categories as an array of objects.

What criteria to get the categories and how to sort them is specified in the parameters of the function.

The parameters passed to this function are very similar to those of wp_list_categories(). They can also be passed as an array or a query string: type=post&order=DESC.

1 time — 0.005625 sec (very slow) | 50000 times — 11.98 sec (slow) | PHP 7.1.11, WP 4.9.5
Hooks from the function



  • Array of WP_Term (categories) objects.
  • Empty array if no categories could be obtained.
	[0] => WP_Term Object
			[term_id] => 7
			[name] => Codex
			[slug] => codex
			[term_group] => 0
			[term_taxonomy_id] => 7
			[taxonomy] => category
			[description] =>
			[parent] => 3
			[count] => 17
			[filter] => raw
			[term_order] => 1
			[cat_ID] => 7
			[category_count] => 17
			[category_description] =>
			[cat_name] => Codex
			[category_nicename] => codex
			[category_parent] => 3

	[1] => WP_Term Object ( ... )

Usage Template

$categories = get_categories( [
	'taxonomy'     => 'category',
	'type'         => 'post',
	'child_of'     => 0,
	'parent'       => '',
	'orderby'      => 'name',
	'order'        => 'ASC',
	'hide_empty'   => 1,
	'hierarchical' => 1,
	'exclude'      => '',
	'include'      => '',
	'number'       => 0,
	'pad_counts'   => false,
	// full list of params:
] );

if( $categories ){
	foreach( $categories as $cat ){

		// $cat->term_id
		// $cat->name (Category 1)
		// $cat->slug (category-1)
		// $cat->term_group (0)
		// $cat->term_taxonomy_id (4)
		// $cat->taxonomy (category)
		// $cat->description (text)
		// $cat->parent (0)
		// $cat->count (14)

		// And aliases:
		// $cat->object_id (2743)
		// $cat->cat_ID (4)
		// $cat->category_count (14)
		// $cat->category_description (text)
		// $cat->cat_name (Category 1)
		// $cat->category_nicename (category-1)
		// $cat->category_parent (0)



get_categories( $args );

Arguments to retrieve categories. For a complete list of parameters, see WP_Term_Query::__construct().

Default: '' - presets

Arguments of $args

For a complete list of parameters, see the WP_Term_Query::__construct() method.

taxonomy(string/array) (required)
The name of the taxonomy to work with. You can specify multiple names as an array. Since WP 4.5, the taxonomies names passes to the first parameter of the function.
The maximum number of items that will be received. Limit.
Default: all.

Specify here a number or an array of numbers to get the terms whose object_id field of the wp_term_relationships table matches the specified values.

Usually, the object_id field contains the ID of the posts to which the term is attached.

An array of terms IDs to be included in the selection. When this parameter is specified, many others become useless. The value is passed through wp_parse_id_list().
Default: ''
An array of terms IDs that need to be excluded. You can also specify a comma-separated string of ids. The value is passed through
Default: ''
An array of parent terms IDs tree of which need to be excluded. The entire branch will be excluded. The value is passed through wp_parse_id_list().
Default: ''
Top indent in the SQL request — how many first rows to skip. You need to specify a number.
Default: 0

The field by which to sort the result. Can be:

  • id or term_id - by ID.
  • name - by name. By default.
  • count - by the term_taxonomy table count field - by the number of posts.
  • slug - by an alternative name.
  • description - by description.
  • term_group - by thr group.
  • parent - by the parent field.
  • include - by the order specified in the $include parameter.
  • slug__in - by the order specified in the $slug parameter. Since WP 4.9.
  • meta_value - by the value of the custom field.
  • meta_value_num - by the value of the custom field (the value will be interpreted as a number rather than a string).
  • key of "meta_query" - in the $meta_query parameter we specify parameters for custom fields query. Also we can specify array key for every set of such parameters. After that this key can be used as a key for sorting according to the corresponding metafield (custom field).
  • none - do not sort

For arbitrary sorting, you can use the YIKES Inc. Simple Taxonomy Ordering plugin.

Default: 'id'


The sort direction for the $orderby parameter:

  • ASC - from less to more (1, 2, 3; a, b, c).
  • DESC - in reverse order, from more to less (3, 2, 1; c, b, a).

Default: "ASC"

Whether to hide terms that have no entries. 1 (true) - hide empty, 0 (false) - show empty.
Default: true

What fields to return in the resulting array. Can be:

  • all - Return an array of objects (all data) - default.
  • ids - return an array of numbers.
  • names - return an array of strings.
  • count - returns the count of found terms.
  • id=>parent - return an array, where key = term_id and value = parent term ID.
  • id=>slug - return an array, where key = term_id and value = term slug.
  • id=>name - return an array, where key = term_id and value = term name.

Default: 'all'

true - returns the number of terms. In this case, the fields parameter is ignored.
false - returns an array of term objects.
Specify a string or an array of strings here, to get the terms with the specified slugs.
Default: ''

Whether to include terms that have non-empty child terms (that have posts). It means, that empty terms will be included in the array if their child terms have posts, even if the argument hide_empty = true.

  • true - yes, include.
  • false - no, dont include.

Default: true

Search by term name and term slug. Gets the terms name or slug of which contains specified string. I.e. the query looks like this: LIKE '%search_string%'.
Default: ''
Specify a string or array of strings here, to get the terms with the specified names.
Default: ''
Gets terms that have the specified string in their name. Search by name.
Default: ''
description__like (string)
Show terms that have a specified string in their description. Search by description.
Default: ''

If true, then the number that shows posts count of the parent categories becomes the sum of parent category posts and posts from it's child categories. By default, only self posts are counted.

It depends on the parent parameter because the counting works in PHP and if, for example, you specify parent=0, only the top terms will be obtained and pad_counts will not be able to correctly count the number of posts in the child terms. To work around this limitation, you need to get all the terms by not specify parent parameter at all, and then remove unnecessary terms in PHP... Here is an example of such code:

$terms = get_terms( [
	'hide_empty'  => 0,
	'orderby'     => 'name',
	'order'       => 'ASC',
	'taxonomy'    => 'category',
	'pad_counts'  => 1
] );

// leave only terms with parent=0
$terms = wp_list_filter( $terms, [ 'parent'=>0 ] );

Default: false


If specify all, following parameters will be force disabled: childless, child_of, hide_empty, hierarchical, pad_counts. "force" - means interrupt the current settings for these parameters. "Disabled" - means they will be set to false or 0.

Usually used for convenience, when you need to get terms, not for output, but for further work with them, this parameter allows you to not double check mentioned parameters...

// code snippet
if ( 'all' === $args['get'] ) {
	$args['childless']    = false;
	$args['child_of']     = 0;
	$args['hide_empty']   = 0;
	$args['hierarchical'] = false;
	$args['pad_counts']   = false;

Default: ''


ID of the parent term. Get the terms of taxonomy that are child of the specified term. The whole tree will be obtained (all nesting levels).

If multiple taxonomies are specified, the parameter is ignored.
Default: 0


true will skip (not get) terms that have child terms.

Has no effect on non-hierarchical taxonomies.
По умолчанию: false


The parent ID of the term to obtain only direct children.

Only the first nesting level will be obtained, not the whole tree as do parameter child_of. If you specify 0, the top-level terms will be displayed.
Default: ''

Enter a number or an array of numbers here to get the terms that have the field term_taxonomy_id matched the specified values.
Default: ''
Allows you to set an unique cache key to be used by get_terms() with WP object cache. For example, if to change the query you use one of the get_terms() filter (e.g. terms_clausses), setting this parameter, allow you to overwrite stored cache for identical queries.
Default: 'core'
true — load the metadata cache so you can retrieve it quickly. The cache is loaded for the received items.
Default: true
Query to retrieve terms by specified metadata. The parameter has many nested parameters, see WP_Meta_Query.
Get the terms with specified meta key. Can be used in conjunction with meta_value.
Default: ''
Get the terms with specified meta value. Always used in conjunction with meta_key.
Default: ''
MySQL operator used for comparing the meta value. See WP_Meta_Query::__construct() for accepted values and default value.
MySQL operator used for comparing the meta key. See WP_Meta_Query::__construct() for accepted values and default value.
MySQL data type that the meta_value column will be CAST to for comparisons. See WP_Meta_Query::__construct() for accepted values and default value.
MySQL data type that the meta_key column will be CAST to for comparisons. See WP_Meta_Query::__construct() for accepted values and default value.
Whether to suppress work of get_terms() filters (hooks)? If set to true, the filters will not work for the current request.
Default: false (filters enabled)
cache_results(true/false) (WP 6.4)

Whether to cache the results in the Object Cache.

This caching for terms has always been in place. In WP 6.2, it was moved to a separate cache group term-queries, and in 6.4, this parameter was added to allow disabling of the caching.

Default: true



#1 Dropdown list

To create a drop-down list of categories, we can use another special function wp_dropdown_categories():

wp_dropdown_categories( [
	'hide_empty' => 0,
	'name' => 'category_parent',
	'orderby' => 'name',
	'selected' => $category->parent,
	'hierarchical' => true,
	'show_option_none' => __('None')
] );

However, with this approach, we will lose some flexibility in configuring the list, because we will get a fully formed list.

Therefore, in some cases, it makes more sense to create a drop-down list using get_categories(). Example (it is assumed that we need to display subcategories (children) of category 10):

<select name="event-dropdown" onchange="document.location.href = this.options[ this.selectedIndex ].value;">

	<option value=""><?php echo esc_attr( 'Select category' ); ?></option>

	$categories = get_categories( 'child_of=10' );

	foreach( $categories as $category ){

		$option = '<option value="' . get_term_link( $category ) . '">';
		$option .= $category->name;
		$option .= ' (' . $category->count . ')';
		$option .= '</option>';

		echo $option;


#2 A list of categories and their descriptions

This example will show how you can list the links to the categories, with a category description right after each link (you set description when you create/edit the category):

$categories = get_categories( [
	'orderby' => 'name',
	'order' => 'ASC'
] );

foreach( $categories as $category ){

	echo '<p>Category: '. sprintf( '<a href="%s">%s</a>', get_category_link( $category->term_id ), $category->name  ) .' </p> ';
	echo '<p> Description:'. $category->description . '</p>';
	echo '<p> Post Count: '. (int) $category->count . '</p>';

#3 Get only categories with posts in them

By default get_category() returns ONLY categories that have posts (not empty categories). This means that if there is no post assigned to a category, the category will not be retrieved.

To avoid this and show all categories whether they have posts or not, you must specify parameter 'hide_empty'' => false:

$args = array(
	'hide_empty' => false,

$cats = get_categories( $args ); // will return all categories (including empty ones)

#4 Retrieve only top level categories

To do this, set 'parent' => 0. This example print the links and the names of the top-level categories only.

$cats = get_categories( array(
	'orderby' => 'name',
	'parent'  => 0
) );

foreach ( $cats as $cat ) {

	printf( '<a href="%1$s">%2$s</a><br />',
		esc_url( get_category_link( $cat->term_id ) ),
		esc_html( $cat->name )


  • See: get_terms() Type of arguments that can be changed.


Since 2.1.0 Introduced.

get_categories() code WP 6.5.3

function get_categories( $args = '' ) {
	$defaults = array( 'taxonomy' => 'category' );
	$args     = wp_parse_args( $args, $defaults );

	 * Filters the taxonomy used to retrieve terms when calling get_categories().
	 * @since 2.7.0
	 * @param string $taxonomy Taxonomy to retrieve terms from.
	 * @param array  $args     An array of arguments. See get_terms().
	$args['taxonomy'] = apply_filters( 'get_categories_taxonomy', $args['taxonomy'], $args );

	// Back compat.
	if ( isset( $args['type'] ) && 'link' === $args['type'] ) {
				/* translators: 1: "type => link", 2: "taxonomy => link_category" */
				__( '%1$s is deprecated. Use %2$s instead.' ),
				'<code>type => link</code>',
				'<code>taxonomy => link_category</code>'
		$args['taxonomy'] = 'link_category';

	$categories = get_terms( $args );

	if ( is_wp_error( $categories ) ) {
		$categories = array();
	} else {
		$categories = (array) $categories;
		foreach ( array_keys( $categories ) as $k ) {
			_make_cat_compat( $categories[ $k ] );

	return $categories;