It has to do with the way the admin post table is constructed. WordPress uses a class WP_Posts_List_Table
to generate and handle that table. You’ll notice that there are a few tables in the admin area similar: Plugins, Terms, Users, etc. They each are their own class, but they all extend from a base class of WP_List_Table
.
manage_edit-{$post_type}_columns
is a more generic filter that is set (but not called) in WP_List_Table
. And, it is actually manage_{$screen->id}_columns
. The callback is the get_columns
method for the table object.
add_filter( "manage_{$this->screen->id}_columns", array( &$this, 'get_columns' ), 0 );
This filter is used by the get_column_headers()
function for retrieving the columns.
So where does manage_{$post_type}_posts_columns
then? Remember the method get_columns()
that is call for the filter manage_{$screen->id}_columns
, the WP_Posts_List_Table
class over-rides the base method from WP_List_Table
. In WP_Posts_List_Table::get_columns()
is where the filter manage_{$post_type}_posts_columns
is called.
To recap:
- A
WP_Posts_List_Table
object is created - It’s parent class
WP_List_Table
adds$this->get_columns()
to the hookmanage_{$screen->id}_columns
- The function
get_column_headers()
calls the filtermanage_{$screen->id}_columns
WP_Posts_List_Table
has over-ridden the methodget_columns()
- Inside of
WP_Posts_List_Table::get_columns()
, it calls the filtermanage_{$post_type}_posts_columns
This is where your manage_{$post_type}_posts_columns hook would run WP_Posts_List_Table::get_columns()
will return the columns and then run the remaining filters formanage_{$screen->id}_columns
Which one should you use? I don’t know. We know that manage_{$post_type}_posts_columns
can only be called for post types, whereas manage_edit-{$post_type}_columns
may match a different admin page (although I’m not sure if it would).