Showing custom taxonomy column in custom posts type listings
Asked Answered
J

5

18

I have created a custom post type named banners. Thereby I register a new taxonomy called location that specifies on which page the banner is to be shown. Everything is great however when I click on the custom posts type 'Banner' in the admin window I see all the banners created however the table does not have a column for the taxonomy 'Location'.

In other words I want to be able to see what location the banner is in, in the banners listing.

Johnnie answered 11/11, 2011 at 7:40 Comment(0)
C
45

For those interested, the register_taxonomy register_taxonomy function, as of WordPress 3.5, now offers an argument for show_admin_column (false by default). Set to true, it automatically displays the taxonomy column in the admin.

Conakry answered 24/2, 2013 at 20:26 Comment(3)
this is solution I was looking for, there are lots of more complicated ones out there folks!Unsegregated
This should be the accepted answer!Bonina
I found example codes in this post - justintadlock.com/archives/2011/06/27/…Monosome
V
9

You can use the manage_post-type_custom_column and manage_edit_post-type_columns filters to add your taxonomy column to the post type listing.

add_action( 'admin_init', 'my_admin_init' );
function my_admin_init() {
    add_filter( 'manage_edit-banner_columns', 'my_new_custom_post_column');
    add_action( 'manage_banner_custom_column', 'location_tax_column_info', 10, 2);
}

function my_new_custom_post_column( $column ) {
    $column['location'] = 'Location';

    return $column;
}

function location_tax_column_info( $column_name, $post_id ) {
        $taxonomy = $column_name;
        $post_type = get_post_type($post_id);
        $terms = get_the_terms($post_id, $taxonomy);

        if (!empty($terms) ) {
            foreach ( $terms as $term )
            $post_terms[] ="<a href='edit.php?post_type={$post_type}&{$taxonomy}={$term->slug}'> " .esc_html(sanitize_term_field('name', $term->name, $term->term_id, $taxonomy, 'edit')) . "</a>";
            echo join('', $post_terms );
        }
         else echo '<i>No Location Set. </i>';
}
Vomer answered 12/11, 2011 at 4:5 Comment(2)
Just a note that the manage_post-type_custom_column filter only works for Custom Post Types where hierarchical => true (like Pages). For CPTs where hierarchical => false (like Posts) you should use the very similar filter manage_post-type_posts_custom_column. So, in this specific example, you'd change line 4 to read: add_action( 'manage_banner_posts_custom_column', 'location_tax_column_info', 10, 2); More info hereMaurinemaurise
Just a note that the hook name for the column content is manage_{$post->post_type}_posts_custom_column. The example code above is missing the _posts portion of that.Decrescent
P
8
 //what version of wordpress you are using
 //since wp 3.5 you can pass parameter show_admin_column=>true
 // hook into the init action and call create_book_taxonomies when it fires
 add_action( 'init', 'create_book_taxonomies', 0 );

 // create two taxonomies, genres and writers for the post type "book"
 function create_book_taxonomies() {
 // Add new taxonomy, make it hierarchical (like categories)
$labels = array(
    'name'              => _x( 'Genres', 'taxonomy general name' ),
    'singular_name'     => _x( 'Genre', 'taxonomy singular name' ),
    'search_items'      => __( 'Search Genres' ),
    'all_items'         => __( 'All Genres' ),
    'parent_item'       => __( 'Parent Genre' ),
    'parent_item_colon' => __( 'Parent Genre:' ),
    'edit_item'         => __( 'Edit Genre' ),
    'update_item'       => __( 'Update Genre' ),
    'add_new_item'      => __( 'Add New Genre' ),
    'new_item_name'     => __( 'New Genre Name' ),
    'menu_name'         => __( 'Genre' ),
);

$args = array(
    'hierarchical'      => true,
    'labels'            => $labels,
    'show_ui'           => true,
    'show_admin_column' => true,
    'query_var'         => true,
    'rewrite'           => array( 'slug' => 'genre' ),
);

register_taxonomy( 'genre', array( 'book' ), $args );
 }
Percent answered 15/1, 2014 at 9:20 Comment(1)
In Wordpress 5.0+ under in the $args = array this needs to be added so it shows in the admin area when adding/editing a post: 'show_in_rest' => true,Arrange
L
0

In addition to Jonathan Wold answer, you can add the ability to filter by your custom taxonomy like this:

add_action('restrict_manage_posts', 'filter_post_type_backend_by_taxonomies', 99, 2);

function filter_post_type_backend_by_taxonomies($post_type, $which) {
    if( 'your_post_type' !== $post_type) {
        return;
    }
    
    $taxonomies = array( 'your_custom_taxonomy' );
    
    foreach( $taxonomies as $taxonomy_slug ) {
        $taxonomy_obj = get_taxonomy( $taxonomy_slug );
        $taxonomy_name = $taxonomy_obj->labels->name;
        
        $terms = get_terms($taxonomy_slug);
        
        echo "<select name='{$taxonomy_slug}' id='{$taxonomy_slug}' class='postform'>";
        echo '<option value="">' . sprintf( esc_html__( 'Show all %s', 'domain-name' ), $taxonomy_name) . '</option>';
        foreach ( $terms as $term ) {
            printf(
                    '<option value="%1$s" %2$s>%3$s (%4$s)</option>',
                    $term->slug,
                    ( ( isset( $_GET[$taxonomy_slug] ) && ( $_GET[$taxonomy_slug] == $term->slug ) ) ? ' selected="selected"' : '' ),
                    $term->name,
                    $term->count
            );
            }
        echo '</select>';
    }
}
Liam answered 18/10, 2020 at 8:10 Comment(0)
O
0

2024 Update

When registering custom taxonomies with the register_taxonomy() function and you want a custom admin column for it, you can follow different approaches based on what you are trying to achieve:

1. Automated column method

The easiest way, as others described is to set the show_admin_column parameter to true while registering the taxonomy. This will make WordPress create the admin column and render all the terms automatically for each row.

add_action( 'init', 'so8090996_register_taxonomy' );
function so8090996_register_taxonomy() {
                                               /* or 'post' / 'page' */
    register_taxonomy( 'your_custom_taxonomy', array( 'your_post_type' ), array(
        'labels'                => array( /* ... */ ),
        'hierarchical'          => true,
        'public'                => true,
        'show_ui'               => true,
        'show_admin_column'     => true, // create column automatically
        /* ... */
    );
}

a) If you don't want to customize the rendered terms

You are finished. Everything is rendered automatically.

b) If you want to customize the rendered terms in the rows

Columns created this automated way are NOT seen as custom columns by WordPress, so you can NOT render values (terms) for the rows with ANY of the manage_[...]_custom_column actions.

However, you can use the post_column_taxonomy_links filter to override the rendering of term links in this column:

add_filter( 'post_column_taxonomy_links', 'so8090996_custom_taxonomy_links', 10, 3 );
function so8090996_custom_taxonomy_links( $term_links, $taxonomy, $terms ) {
    /* This function filters all the taxonomies in all post lists, so only edit yours */
    if ($taxonomy === 'your_custom_taxonomy' && is_array( $terms ) ) {
        $term_links = array();
        foreach ( $terms as $t ) {
            $term_name = 'Custom ' . $t->name; // modify term name as you want
            
            $term_link_params = array(
                'post_type' => 'your_post_type', /* CHANGE to 'post'/'page' or any CPT */
                $t->taxonomy => $t->slug,
            );
            $term_link = add_query_arg( $term_link_params, 'edit.php' );

            $term_links[] = sprintf( '<a href="%s">%s</a>', $term_link, $term_name );
        }
        return $term_links;
    }

    /* Return all others */
    return $term_links;
}

2. Manual column creation and data rendering

If you want even more customization, and you want full control over the rendering of terms, you can create the column manually and use the manage_[...]_custom_column actions to render the column contents in each row.

  1. First, make sure the admin column is not rendered automatically, by setting the show_admin_column to false in register_taxonomy().

  2. Create the column with the manage_posts_columns (for all lists) or manage_{$post_type}_posts_columns (for specific post type) filter.

    add_filter( 'manage_{your_post_type}_posts_columns', 'so8090996_create_custom_column' );
    function so8090996_create_custom_column( $columns ) {
        $columns['your_custom_taxonomy'] = 'Column Title';
        return $columns;
    }
    

    WARNING: If you use 'taxonomy-your_custom_taxonomy' key for adding the column above, WordPress will think it is a taxonomy column automatically created by itself, an you will - again - not be able to render the column values with manage_[...]_custom_column actions, only edit them with the post_column_taxonomy_links filter, just like in 1./b) method.

  3. Render the column values with the manage_posts_custom_column (for all lists) or manage_{$post->post_type}_posts_custom_column (for specific post type) action.

    add_action( 'manage_{your_post_type}_posts_custom_column', 'so8090996_manage_custom_column', 10, 2 );
    function so8090996_manage_custom_column( $column_name, $post_id ) {
        if ( $column_name === 'your_custom_taxonomy' ) {
            $terms = get_terms( array (
                'taxonomy' => 'your_custom_taxonomy',
                'object_ids' => $post_id,
                /* any WP_Term_Query params */
            ) );
    
            $term_links = array();
            foreach ( $terms as $t ) {
                $term_name = 'Custom ' . $t->name; // modify term name as you want
    
                $term_link_params = array(
                    'post_type' => 'your_post_type', /* CHANGE to 'post'/'page' or any CPT */
                    $t->taxonomy => $t->slug,
                );
                $term_link = add_query_arg( $term_link_params, 'edit.php' );
    
                $term_links[] = sprintf( '<a href="%s">%s</a>', $term_link, $term_name );
            }
    
            echo implode( ', ', $term_links );
        }
    }
    
Ostensorium answered 24/6 at 18:15 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.