I'm working on a site that has a fairly large page structure a few levels deep - in some sections there are a lot of pages.

So I want to have functionality if user choose on select box level 1 then only pages in level 1 will show in below list of pages. if he choose level 2 then only level 2 pages, same go to level 3 level 4 level 5 level 6.

it's working for top level parent pages when I set query_vars['post_parent'] = 0; and I want to have same functionality to show list of level 1 child page,level 2 child pages and so on...

I am stuck on it. please I will be great full if anyone can help me for it. Thanks see screenshot link https://i.stack.imgur.com/EKpy6.png

function level_page_admin_posts_filter( $query ) {
  global $pagenow;
  if ( is_admin() && $pagenow == 'edit.php' && !empty($_GET['lavel_pages'])) {
      $level = $_GET['lavel_pages'];
      if($level == 'parent'){
        $query->query_vars['post_parent'] = 0;
      if($level == 1){
      if($level == 2){

add_filter( 'parse_query', 'level_page_admin_posts_filter' );

function admin_page_filter_level_pages() {
  global $wpdb;
  if (isset($_GET['post_type']) && $_GET['post_type'] == 'page') {
  $sql = "SELECT ID, post_title FROM ".$wpdb->posts." WHERE post_type = 'page' AND post_parent = 0 AND post_status = 'publish' ORDER BY post_title";
  $parent_pages = $wpdb->get_results($sql, OBJECT_K);
  $select = '
    <select name="lavel_pages">
      <option value="parent">Parent Pages</option>
      <option value="1">Level 1</option>
      <option value="2">Level 2</option>
      <option value="3">Level 3</option>
      <option value="4">Level 4</option>
  $select .= ' </select>';
  echo $select;
} else {
add_action( 'restrict_manage_posts', 'admin_page_filter_level_pages' );

1 Answer 1


So it looks like get_ancestors() is the function you need to be able to figure out what 'level' something is. The number of results returned from get_ancestors corresponds to your 'level' number, with 0 results meaning parent page.

And so the problem you have is that this number isn't available as a query argument. Therefore, perhaps the simplest option would be to store this as a meta field against all your pages when they're saved. You could achieve this with a simple hook, like:

add_action('save_post', 'hafiz_update_level_number', 10, 2);
function hafiz_update_level_number($postID, $post) {
   if ($post->type == 'page') {
        update_post_meta($postID, 'hafiz_level_number', get_ancestors($postID)) ;

Now don't need to have the if ($level == ?) code, you just make sure you have a number where 0 is 'parent' and 1 is level 1, 2 is level 2, etc. and you can make your query work something like this:

$query->query_vars['meta_key'] = 'hafiz_level_number';
$query->query_vars['meta_value'] = $levelNumber;

You may have to edit this for how you're using this $query object, but hopefully you get the general idea here.

Note you have the obvious problem that this new value is not set unless a post has been saved or updated after you install this hook, so you will need to either manually open and save every page, or write a quick script to run once which loops through every page and sets this value for every page.

Hope that's helpful. This code is untested but the intention is to outline a way you can write the complete code you need to answer your question. Please respond with any questions

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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