Adding the Page Order to the Page List in the WordPress Admin

I like to keep my WordPress sites’ admin areas as organized and clean as possible to limit confusion and to make items easy to find. One example of this is trying to keep my WordPress Pages in a logical order. When I look at the Pages list in the WordPress admin I like it to basically reflect the order of the menus on my site. This makes finding pages easier on the backend.

However, the default display of pages in the WordPress admin shows columns which, honestly, I don’t find to be of much use. WordPress shows the page’s author, a count of comments, and the published date of the page. Personally, I cannot think of a time when I have allowed comments on a page so I have never needed a comment count. The author of a page is also something I rarely have a use for. Honestly these two columns are much more applicable for blog posts instead of pages. Thankfully they can be hidden via the Screen Options.

Showing and hiding columns in the Screen Options panel
Showing and hiding columns in the Screen Options panel

This does not solve my desire to see the Order for pages in the list, though. Why is this important to me? Well, it isn’t crucial. After all, you can quickly check the Order of a page by toggling the Quick Edit option.

Viewing a page's Menu Order in the Quick Edit panel

But if I want to add a page between two other pages that means I would need to open up Quick Edit on two different pages to find their Order. A couple of clicks and I also need to remember each number. It is much easier to just be able to glance at my pages and see how they are ordered. To this end, I created some code for the functions.php file (or a plugin).

The first thing we need to do is change the columns on the Pages listing screen. WordPress has a manage_pages_columns filter that allows us to manipulate these columns. Let’s take a look at the columns that WordPress gives us “out of the box.” Using Ray, I can easily see what the default value of $columns is in the manage_pages_columns hook. Using add_filter I will just throw the content of $columns into Ray:

Using add_filter to check the default value of $columns

I get the following results in Ray:

The default value of $columns for pages

We are getting an array with five elements for our columns. There is a checkbox at the beginning which is used for bulk actions on pages:

The “cb” column

The other array elements should look familiar – the page title, author, the number of comments, and the page’s date of publication. That all makes sense. Let’s change them to match what we are looking for. We can do this by returning an array of columns that we would like to see:

function scc_filter_page_columns( $columns ) {
    return array(
        'cb'    => '<input type="checkbox" />',
	'title' => 'Title',
	'order' => 'Order'
    );
}

add_filter( 'manage_pages_columns', 'scc_filter_page_columns' );

I want to keep the checkbox used for bulk actions on pages and, of course, the page title. I will continue returning those. Instead of returning the other columns, though, I am going to return a column for the page order. This only gets us part of the way there. The column header will be shown but WordPress doesn’t know what to put in that column for each record.

Our Order Column header is in place

WordPress doesn’t just provide a filter to change the table headers in the page list. WordPress also provides a filter to populate the content for your custom columns, manage_pages_custom_column. This hook will pass through the name of the column (the key in the array we are returning in scc_filter_page_columns) and the id of the post currently being displayed in the table. Let’s use Ray again and verify what is passed to our function for the $column_name.

Using Ray to get the value of $column_name

I have five pages on my example site, and this action will run for each page, so I will see the value of $column_name for each of the five pages in Ray:

The value of $column_name in our manage_pages_custom_column action

As expected, the $column_name is the key assigned in our array of columns, order. The other columns, ‘cb’ and ‘title,’ are not custom columns but default WordPress columns so we won’t see those in this hook. Instead of simply sending the $column_name value to Ray, let us instead populate that column with the order of the page.

function scc_populate_page_columns( $column_name, $post_id ) {
    global $post;
    if ( 'order' === $column_name ) {
        if ( $post->post_parent == 0 ) {
	    echo "<strong>{$post->menu_order}</strong>";
	} else {
	    $parents = get_post_ancestors( $post->ID );
	    foreach ( $parents as $parent ) {
	        echo " &mdash; ";
	    }
	    echo $post->menu_order;
	}
    }
}

add_action( 'manage_pages_custom_column', 'scc_populate_page_columns', 10, 2 );

The first thing that we will do is look for our $column_name which should be set to ‘order’. You could add multiple custom columns and determine what to do for each by matching on the column name. We have the information for the page currently being displayed with global $post. With that, we can get the page’s order and display it. I am also doing a few additional actions to make the display of the page order more informative.

If the page does not have a parent, it is a top-level page. I want to bold these pages so that they are more easily distinguishable. For the children pages I want to add an em dash for each parent the page has. This helps me easily pick out the hierarchy of the pages and tell how deep each page is. Here is the result:

The display of pages with their set orders.

Now if I want to add a new child of “Test Page,” I can easily determine the Order I need to set for it. As mentioned previously we can also extend the information we display for any other columns that we need.

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes:

<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>