7 min read

Programming the Manage panel

The Manage Posts screen can be changed to show extra columns, or remove unwanted columns in the listing.

Let’s say that we want to show the post type—Normal, Photo, or Link. Remember the custom field post-type that we added to our posts? We can use it now to differentiate post types.

Time for action – Add post type column in the Manage panel

We want to add a new column to the Manage panel, and we will call it Type. The value of the column will represent the post type—Normal, Photo, or Link.

  1. Expand the admin_menu() function to load the function to handle Manage Page hooks:
    add_submenu_page('post-new.php', __('Add URL',
    $this->plugin_domain) , __('URL', $this->plugin_domain) , 1 ,
    'add-url', array(&$this, 'display_form') );
    // handle Manage page hooks
    add_action('load-edit.php', array(&$this, 'handle_load_edit') );
    }
  2. Add the hooks to the columns on the Manage screen:
    // Manage page hooks
    function handle_load_edit()
    {
    // handle Manage screen functions
    add_filter('manage_posts_columns', array(&$this,
    'handle_posts_columns'));
    add_action('manage_posts_custom_column', array(&$this,
    'handle_posts_custom_column'), 10, 2);
    }
  3. Then implement the function to add a new Column, remove the author and replace the date with our date format:
    // Handle Column header
    function handle_posts_columns($columns)
    {
    // add 'type' column
    $columns['type'] = __('Type',$this->plugin_domain);
    return $columns;
    }
  4. For date key replacement, we need an extra function:    
    function array_change_key_name( $orig, $new, &$array )
    {
    foreach ( $array as $k => $v )
    $return[ ( $k === $orig ) ? $new : $k ] = $v;
    return ( array ) $return;
    }
  5. And finally, insert a function to handle the display of information in that column:
    // Handle Type column display
    function handle_posts_custom_column($column_name, $id)
    {
    // 'type' column handling based on post type
    if( $column_name == 'type' )
    {
    $type=get_post_meta($id, 'post-type', true);
    echo $type ? $type : __('Normal',$this->plugin_domain);
    }
    }
  6. Don’t forget to add the Manage page to the list of localized pages:
    // pages where our plugin needs translation
    $local_pages=array('plugins.php', 'post-new.php', 'edit.php');
    if (in_array($pagenow, $local_pages))

As a result, we now have a new column that displays the post type using information from a post custom field.

What just happened?

We have used the load-edit.php action to specify that we want our hooks to be assigned only on the Manage Posts page (edit.php). This is similar to the optimization we did when we loaded the localization files.

The handle_posts_columns is a filter that accepts the columns as a parameter and allows you to insert a new column:

function handle_posts_columns($columns)
{
$columns['type'] = __('Type',$this->plugin_domain);
return $columns;
}

You are also able to remove a column. This example would remove the Author column:

unset($columns['author']);

To handle information display in that column, we use the handle_posts_custom_column action.

The action is called for each entry (post), whenever an unknown column is encountered. WordPress passes the name of the column and current post ID as parameters.

That allows us to extract the post type from a custom field:

function handle_posts_custom_column($column_name, $id)
{
if( $column_name == 'type' )
{
$type=get_post_meta($id, 'post-type', true);

It also allows us to print it out:

    echo $type ? $type : __('Normal',$this->plugin_domain);
}
}

Modifying an existing column

We can also modify an existing column. Let’s say we want to change the way Date is displayed.

Here are the changes we would make to the code:


// Handle Column header
function handle_posts_columns($columns)
{
// add 'type' column
$columns['type'] = __('Type',$this->plugin_domain);
// remove 'author' column
//unset($columns['author']);
// change 'date' column
$columns = $this->array_change_key_name( 'date', 'date_new',
$columns );
return $columns;
}
// Handle Type column display
function handle_posts_custom_column($column_name, $id)
{
// 'type' column handling based on post type
if( $column_name == 'type' )
{
$type=get_post_meta($id, 'post-type', true);
echo $type ? $type : __('Normal',$this->plugin_domain);
}
// new date column handling
if( $column_name == 'date_new' )
{
the_time('Y-m-d <br > g:i:s a');
}
}
function array_change_key_name( $orig, $new, &$array )
{
foreach ( $array as $k => $v )
$return[ ( $k === $orig ) ? $new : $k ] = $v;
return ( array ) $return;
}

The example replaces the date column with our own date_new column and uses it to display the date with our preferred formatting.

Manage screen search filter

WordPress allows us to show all the posts by date and category, but what if we want to show all the posts depending on post type?

No problem! We can add a new filter select box straight to the Manage panel.

Time for action – Add a search filter box

  1. Let’s start by adding two more hooks to the handle_load_edit() function. The restrict_manage_posts function draws the search box and the posts_where alters the database query to select only the posts of the type we want to show.
    // Manage page hooks
    function handle_load_edit()
    {
    // handle Manage screen functions
    add_filter('manage_posts_columns',
    array(&$this, 'handle_posts_columns'));
    add_action('manage_posts_custom_column',
    array(&$this, 'handle_posts_custom_column'), 10, 2);
    // handle search box filter
    add_filter('posts_where',
    array(&$this, 'handle_posts_where'));
    add_action('restrict_manage_posts',
    array(&$this, 'handle_restrict_manage_posts'));
    }
  2. Let’s write the corresponding function to draw the select box:
    // Handle select box for Manage page
    function handle_restrict_manage_posts()
    {
    ?>
    <select name="post_type" id="post_type" class="postform">
    <option value="0">View all types</option>
    <option value="normal" <?php if( $_GET['post_type']=='normal')
    echo 'selected="selected"' ?>><?php _e
    ('Normal',$this->plugin_domain); ?></option>
    <option value="photo" <?php if( $_GET['post_type']=='photo')
    echo 'selected="selected"' ?>><?php _e
    ('Photo',$this->plugin_domain); ?></option>
    <option value="link" <?php if( $_GET['post_type']=='link')
    echo 'selected="selected"' ?>><?php _e
    ('Link',$this->plugin_domain); ?></option>
    </select>
    <?php
    }
  3. And finally, we need a function that will change the query to retrieve only the posts of the selected type:
    // Handle query for Manage page
    function handle_posts_where($where)
    {
    global $wpdb;
    if( $_GET['post_type'] == 'photo' )
    {
    $where .= " AND ID IN (SELECT post_id FROM {$wpdb->postmeta}
    WHERE meta_key='post-type' AND metavalue='".__
    ('Photo',$this->plugin_domain)."' )";
    }
    else if( $_GET['post_type'] == 'link' )
    {
    $where .= " AND ID IN (SELECT post_id FROM {$wpdb->postmeta}
    WHERE meta_key='post-type' AND metavalue='".__
    ('Link',$this->plugin_domain)."' )";
    }
    else if( $_GET['post_type'] == 'normal' )
    {
    $where .= " AND ID NOT IN (SELECT post_id FROM
    {$wpdb->postmeta} WHERE meta_key='post-type' )";
    }
    return $where;
    }

What just happened?

We have added a new select box to the header of the Manage panel. It allows us to filter the post types we want to show.

We added the box using the restrict_manage_posts action that is triggered at the end of the Manage panel header and allows us to insert HTML code, which we used to draw a select box.

To actually perform the filtering, we use the posts_where filter, which is run when a query is made to fetch the posts from the database.

if( $_GET['post_type'] == 'photo' )
{
$where .= " AND ID IN (SELECT post_id FROM {$wpdb->postmeta}
WHERE meta_key='post-type' AND metavalue='".__
('Photo',$this->plugin_domain)."' )";

If a photo is selected, we inspect the WordPress database postmeta table and select posts that have the post-type key with the value, Photo.

At this point, we have a functional plugin. What we can do further to improve it is to add user permissions checks, so that only those users allowed to write posts and upload files are allowed to use it.

Quick reference
manage_posts_columns($columns): This acts as a filter for adding/removing columns in the Manage Posts panel. Similarly, we use the function, manage_pages_columns for the Manage Pages panel.
manage_posts_custom_column($column, $post_id): This acts as an action to display information for the given column and post. Alternatively, manage_pages_custom_column for Manage Pages panel.
posts_where($where): This acts as a filter for the where clause in the query that gets the posts.
restrict_manage_posts: This acts as an action that runs at the end of the Manage panel header and allows you to insert HTML.

LEAVE A REPLY

Please enter your comment!
Please enter your name here