First, Wish you all a Happy New Year! 🙂
Now lets get down to the nerd stuff!
This is a very commonly faced problem by many WP devs. When logged in as a user with a role that is allowed to create / edit posts such as Author, Editor, Contributor or a custom role with the ‘edit_posts’ capability, the posts list on the ‘Posts’ page in the back-end shows all the published posts, even those by other users. The current user can see and edit his own posts, which is fine, but can see user’s posts which seems to be killing the sense of privacy in a multi-user system and is undesired by many developers. Doesn’t it look more secure and sophisticated when the posts list shows only the current users posts? In fact in a system where users are given accounts and privileges to create / edit posts, this fact is very important that they get to see only their work and not others. Also, it will reduce the posts list!

Unfortunately this is not possible with ‘edit_posts’ capability, as it displays all the published posts, and hence this hack can be used.

We’ll use the very well known action hook, ‘pre_get_posts’ for achieving this. If this sounds strange for you, then I suggest you read more on WP Actions and ‘pre_get_posts’ before reading down.

This is the code that’ll do our job:

[php]
add_action(‘pre_get_posts’, ‘filter_posts_list’);
function filter_posts_list($query)
{
//$pagenow holds the name of the current page being viewed
global $pagenow;

//$current_user uses the get_currentuserinfo() method to get the currently logged in user’s data
global $current_user;
get_currentuserinfo();

//Shouldn’t happen for the admin, but for any role with the edit_posts capability and only on the posts list page, that is edit.php
if(!current_user_can(‘administrator’) && current_user_can(‘edit_posts’) && (‘edit.php’ == $pagenow))
{
//global $query’s set() method for setting the author as the current user’s id
$query->set(‘author’, $current_user->ID);
}
}
[/php]

That’s it! The code is pretty simple. We hook into ‘pre_get_posts’ which runs before the query for retrieving the posts list is run. Then we check that the current user is not the Admin but has a role with ‘edit_posts’ capability, and use $pagenow global variable to make sure our code is run only on the ‘Posts’ page in the back-end, which is actually named ‘edit.php’. Variable $query is an object of the WP_Query class, and holds the current query for getting the posts. It has a method ‘set’ that allows you to change the arguments of the query. All the parameters that can be used with WP_Query, are valid over here. Hence we set the current user’s id as the ‘Author’, which means the query will now retrieve only the current user’s posts.

Note: You can filter the posts list with any criteria you want using the same method!

Now, if you log in with the role you did this for (not the Admin!), and view the posts list page, you’ll see that it no more displays all the published posts, but only the current users posts.

There’s one more place that will reveal to the current user that there are other posts in this system as well, that is the 3 links that show the posts counts, ‘All’, ‘Published’ and ‘Mine’. As we’re showing the only the current user’s posts, we are interested in ‘Mine’, hence want to hide the other two.

Let’s do it right away. Edit the above code, and add the following lines to it, right after the line ‘$query->set…’:

[php]
$screen = get_current_screen();
add_filter(‘views_’.$screen->id, ‘remove_post_counts’);
[/php]

We’re using an undocumented filter ‘views_’.{screen_id}, which needs the current screen’s id. Hence we use the ‘get_current_screen()’ method for getting the current screen’s id, and append it to ‘view’. The function ‘remove_post_counts’ is as follows:

[php]
function remove_post_counts($posts_count_disp)
{
//$posts_count_disp contains the 3 links, we keep ‘Mine’ and remove the other two.
unset($posts_count_disp[‘all’]);
unset($posts_count_disp[‘publish’]);

return $posts_count_disp;
}
[/php]

Visit the ‘Posts’ page again, and you should see only the current user’s posts count displayed there.

I assume this tutorial will help you achieve a better level of privacy and thus security, if you’re extensively using custom user roles in your system and allowing unknown users to edit posts. You can use the same trick and filter the posts list in the back-end ‘Posts’ page using any criteria you want!

Doubts, comments, criticism… always welcome!

By rutwick

30 thoughts on “Display only the posts authored by the current WP user on the ‘Posts’ page in the back-end”
  1. Thanks for the article.

    if I leave current_user_can(‘edit_posts’) in the if statement it doesn’t work and everybody can see everything. I don’t know why, probably something with my capabilities.

    I would like to suggest to put unset($posts_count_disp[‘draft’]); in remove_post_counts too.

    bye

  2. Another thing… for the trash label.

    If i put unset($posts_count_disp[‘trash’]); this hide to the user his trash too 🙁
    and for the draft it hide the draft label, but anyway a user can see draft article under mine label.

    bye

    1. You can put another check as $query->set(‘post_status’, ‘publish’) although it should happen by default.

  3. thank you,i wish to use these code for my site. but i donot know where should i paste these code? please in form the wp file name.

  4. Great solution !! I had done this before by adding some custom CSS with “display:none;” for these things.

    Also remember that the add new link, the check boxes, the search box and the bulk action boxes need to be removed as they are useless or unnecessary to the eyes of some users. Also by clicking them the user will get a error message.

    1. Thanks!
      Yes you’re right about those sections, I should give it a try.
      Do you have a solution to do that? Please let me know it too!

  5. Great Post!!

    However, I would like to know is there a way to change the number in the () to reflect the number only associated to the author? Instead of removed all the section like “Published”or “Draft”.

    Thanks

    1. Yep, just use the filter used for changing the number. That is, `add_filter(‘views_’.$screen->id, ‘remove_post_counts’)` is what you’ll need.

  6. sweet post. is there a way to filter on the counts for all/published instead and still leave the links there? tia 😀

  7. Thank you for this post, I have been looking for a similar code snippet to display posts by current author on the front end of a buddypress site. Specifically the author’s activity page. I am using a plugin that adds a “posts()” count display and when clicked it displays the most recent post, I want to display the excerpt of all posts by the current author, or the ability to display the last 3 post excerpts with the ability to navigate to the next 3 if any exist. When I first created the site this was a default setting which I lost at some point through an update. Here’s an example of how it used to look “http://www.petownerworld.com/members/cherieasmith/activity/” and here’s how it now displays “http://www.petownerworld.com/members/cherieasmith/” Thank you for your help.

    1. Hi,
      Sorry, I’m unable to understand where you are (or were!) stuck exactly! Could you please explain what the problem was?

  8. Your codes works! However, I received this error message: Notice: Undefined index: post_status in……
    Seem post_status is not recognized, but still work though..any idea why?

    1. Sorry for the delay in reply.
      Please try printing the contents of the array, you’ll know if the status is set or not.
      – rutwick

  9. Hi, how come this doesn’t work in my site?
    Does this work in Multisite?
    My non-admin users has Contributor Role.

    Thanks.

    1. Pretty much yes, as WP uses the same method for displaying the posts on the front end. The WP_Query!

  10. Thank you for tip . One more question , I have “Author” page on my site where all posts are listed from that particular author . Is it possible to allow logged in authors to edit/delete their own posts from that page ?

    1. I think you should check the current user’s role on that page, and list his posts if its an Author. For edit, you may have to display a custom form.

Leave a Reply

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