WordPress.org

Make WordPress Core

Opened 22 months ago

Closed 19 months ago

Last modified 17 months ago

#21240 closed enhancement (fixed)

Ability to "Turn On" Native custom columns for registered custom taxonomies

Reported by: jtsternberg Owned by: nacin
Milestone: 3.5 Priority: normal
Severity: normal Version:
Component: Taxonomy Keywords: has-patch commit
Focuses: Cc:

Description

I believe it would be very beneficial to have an argument for displaying custom columns for registered custom taxonomies (register_taxonomy). Attached is a class to get it started for hierarchical taxonomies. Would need tag-like taxonomy support added.

Attachments (11)

custom-taxonomy-columns.php (1.8 KB) - added by jtsternberg 22 months ago.
tax-columns.png (41.5 KB) - added by jtsternberg 22 months ago.
This is what the output would look like in theory.
21240.diff (7.2 KB) - added by jtsternberg 21 months ago.
Incorporating 'show_taxonomy_columns' in the register_post_type function as well as setting up the columns
21240.2.diff (9.0 KB) - added by jtsternberg 21 months ago.
Ok I've incorporated tags and categories into the new API and moved the column header array creation to WP_Post_List_Table
21240.3.diff (8.4 KB) - added by jtsternberg 21 months ago.
One more diff where I add the 'show_taxonomy_columns' taxonomies to an object variable for access in the other methods
21240.4.diff (8.7 KB) - added by jtsternberg 21 months ago.
Add filter to allow plugins/themes to modify/add/remove taxonomy columns
21240.5.diff (6.3 KB) - added by SergeyBiryukov 21 months ago.
21240.6.diff (6.3 KB) - added by SergeyBiryukov 21 months ago.
21240.7.diff (4.8 KB) - added by nacin 20 months ago.
21240.8.diff (5.2 KB) - added by nacin 20 months ago.
21240.9.patch (591 bytes) - added by ocean90 20 months ago.

Download all attachments as: .zip

Change History (52)

comment:1 follow-up: scribu22 months ago

We talked about this in IRC. The idea is to make it easy for custom taxonomies to generate columns on CPT WP_List_Table screens, just like the Categories and Tags columns on wp-admin/edit.php

Here's my proposal:

register_taxonomy( 'presentation', 'presentation_type', array(
  ...
  'show_admin_column' => true
) );

This would create a 'Presentations' column in WP Admin -> Presentations.

And the implementation (as a plugin): https://gist.github.com/3098902

Last edited 22 months ago by scribu (previous) (diff)

jtsternberg22 months ago

This is what the output would look like in theory.

comment:2 in reply to: ↑ 1 jtsternberg22 months ago

Here's my proposal:

register_taxonomy( 'presentation', 'presentation_type', array(
  ...
  'show_admin_column' => true
) );

This would create a 'Presentations' column in WP Admin -> Presentations.

And the implementation (as a plugin): https://gist.github.com/3098902

From your estimation, how close is this to being complete? What still needs work?

comment:3 scribu22 months ago

Well, if you have the same taxonomy registered for multiple post types, you can't control on which screens it shows up.

Maybe besides

'show_admin_column' => true

we could also have

'show_admin_column' => array( 'post', 'movie' ) )

which would make it so it shows up only on the post and movie tables.

comment:4 follow-up: jtsternberg22 months ago

I think I may be partial to adding the flag to the register_post_type parameters instead of register_taxonomy. Normal workflow is to add custom taxonomies TO a custom post type rather than the other way around I think. It may be symantics, but what about:

register_post_type( 'movies', array(
  ...
  'show_taxonomy_columns' => array( 'actors', 'locations' ) )
) );

comment:5 scribu22 months ago

My thinking was that you need to register the post type before the taxonomy, but that isn't really a problem, since the column rendering is done much later.

comment:6 in reply to: ↑ 4 wpsmith22 months ago

  • Cc travis@… added

+1 to adding it to CPTs. To me it's more logical workflow and since the screen is a CPT screen. However, it would be even better if it didn't matter.

Replying to jtsternberg:

I think I may be partial to adding the flag to the register_post_type parameters instead of register_taxonomy. Normal workflow is to add custom taxonomies TO a custom post type rather than the other way around I think. It may be symantics, but what about:

register_post_type( 'movies', array(
  ...
  'show_taxonomy_columns' => array( 'actors', 'locations' ) )
) );

comment:7 scribu22 months ago

You bring up a good point. If we store it on the CPT, then it won't work if you a have a user taxonomy.

comment:8 jtsternberg22 months ago

So should it have a separate complementary function for flexibility? something like

register_taxonomy_columns( $taxonomies, $object_types, $args );

comment:9 follow-up: scribu21 months ago

21240.diff looks like a step in the right direction.

  1. Any particular reason for making get_taxonomy_column_headers() a stand-alone function?
  2. What is the purpose of the 'taxonomy_column_header' filter?

jtsternberg21 months ago

Incorporating 'show_taxonomy_columns' in the register_post_type function as well as setting up the columns

comment:10 in reply to: ↑ 9 jtsternberg21 months ago

Replying to scribu:

21240.diff looks like a step in the right direction.

  1. Any particular reason for making get_taxonomy_column_headers() a stand-alone function?
  2. What is the purpose of the 'taxonomy_column_header' filter?
  1. vs rolling it into the get_column_headers() function? No particular reason, just thought it might be cleaner.
  2. The filter will allow you to rename the taxonomy column headers if you want. As is, the Taxonomy column headers will be the $taxonomy_object->label, but with this filter could be changed to anything you wanted. Maybe the the $taxonomy_object->label in
    $empty = !empty( $empty ) ? $empty : __( 'No '. $taxonomy_object->label ); 
    

should have that same filter applied.

comment:11 follow-up: scribu21 months ago

  • Keywords has-patch added

vs rolling it into the get_column_headers() function?

No, vs making it a protected method.

__( 'No '. $taxonomy_object->label )

You can only pass plain strings to __().

But even doing:

sprintf( __( 'No %s' ), $taxonomy_object->label )

won't be good enough. We'll probably have to introduce $taxonomy_object->labels->no_terms.

PS: How about handling the built-in 'categories' and 'tags' columns using this new API?

Last edited 21 months ago by scribu (previous) (diff)

comment:12 in reply to: ↑ 11 jtsternberg21 months ago

Replying to scribu:

vs rolling it into the get_column_headers() function?

No, vs making it a protected method.

Do you envision this being incorporated into class WP_List_Table then?

We'll probably have to introduce $taxonomy_object->labels->no_terms.

I like that idea.

PS: How about handling the built-in 'categories' and 'tags' columns using this new API?

will do.

comment:13 scribu21 months ago

Do you envision this being incorporated into class WP_List_Table then?

Into WP_Post_List_Table for now, but keeping it as a function works too.

jtsternberg21 months ago

Ok I've incorporated tags and categories into the new API and moved the column header array creation to WP_Post_List_Table

jtsternberg21 months ago

One more diff where I add the 'show_taxonomy_columns' taxonomies to an object variable for access in the other methods

comment:14 jtsternberg21 months ago

In 21240.4.dff I added

$this->taxonomy_columns = apply_filters( 'show_taxonomy_columns', $taxonomies, $post_type );

This line allows plugins and themes to filter the taxonomy columns. i.e.

add_filter( 'show_taxonomy_columns', 'add_resource_category_column', 10, 2 );
function add_resource_category_column( $tax_columns, $post_type ) {
	if ( $post_type == 'resources' ) $tax_columns[] = 'resource-categories';
	return $tax_columns;
}

This allows taxonomies registered after the fact to add their columns to post-types.

Last edited 21 months ago by jtsternberg (previous) (diff)

jtsternberg21 months ago

Add filter to allow plugins/themes to modify/add/remove taxonomy columns

SergeyBiryukov21 months ago

comment:15 SergeyBiryukov21 months ago

21240.5.diff is another take.

  • As far as I can see, there's no need for no_items label to be based on menu_name (this wouldn't be localizable). It can fall back to "No Tags" / "No Categories", like the other labels.
  • We should probably keep the existing $posts_columns keys and CSS classes for categories and tags for backwards compatibility.
  • A separate taxonomy_column() method doesn't seem necessary. We could just combine the cases in single_row().
  • I think the taxonomy columns should be added before the comments and date columns.
  • $posts_columns filters should be applied after the taxonomy columns are added, not before.
  • __( $taxonomy_object->label ) is not localizable.
  • taxonomy_column_header filter doesn't seem necessary, we can add it later if needed.
  • taxonomy_column_args filter doesn't seem necessary as well.
  • Some minor edits as per the coding standards.

comment:16 scribu21 months ago

In 21240.5.diff, aren't these lines redundant:

 	46	                'labels' => array( 
 	47	                        'no_items' => __( 'Uncategorized' ), 
 	48	                ), 

?

comment:17 scribu21 months ago

Also, I'm not sure these two lines have the intended effect:

$taxonomies = array_diff( $taxonomies, array( 'category', 'post_tag' ) );
$this->taxonomy_columns = array_merge( array( 'categories', 'tags' ), $taxonomies ); 

You always end up with 'categories' and 'tags', even though they might not be desired.

comment:18 scribu21 months ago

My suggestion would be to transform the taxonomy names into the desired column names later, right before rendering.

SergeyBiryukov21 months ago

comment:19 SergeyBiryukov21 months ago

Replying to scribu:

In 21240.5.diff, aren't these lines redundant:

Currently the category column says "Uncategorized" if there's no categories:
http://core.trac.wordpress.org/browser/tags/3.4.1/wp-admin/includes/class-wp-posts-list-table.php#L613

But it could say "No Categories" as well. Removed from 21240.6.diff for consistency.

You always end up with 'categories' and 'tags', even though they might not be desired.

Thanks, fixed in 21240.6.diff.

Not sure if those empty( $post_type ) checks in lines 274 and 279 (introduced in [12702]) are still needed. With WP_Screen, is it possible to have an empty $post_type there?

My suggestion would be to transform the taxonomy names into the desired column names later, right before rendering.

My concern was that a plugin or custom code might rely on categories or tags array key when hooking to the manage_posts_columns filter.

comment:20 jtsternberg20 months ago

Any word on this ticket? Would LOVE to see it in 3.5!

comment:21 scribu20 months ago

  • Type changed from feature request to enhancement
case ( in_array( $column_name, $this->taxonomy_columns ) ) : 

That is absolutely wicked! :D

Instead of this:

$custom_taxonomies = array_diff( $taxonomies, array( 'category', 'post_tag' ) ); 
$this->taxonomy_columns = array_merge( $this->taxonomy_columns, $custom_taxonomies ); 

Why not just set 'show_taxonomy_columns' => array( 'category', 'post_tag' ) when registering the 'post' post type?

Last edited 20 months ago by scribu (previous) (diff)

comment:22 scribu20 months ago

That would also require unsetting the 'categories' and 'tags' columns, which I think would be good, to further narrow the divide between these two native taxonomies and custom ones.

comment:23 jtsternberg20 months ago

Anything I can do to help move this along?

nacin20 months ago

comment:24 follow-up: nacin20 months ago

I've looked at this a number of times but wasn't a diehard fan of the current approach. Couldn't figure out why exactly. Today in IRC I started to offer a review of the patch. There are some smaller things pointed out there like column and taxonomy names conflicting, overly clever code, etc.

I don't think that tying this directly to register_post_type() is particularly useful. First, this kind of modification is just as likely to be done by a plugin adding a taxonomy or otherwise, and not by the plugin registering the post type. Second, it'd probably make more sense for it to be controlled by register_taxonomy(), as that's what is being shown, and they are specifically being registered against a post type anyway. It also makes for really complicated code.

People are used to registering a custom column with one filter (which is very simple to do). Then, they are used to registering a callback against an action to handle output of the column's contents, row by row. Not much harder to do, but it's annoying when all you want is a taxonomy column. You have to replicate the 'tags' code from the list table. That's no fun, and that's really what (I think) this ticket is trying to get at.

So, 21240.7.diff.

It simply abstracts out the code used to render both 'categories' and 'tags' columns. For compatibility with the column management filters, it keeps the names for both of those columns, translating them back and forth as necessary with 'category' and 'post_tag'.

For the other taxonomies, a 'taxonomy-{$taxonomy}' column is automatically registered based on the taxonomy names returned from a new manage_taxonomies_for_{$post_type}_columns filter. If the post type supports categories or tags, those are automatically passed to the filter as a starting point.

The only other thing I would possibly add here is a show_column_on_post_screens-like argument (that name is terrible, I know) to register_taxonomy(). If true, then that taxonomy will be a column by default (passed to the filter the same way categories and tags are now), for all post types to which it is registered.

Last edited 20 months ago by nacin (previous) (diff)

nacin20 months ago

comment:25 in reply to: ↑ 24 nacin20 months ago

Replying to nacin:

The only other thing I would possibly add here is a show_column_on_post_screens-like argument (that name is terrible, I know) to register_taxonomy(). If true, then that taxonomy will be a column by default (passed to the filter the same way categories and tags are now), for all post types to which it is registered.

Added in 21240.8.diff.

comment:26 follow-up: nacin20 months ago

Also, my patches change "No Tags" to a simple em-dash. It avoids introducing a new string for the taxonomy object and, I think, cleans up the screen a bit.

For categories, it still says "Uncategorized" — eventually, we'll remove the one-category requirement and maybe rip that out.

comment:27 nacin20 months ago

  • Owner set to nacin
  • Resolution set to fixed
  • Status changed from new to closed

In [21788]:

Allow easy registration of taxonomy columns on post (and custom post type) list table screens.

To register a column for a list table, use the new manage_taxonomies_for_{$post_type}_columns
filter. Introduces show_admin_column => true for register_taxonomy(), which automatically
displays that column on all associated post types.

props jtsternberg, SergeyBiryukov for initial patches.
fixes #21240.

comment:28 nacin20 months ago

  • Milestone changed from Awaiting Review to 3.5

ocean9020 months ago

comment:29 in reply to: ↑ 26 ; follow-up: ocean9020 months ago

  • Keywords 2nd-opinion removed
  • Resolution fixed deleted
  • Status changed from closed to reopened

Replying to nacin:

Also, my patches change "No Tags" to a simple em-dash. It avoids introducing a new string for the taxonomy object and, I think, cleans up the screen a bit.

For categories, it still says "Uncategorized" — eventually, we'll remove the one-category requirement and maybe rip that out.

I think we can remove the "Uncategorized" part. Currently a post will always have the default category (#14901, #11576). So get_the_terms( $post->ID, 'category') will always return a term. And because it's possible to rename the default category it's not always "Uncategorized".

And if get_the_terms( $post->ID, 'category')` returns nothing, then somebody probably has removed the default category successfully and we should respect it.

21240.9.patch does address this.

comment:30 alexvorn220 months ago

What about the option to sort columns alphabeticaly, by name, or by number?

comment:31 scribu20 months ago

If you mean in WP Admin -> Posts, no, we're not going to do that.

If you mean in WP Admin -> Categories, it's already possible.

comment:32 in reply to: ↑ 29 scribu20 months ago

  • Keywords commit added

+1 for ocean90's reasoning and patch.

comment:33 toscho20 months ago

  • Cc info@… added

comment:34 navjotjsingh20 months ago

  • Cc navjotjsingh@… added

comment:35 nacin20 months ago

  • Resolution set to fixed
  • Status changed from reopened to closed

In [21806]:

Don't show 'Uncategorized' in the category column on edit.php if there are no categories (including the default one). props ocean90. fixes #21240.

comment:36 Bueltge20 months ago

  • Cc frank@… added

great idea/solution. thanks

comment:37 tott19 months ago

The changed behavior in putting previous category and post-tag cases into the default section in r21788 breaks manage_*posts_custom_column hooks if you also want to include custom taxonomies via these hooks as the $taxonomy value is not reset.
The following change fixes this.

Index: wp-admin/includes/class-wp-posts-list-table.php
===================================================================
--- wp-admin/includes/class-wp-posts-list-table.php     (revision 21921)
+++ wp-admin/includes/class-wp-posts-list-table.php     (working copy)
@@ -629,6 +629,7 @@
                        break;
 
                        default:
+                               $taxonomy = null;
                                if ( 'categories' == $column_name )
                                        $taxonomy = 'category';
                                elseif ( 'tags' == $column_name )

comment:38 nacin19 months ago

  • Resolution fixed deleted
  • Status changed from closed to reopened

comment:39 nacin19 months ago

Thanks tott — I had coded this not realizing it was a foreach loop going through the columns, but rather a function call for each column.

comment:40 nacin19 months ago

  • Resolution set to fixed
  • Status changed from reopened to closed

In [21945]:

Reset $taxonomy in single_row's default branch. props tott. fixes #21240.

comment:41 nacin17 months ago

In 23081:

Media list table: Fix the categories column, hidden thanks to a typo. props eddiemoya, fixes #22764. see #21240, #21391.

Note: See TracTickets for help on using tickets.