7

I have been looking for ways to completely remove the All, Published, and Trash webpages for USERS other than the me, the Administrator.

So the scenario for me is: I have registered users (which I would like to assign with the roles of authors, contributors, etc). Now, when they log in to my website and access the Posts area, I wish for them not to see these three links (All, Published, Trash).

I have tried using the jquery function, which is basically the same as display: none, but I don't think it's the optimal choice. I know there's better ways for me to do this.

I did try using plugins, such as Member and Adminimize, among other things, but I can't find the right one.

I hope there's someone out there who can help me. Thanks in advance.

Remove All, Published, and Trash

5

The WP_Posts_List_Table class extends WP_List_Table and within the WP_List_Table::views() method we have the following dynamic views filter:

/**
 * Filter the list of available list table views.
 *
 * The dynamic portion of the hook name, `$this->screen->id`, refers
 * to the ID of the current screen, usually a string.
 *
 * @since 3.5.0
 *
 * @param array $views An array of available list table views.
 */
 $views = apply_filters( "views_{$this->screen->id}", $views );

So we can use the generated views_edit-post filter to adjust the views of the post list table.

Example:

Let's remove the all, publish, future, sticky, draft, pending and trash for non-admins (PHP 5.4+):

/**
 * Remove the 'all', 'publish', 'future', 'sticky', 'draft', 'pending', 'trash' 
 * views for non-admins
 */
add_filter( 'views_edit-post', function( $views )
{
    if( current_user_can( 'manage_options' ) )
        return $views;

    $remove_views = [ 'all','publish','future','sticky','draft','pending','trash' ];

    foreach( (array) $remove_views as $view )
    {
        if( isset( $views[$view] ) )
            unset( $views[$view] );
    }
    return $views;
} );

where you can modify the $remove_views to your needs. Another approach would be to only pick up mine and only return that view.

Then we could try to force the mine view further with:

/**
 * Force the 'mine' view on the 'edit-post' screen
 */
add_action( 'pre_get_posts', function( \WP_Query $q )
{
    if( 
           is_admin() 
        && $q->is_main_query() 
        && 'edit-post' === get_current_screen()->id 
        && ! current_user_can( 'manage_options' )
    )
        $q->set( 'author', get_current_user_id() ); 
} );

Before:

before

After:

after

6
  • Awesome, works like magic! Thank you so very much! – chest_nut Apr 20 '16 at 13:30
  • You're welcome and hopefully you can adjust it to your needs @chest_nut – birgire Apr 20 '16 at 13:36
  • Yes, thank you! I surely will. I'm still learning and it's amazing that you guys are here to help us out. :) @birgire – chest_nut Apr 20 '16 at 13:40
  • For custom post types, the filter is views_edit-my_custom_post_type. Refer to the Admin Screen Reference here codex.wordpress.org/Plugin_API/Admin_Screen_Reference – Ben May 19 '18 at 18:48
  • I think its better to use wp_count_posts, check the $type that is passed, and unset the desired indexes. – Mort 1305 May 28 '20 at 6:42
2

Those statuses are turned from get_available_post_statuses(), which in turn gets its values from wp_count_posts().

wp_count_posts() passes it's values through the wp_count_posts filter. So you can tap into that and hijack what gets returned.

Try this:

function _dbdb_wp_count_posts( $counts, $type, $perm ) {
    global $pagenow;

    if( 'edit.php' !== $pagenow ){
        return $counts;
    }

    if( current_user_can( 'manage_options' ) ){
        return $counts;
    }

    $_counts = new stdClass();
    foreach ( $counts as $status => $count ){
        $_counts->$status = '';
    }

    return $_counts;
}
add_filter('wp_count_posts', '_dbdb_wp_count_posts', 99, 3 );

What this does is check if we're on the edit.php page in the Admin,and if not, just return the counts.

Then it checks if the current user can manage site options, which only an Administrator can. If the current user can, all counts are returned.

If you get past this check, it assumes you're not an Administrator, so it resets all counts to 0, effectively removing the status links.

Note: the "all" and "mine" status links are hard-coded in the get_views() method of the WP_Posts_List_Table Class and aren't filterable.

I quickly tested this on my dev server, first signing in as an Admin, and then as an Author. It worked as expected, but be sure to test thoroughly.

4
  • 1
    Thank you for your response. The Published and Trash links are gone. However, I still have the All link, even though its counter is at zero, the link is still active and it brings me to the list of all the posts. Hmm... I'm not sure if that's what's appearing on your end as well? – chest_nut Apr 19 '16 at 15:49
  • 1
    Yes. I mentioned that in my answer. The "all" link and the "mine" are hard-coded, not passed through s filter like the others. They can't be removed, only hidden. – darrinb Apr 19 '16 at 17:05
  • 1
    I see, thank you @darrinb . Guess I will just hide the All link then. Thanks a lot. I'm still new on WP development I really am wanting to learn as much as I can. Anyway, thanks again, really appreciate it. – chest_nut Apr 20 '16 at 0:48
  • 1
    No problem! Glad I could help! If this worked for you, be sure to accept the answer so others know. – darrinb Apr 20 '16 at 2:17

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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