3

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.

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

  • 2
    Would it be easy to change to use a custom taxonomy for colour instead? Then WP will just do all this for you. – Andy Macaulay-Brook Mar 14 at 15:19
  • @AndyMacaulay-Brook Yes, I've considered the possibility for using a custom taxonomy, but I would have to migrate all the current meta data from its field to the new terms. I'm not sure if it would be worth the effort. Good point though. – Mark Mar 14 at 20:07
  • I'm getting the sense that this is not possible if I keep 'color' as a custom meta field, as opposed to switching to a custom taxonomy. Would you all agree? – Mark Mar 14 at 20:11
  • 1
    It’s possible. Just a little complicated. You’ll see that when you add a taxonomy using register_taxonomy that you have a parameter to show the taxonomy in a column on edit.php and the terms are links that do exactly what you want. They use a query string for the parameter that is built-in to WP, ?Dog_color=blue, for example. For a custom field we need to write code to create a custom query argument and also to turn your column of fields into links using that argument. If I have time I’ll try and code you an answer tomorrow. – Andy Macaulay-Brook Mar 14 at 20:13
  • I'm working out an answer, but could you post the section of code you've used to add the colours to the admin column? Then I can match my code for turning them into links. – Andy Macaulay-Brook Mar 15 at 17:20
2

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.

  • 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? – jsmod Mar 15 at 21:24
  • 1
    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. – Andy Macaulay-Brook Mar 15 at 21:26
  • 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 Mar 15 at 21:42
  • 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 Mar 15 at 21:45
  • 1
    The url encode function I've used will sort out both spaces and URLs for you. – Andy Macaulay-Brook Mar 15 at 22:23
0

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/

  • 1
    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. – Andy Macaulay-Brook Mar 14 at 15:54
  • @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 ;-) – Jurgen Oldenburg Mar 14 at 15:59
  • 1
    Thanks but as per my question, I would not like to use a plugin. – Mark Mar 14 at 20:08
0

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'
                )
        );


}
  • 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. – Andy Macaulay-Brook Mar 15 at 22:25

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.