6

I'd like to be able to filter my sidebar widgets (tag cloud, category, archive) to only show those tags/categories/months that apply to a given author on the author template.

What is the correct way to filter or modify these widgets? I found this page in the codex but it doesn't seem that the native functions for any of the widgets can accept an author id as a parameter.

2
  • Can your authors add their own categories? Are these what you'd want displayed when filtered by author ID? Or just display the category if they've posted in it?
    – James Kemp
    Mar 18, 2014 at 13:30
  • @JamesKemp Yes - using the answer here I've allowed them to create categories. Ideally just display categories if they have posts in them.
    – javy
    Mar 18, 2014 at 14:40

3 Answers 3

3
+50

It's a bit unwieldy to just grab all posts by an author and filter through them to only return a category list. If you wish to use the default widgets in the sidebar and have them filtered by the author only on the author template then I'd suggest using the following approach.

First, filter the tag and category widget queries for categories and tags.

add_filter( 'widget_tag_cloud_args', 'filter_categories_by_author' );
add_filter( 'widget_categories_dropdown_args', 'filter_categories_by_author' );
add_filter( 'widget_categories_args', 'filter_categories_by_author' );
function filter_categories_by_author( $args ){
    // only process if on the author template
    if( is_author() ){
        $author_id = get_the_author_meta( 'ID' );
        $taxonomy = !empty( $args['taxonomy'] ) ? $args['taxonomy'] : 'category';
        // filter by including only IDs associated to the author
        $args['include'] = get_taxonomy_ids_by_author( $author_id, $taxonomy );
    }
    return $args;
}

Then using the dependent method to retrieve taxonomy ids filtered by the user ID.

function get_taxonomy_ids_by_author( $user_id, $taxonomy = 'category' ){
    global $wpdb;
    return $wpdb->get_col( $wpdb->prepare( "
        SELECT DISTINCT(terms.term_id) as ID
        FROM $wpdb->posts as posts
        LEFT JOIN $wpdb->term_relationships as relationships ON posts.ID = relationships.object_ID
        LEFT JOIN $wpdb->term_taxonomy as tax ON relationships.term_taxonomy_id = tax.term_taxonomy_id
        LEFT JOIN $wpdb->terms as terms ON tax.term_id = terms.term_id
        WHERE 1=1 AND (
            posts.post_status = 'publish' AND
            posts.post_author = %d AND
            tax.taxonomy = '%s' )
        ORDER BY terms.name ASC
    ", $user_id, $taxonomy ) );
}

source: https://gist.github.com/codearachnid/9655690

3
  • I awarded you the bounty because I think your solution is the most efficient (and it was about to expire) but the code is only working for categories, tags and archives are still the same. Any thoughts?
    – javy
    Mar 26, 2014 at 11:00
  • Thank you @javy. When I tested this it was for categories and tag cloud widgets; however, I did not test against the archive widget. I'll look into what hooks those have specifically and update with hooks appropriate there. In theory it should just be a matter of finding the right hook. Mar 26, 2014 at 11:14
  • No problem, this has been a great help!
    – javy
    Mar 26, 2014 at 14:00
1

There is no built in way to do this, and I don't know that it's been tried before. That being said, the tools are all there, you have to put them together.

You can get the current User ID with $userid = wp_get_current_user()

You can then get all posts by a user with $posts = WP_Query('author='.$userid)

Then loop through all posts by the author, and append the categories of each post in an array. For example,

$allCategories = Array();
foreach($posts as $post){
    array_merge($allCategories, wp_get_post_categories($post->ID))
}

Then use the array_unique() function to remove duplicates.

Lastly, foreach through each category, and get a link to the category with get_category_link()

1
  • This seems like it could certainly do the trick but, having no empirical evidence, I think @codearachnid's solution is probably a more efficient means of doing so.
    – javy
    Mar 26, 2014 at 11:02
0

I haven't tested this but you could try

add_action('pre_get_posts', callback);
function callback( &$query )
{
    if ( is_author() ) {
        $query->set('author', get_the_author_meta('ID') );
    }
}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.