get_pages()WP 1.5.0

Retrieve pages data (or hierarchical post type data) as an array of posts objects. Caches the result in object cache.

The received data should be custom processed via foreach.

Specify the post_type parameter to get data of custom post types.

The function works only with hierarchical post types. So the function returns false if post_type = post would be specified.

Use get_posts() to get the same posts data for non-hierarchical post types.

Use wp_list_pages() to display page titles in a tree view.

1 time — 0.004261 sec (very slow) | 50000 times — 6.05 sec (fast) | PHP 7.1.2, WP 4.7.3
Hooks from the function

Return

WP_Post[]|false. Array of pages (or hierarchical post type items). Boolean false if the specified post type is not hierarchical or the specified status is not supported by the post type.

Usage template

$pages = get_pages( [
	'sort_order'   => 'ASC',
	'sort_column'  => 'post_title',
	'hierarchical' => 1,
	'exclude'      => '',
	'include'      => '',
	'meta_key'     => '',
	'meta_value'   => '',
	'authors'      => '',
	'child_of'     => 0,
	'parent'       => -1,
	'exclude_tree' => '',
	'number'       => '',
	'offset'       => 0,
	'post_type'    => 'page',
	'post_status'  => 'publish',
] );

foreach( $pages as $post ){
	setup_postdata( $post );
	// output format
}

wp_reset_postdata();

Usage

$pages = get_pages( $args );
$args(array/string)
Array or string of arguments to retrieve pages.
Default: array() (preset)

$args parameter arguments

post_type(string)
The post type to query.
Default: 'page'
post_status(string/array)
Array or comma-separated list or of post statuses to include. Ex: 'publish,private'
Default: 'publish'
exclude(string/array)
Array of page IDs to exclude. Can be specified as string: exclude=3,7,31.
Default: empty array
exclude_tree(string/array)
Array or comma-separated string of page IDs to exclude. This is the opposite of child_of parameter. It cuts the entire pages branch starting with the one specified in this parameter, cuts it and all levels of child pages. Here we need to specify the ID of the "top-level" page.
Default: empty array
include(array/string)

Array of page IDs to include. Can be specified as string: include=45,63,78,94,128,140.

Important: specifying of this parameter cancels the following parameters: child_of, parent, exclude, meta_key, meta_value and set hierarchical = false.

Default: empty array

child_of(int)

Page ID child and grandchild of which we want to get. For example, if specify 10 we get all child pages of page 10 and all child pages of child pages, i.e not only the first level, but also the second, third, etc. We get the entire hierarchy.

Important: this parameter cancels if the include parameter is specified.

Important: we can't use number parameter together with this one. Because this function makes SQL query for getting data of all pages of the specified post_type and only then the appropriate ones are selected as a childs using the function get_page_children( $child_of, $pages ).

Default: 0 (not set)

parent(int/array)

ID of a parent page. Many ID can be specified as an array. Retrieves the pages which has post_parent = this parameter in the DB.

If this parameter is specified, then hierarchical=false is sets forcibly (it true by default).

The difference with the child_of parameter is that this parameter returns only child pages, without any nested pages, i.e. returns one level.

Default: -1 (no restriction)

hierarchical(true/false)

Whether to return pages hierarchically.

  • true (or 1) - children indented from the parent (default).
  • false (or 0) - print all in one row.

Important: hierarchical = false is sets forcibly if any of the following parameters are specified: parent, include. This is done because these parameters are mutually exclusive (if you think about it).

Default: true

meta_key(string)
Only include pages with this meta key.
Default: ''
meta_value(string)
Only include pages with this meta value. Requires $meta_key.
Default: ''
authors(string)

A comma-separated list of author IDs.

Note: get_posts() uses the parameter author instead of authors.

Default: ''

number(int)

The number of pages to return. Specify LIMIT in the SQL query.

Note: this parameter can't be used together with the child_of.

Note: get_posts() uses the numberposts parameter instead of number.

Default: -1 (no limit)

offset(int)
The number of pages to skip before returning. Requires $number.
Specify how many pages you would like to skip from the specified selection, i.e. specify 5 and 5 top pages will be cut.
sort_column(string)

What columns to sort pages by, comma-separated. In this parameter, you can use any field from the table wp_posts.

You can specify multiple fields separated by commas: menu_order, post_title. Possible values:

'author'
'post_author'
'date'
'post_date'
'title'
'post_title'
'name'
'post_name'
'modified'
'post_modified'
'modified_gmt'
'post_modified_gmt'
'menu_order'
'parent'
'post_parent'
'ID'
'rand'
'comment_count'

Note: fields with post_ prefix can be specified without this prefix, for example post_title can be title.

Default: 'post_title'

sort_order(string)

In which direction to arrange field specified in the $orderby parameter:

  • ASC - from smaller to larger abs.
  • DESC - In reverse order (from larger to smaller, sba).

Note: get_posts() uses the parameter order instead of sort_order.

Default: 'ASC'

Examples

0

#1 Show pages in the drop-down list

In this example, we will create a drop-down list with all pages. We get the page link with get_page_link() in which we pass the page ID:

<select name="page-dropdown"
 onchange='document.location.href=this.options[this.selectedIndex].value;'> 
	<option value=""><?php echo esc_attr( __( 'Select page' ) ); ?></option> 
	<?php 
	$pages = get_pages(); 
	foreach( $pages as $page ){
		echo '<option value="' . get_page_link( $page->ID ) . '">'. esc_html($page->post_title) .'</option>';
	}
	?>
</select>
0

#2 Show child pages

Output a dynamic list of child pages. If we place following code at the end of the article, we will get something like categories, where all child pages will go under the main content of the page:

<?php
$mypages = get_pages( array( 'child_of' => $post->ID, 'sort_column' => 'post_date', 'sort_order' => 'desc' ) );

foreach( $mypages as $page ) {      
	$content = $page->post_content;

	// skip pages without content
	if ( ! $content ) continue;

	$content = apply_filters( 'the_content', $content );

	?>
	<h2><a href="<?php echo get_page_link( $page->ID ); ?>"><?php echo $page->post_title; ?></a></h2>
	<div class="entry"><?php echo $content; ?></div>
	<?php
}
0

#3 Pages with the specified template

This example shows how to get the pages which page-tpl.php template file. This template file specified in admin page and stored in post metadata under _wp_page_template key. So we need all the pages whith have such metafield.

$pages = get_pages( array( 
	'meta_key'     => '_wp_page_template', 
	'meta_value'   => 'page-tpl.php', 
	'hierarchical' => 0
));

foreach( $pages as $page ){
	echo "$page->post_title <br>";
}

You can also use get_posts() instead of get_pages().

Changelog

Since 1.5.0 Introduced.
Since 6.3.0 Use WP_Query internally.

get_pages() code WP 6.5.2

function get_pages( $args = array() ) {
	$defaults = array(
		'child_of'     => 0,
		'sort_order'   => 'ASC',
		'sort_column'  => 'post_title',
		'hierarchical' => 1,
		'exclude'      => array(),
		'include'      => array(),
		'meta_key'     => '',
		'meta_value'   => '',
		'authors'      => '',
		'parent'       => -1,
		'exclude_tree' => array(),
		'number'       => '',
		'offset'       => 0,
		'post_type'    => 'page',
		'post_status'  => 'publish',
	);

	$parsed_args = wp_parse_args( $args, $defaults );

	$number       = (int) $parsed_args['number'];
	$offset       = (int) $parsed_args['offset'];
	$child_of     = (int) $parsed_args['child_of'];
	$hierarchical = $parsed_args['hierarchical'];
	$exclude      = $parsed_args['exclude'];
	$meta_key     = $parsed_args['meta_key'];
	$meta_value   = $parsed_args['meta_value'];
	$parent       = $parsed_args['parent'];
	$post_status  = $parsed_args['post_status'];

	// Make sure the post type is hierarchical.
	$hierarchical_post_types = get_post_types( array( 'hierarchical' => true ) );
	if ( ! in_array( $parsed_args['post_type'], $hierarchical_post_types, true ) ) {
		return false;
	}

	if ( $parent > 0 && ! $child_of ) {
		$hierarchical = false;
	}

	// Make sure we have a valid post status.
	if ( ! is_array( $post_status ) ) {
		$post_status = explode( ',', $post_status );
	}
	if ( array_diff( $post_status, get_post_stati() ) ) {
		return false;
	}

	$query_args = array(
		'orderby'                => 'post_title',
		'order'                  => 'ASC',
		'post__not_in'           => wp_parse_id_list( $exclude ),
		'meta_key'               => $meta_key,
		'meta_value'             => $meta_value,
		'posts_per_page'         => -1,
		'offset'                 => $offset,
		'post_type'              => $parsed_args['post_type'],
		'post_status'            => $post_status,
		'update_post_term_cache' => false,
		'update_post_meta_cache' => false,
		'ignore_sticky_posts'    => true,
		'no_found_rows'          => true,
	);

	if ( ! empty( $parsed_args['include'] ) ) {
		$child_of = 0; // Ignore child_of, parent, exclude, meta_key, and meta_value params if using include.
		$parent   = -1;
		unset( $query_args['post__not_in'], $query_args['meta_key'], $query_args['meta_value'] );
		$hierarchical           = false;
		$query_args['post__in'] = wp_parse_id_list( $parsed_args['include'] );
	}

	if ( ! empty( $parsed_args['authors'] ) ) {
		$post_authors = wp_parse_list( $parsed_args['authors'] );

		if ( ! empty( $post_authors ) ) {
			$query_args['author__in'] = array();
			foreach ( $post_authors as $post_author ) {
				// Do we have an author id or an author login?
				if ( 0 == (int) $post_author ) {
					$post_author = get_user_by( 'login', $post_author );
					if ( empty( $post_author ) ) {
						continue;
					}
					if ( empty( $post_author->ID ) ) {
						continue;
					}
					$post_author = $post_author->ID;
				}
				$query_args['author__in'][] = (int) $post_author;
			}
		}
	}

	if ( is_array( $parent ) ) {
		$post_parent__in = array_map( 'absint', (array) $parent );
		if ( ! empty( $post_parent__in ) ) {
			$query_args['post_parent__in'] = $post_parent__in;
		}
	} elseif ( $parent >= 0 ) {
		$query_args['post_parent'] = $parent;
	}

	/*
	 * Maintain backward compatibility for `sort_column` key.
	 * Additionally to `WP_Query`, it has been supporting the `post_modified_gmt` field, so this logic will translate
	 * it to `post_modified` which should result in the same order given the two dates in the fields match.
	 */
	$orderby = wp_parse_list( $parsed_args['sort_column'] );
	$orderby = array_map(
		static function ( $orderby_field ) {
			$orderby_field = trim( $orderby_field );
			if ( 'post_modified_gmt' === $orderby_field || 'modified_gmt' === $orderby_field ) {
				$orderby_field = str_replace( '_gmt', '', $orderby_field );
			}
			return $orderby_field;
		},
		$orderby
	);
	if ( $orderby ) {
		$query_args['orderby'] = array_fill_keys( $orderby, $parsed_args['sort_order'] );
	}

	$order = $parsed_args['sort_order'];
	if ( $order ) {
		$query_args['order'] = $order;
	}

	if ( ! empty( $number ) ) {
		$query_args['posts_per_page'] = $number;
	}

	/**
	 * Filters query arguments passed to WP_Query in get_pages.
	 *
	 * @since 6.3.0
	 *
	 * @param array $query_args  Array of arguments passed to WP_Query.
	 * @param array $parsed_args Array of get_pages() arguments.
	 */
	$query_args = apply_filters( 'get_pages_query_args', $query_args, $parsed_args );

	$pages = new WP_Query();
	$pages = $pages->query( $query_args );

	if ( $child_of || $hierarchical ) {
		$pages = get_page_children( $child_of, $pages );
	}

	if ( ! empty( $parsed_args['exclude_tree'] ) ) {
		$exclude = wp_parse_id_list( $parsed_args['exclude_tree'] );
		foreach ( $exclude as $id ) {
			$children = get_page_children( $id, $pages );
			foreach ( $children as $child ) {
				$exclude[] = $child->ID;
			}
		}

		$num_pages = count( $pages );
		for ( $i = 0; $i < $num_pages; $i++ ) {
			if ( in_array( $pages[ $i ]->ID, $exclude, true ) ) {
				unset( $pages[ $i ] );
			}
		}
	}

	/**
	 * Filters the retrieved list of pages.
	 *
	 * @since 2.1.0
	 *
	 * @param WP_Post[] $pages       Array of page objects.
	 * @param array     $parsed_args Array of get_pages() arguments.
	 */
	return apply_filters( 'get_pages', $pages, $parsed_args );
}