By Mark


2019-03-14 14:50:20 8 Comments

I have a custom post type called dogs. Within the Add Dog interface, I have a radio-button group that gives choices for color, which are added to the new dog post as meta data. There are about five color choices.

I also have the color field set up to be displayed as a sortable column in the admin area, when I look at all my dog posts. The sorting works as expected.

So now what I'd like to do is have each color value be a link which I can click, and when I click it, it filters all dog posts by that color value. So if I click "brown," I'll see a list of only brown dogs.

On Pages, we can click on an Author's name and see Pages filtered by that author. This is what I'd like, for color and the CPT dog.

Currently the links are added in the column like this:

case 'dogbreed': 
    if( $x = get_post_meta( $post_id, 'dog_breed', true ) ) {
        echo '<a href=http://localhost/wordpress/wp-admin/edit.php?dogbreed=' . $x . '>' . $x . '</a>'; 
    }
    break;

I prefer to just do this in functions.php, and not use an enterprise plugin. Is there a way to do this?

3 comments

@Andy Macaulay-Brook 2019-03-15 18:35:54

For comparison, I made a post type of dog with both a custom field dog_colour and a taxonomy dog_colour.

With both added as admin columns, we get:

enter image description here

The taxonomy terms are automatically linked with a query variable, so clicking on one goes to a URL like http://example.com/wp-admin/edit.php?post_type=dog&dog_colour=red and only shows those dogs with the term red.

And for your data, a taxonomy would seem to be the right thing to use: all dogs have a colour and colour is something you might want to list dogs by.

But, there will be other use cases where a custom field is appropriate and where you might want to make the field clickable in the admin column to show all posts with that field value, so here goes...

Unlike taxonomies, custom fields don't automatically get a query var, so we add one like this:

function wpse331647_custom_query_vars_filter( $vars ) {
    $vars[] .= 'dogcolour';
    $vars[] .= 'dogbreed';
    return $vars;
}

add_filter( 'query_vars', 'wpse331647_custom_query_vars_filter' );

Now, calling a URL with ?dogcolour=red will set up a variable called dogcolour with the value red within the WP query.

We then need to modify the WP query to take account of this variable when it is present, but only in the admin and only when the query is for dogs:

add_action( 'pre_get_posts', 'wpse331647_alter_query' );

function wpse331647_alter_query( $query ) {

    if ( !is_admin() || 'dog' != $query->query['post_type'] )
        return;

    if ( $query->query_vars['dogcolour'] ) {
        $query->set( 'meta_key', 'dog_colour' );
        $query->set( 'meta_value', $query->query_vars['dogcolour'] );
    }

    if ( $query->query_vars['dogbreed'] ) {
        $query->set( 'meta_key', 'dog_breed' );
        $query->set( 'meta_value', $query->query_vars['dogbreed'] );
    }

}

And now, if we go to http://example.com/wp-admin/edit.php?post_type=dog&dogcolour=red we get:

enter image description here

The final step is for you to modify however you currently add the field to the admin column so that the field values are links with the correct value in the query string.

Where you currently have:

echo '<a href=http://localhost/wordpress/wp-admin/edit.php? dogcolour=' . $x . '>' . $x . '</a>';

try this instead:

echo '<a href="';
echo admin_url( 'edit.php?post_type=dog&dogcolour=' . urlencode( $x ) );
echo '">';
echo $x;
echo '</a>';

[only broken onto separate lines to help legibility]

PHP's urlencode() handles spaces in your meta values for you, and even URLs. WP's admin_url() will handle the correct domain, protocol/scheme and path to admin for you.

You could make your code more generic by using the post type query var rather than hard-coding it in, of course.

@jsmod 2019-03-15 21:24:05

Would this also work for more than one meta_key? Say, for example, we had dog_colour and dog_breed as custom meta fields. Can variables for both be set in wpse331647_custom_query_vars_filter? And do we just repeat the necessary $query->set in wpse331647_alter_query?

@Andy Macaulay-Brook 2019-03-15 21:26:15

Yep. In the pre_get_posts attached function, test which query variable is set and then alter the query accordingly. I’m on my phone, I’ll edit the answer when I’m back on my laptop.

@jsmod 2019-03-15 21:42:03

Thank you. Now, what if the meta_value had a space in it? For example, let us say we had the dog_breed meta and the value was German Shepherd. Would the link added to the column be able to process the spaces? Because my experiments on a local WordPress installation are giving me something like this for German Shepherd: http://localhost/wordpress/wp-admin/edit.php?dogbreed=German‌​. And just for clarification, the custom meta keys I am playing with are different, but I am presenting them here as dog examples to tie them to the original question.

@jsmod 2019-03-15 21:45:28

This is the code I am using to echo the link in the table columns (modified to go with the dog example): case 'dogbreed': { if( $x = get_post_meta( $post_id, 'dog_breed', true ) ) echo '<a href=http://localhost/wordpress/wp-admin/edit.php?dogbreed=' . $x . '>' . $x . '</a>'; break; }. It shows, it's clickable, but it ignores spaces in the meta_key value.

@jsmod 2019-03-15 22:00:27

Another question (sorry if they are too much, but your answer is very good and now I am experimenting with all sorts of things): what if the meta_value is a hyperlink? To tie this to the dog example, say we had a meta_key for Breeder Website, with values like http://ukdogbreeder.com. So the variable $x in my above-mentioned example would be http://ukdogbreeder.com for this meta_key, meaning the resulting link is: http://localhost/wordpress/wp-admin/edit.php?breederwebsite=‌​http://ukdogbreeder.‌​com

@Andy Macaulay-Brook 2019-03-15 22:23:10

The url encode function I've used will sort out both spaces and URLs for you.

@Andy Macaulay-Brook 2019-03-15 22:24:10

And if the answer's very good, then by all means tick it ;-)

@Andy Macaulay-Brook 2019-03-15 22:30:22

And I've modified the code to account for multiple columns.

@jsmod 2019-03-15 23:07:38

I would have ticked your answer long ago if this were my question, but alas, I can only up-vote it :) @Mark was the original poster, I just let my curiosity get out of hand. Thank you for updating the answer. I tried applying it but I think I broke something somewhere as my local installation has started behaving erratically. I will continue fiddling and see what happens. Anyway, hopefully Mark will find a solution to his question in your answer.

@Andy Macaulay-Brook 2019-03-15 23:08:53

Ha - I didn't notice the name!

@jsmod 2019-03-15 23:16:27

It happens :) By the way, I just noticed that the original question was edited to add the lines of code I used as an example. Should that be removed since it is likely not what he was using? (Unless he was following the exact tutorial I was...)

@jsmod 2019-03-16 00:25:53

Update: After fiddling, I managed to fix the issue I was getting by changing the link to echo '<a href="' . get_admin_url() .'edit.php?dogcolour=' . urlencode( $x ) . '">' . $x . '</a>';. Now all meta values show in their respective columns, and they can be filtered/sorted regardless of their content. Using $field->escaped_value(); in the link seemed to be the culprit in my case. It messed up the table view and hid some meta values.

@Andy Macaulay-Brook 2019-03-16 00:34:16

My bad. I’ve changed it to $x

@jsmod 2019-03-16 00:53:45

Oh, I thought only $field was a placeholder for my own variable $x. So, I copied it into my code as $x->escaped_value(); because I thought you put in escaped_value for an important reason (to deal with the spaces and urls).

@Qaisar Feroz 2019-03-14 16:56:51

Based on @ Andy Macaulay-Brook comment on your question you can try this:

add_action( 'restrict_manage_posts',  'filter_dogs_by_color' ;

// Filter Dogs by Color
function filter_dogs_by_color( $post_type ) {
        if ( 'dog' !== $post_type ) return;    // Replace 'dog' with your post_type

        $taxonomy = 'color'; // Replace 'color' with your taxonomy slug

        $info_taxonomy = get_taxonomy($taxonomy);
        $selected      = isset($_GET[$info_taxonomy->query_var]) ? $_GET[$info_taxonomy->query_var] : '';

        wp_dropdown_categories(array(
             'show_option_all' => __("Show All {$info_taxonomy->label}"),
             'taxonomy'        => $taxonomy,
             'name'            => $info_taxonomy->query_var,
             'orderby'         => 'name',
             'selected'        => $selected,
             'hide_empty'      => true,
              'value_field'   => 'slug'
                )
        );


}

@Andy Macaulay-Brook 2019-03-15 22:25:05

Yes, this will add a filter dropdown for a taxonomy but the OP is after links on the column fields and my point was that taxonomies already show those without extra coding.

@Jurgen Oldenburg 2019-03-14 15:36:32

Take a look at Admin Columns Pro plugin, it gives you complete control over all columns and fields. Even images from custom fields work perfectly.

https://www.admincolumns.com/

They have a free version also:

https://wordpress.org/plugins/codepress-admin-columns/

@Andy Macaulay-Brook 2019-03-14 15:54:05

Hi, thanks for contributing but do have a look at the site guidelines for what is on-topic here: help center Specifically, we're all about helping people solve problems with their own code in the context of WordPress, so third part plugins are considered off-topic.

@Jurgen Oldenburg 2019-03-14 15:59:55

@AndyMacaulay-Brook Oke thanks for the tip, although helping people solve a problem without code but with a plugin that suits their situation seems like a better solution than writing massive amounts of code to get this question answered ;-)

@Mark 2019-03-14 20:08:13

Thanks but as per my question, I would not like to use a plugin.

Related Questions

Sponsored Content

2 Answered Questions

Make custom post type column sortable

1 Answered Questions

initial sort order for a sortable custom column in admin

  • 2014-12-29 03:01:52
  • Madivad
  • 1906 View
  • 3 Score
  • 1 Answer
  • Tags:   admin sort columns

0 Answered Questions

0 Answered Questions

1 Answered Questions

[SOLVED] Adding HTML tags or css classes to admin columns

1 Answered Questions

Order a custom post type admin screen by a second custom post type title

1 Answered Questions

[SOLVED] Make a custom column sortable, by custom post count

1 Answered Questions

1 Answered Questions

[SOLVED] Sort by post word count in admin area

Sponsored Content