cabrerahector / wordpress-popular-posts

WordPress Popular Posts - A highly customizable WordPress widget that displays your most popular posts.
https://wordpress.org/plugins/wordpress-popular-posts/
GNU General Public License v2.0
279 stars 83 forks source link

Use Author Avatar if possible before default image #163

Closed jamminjames closed 6 years ago

jamminjames commented 6 years ago

I've communicated with the plugin author before about this idea, but can't find the thread here or on the Wordpress support page, so I'll start a new one.

I think a big improvement would be an option to use a post's author avatar before going to the default image, if there's no post image. We have author blog posts on our site that display only the author avatar and no other images, so that's why this feature would be nice.

I've found a simple way to do it. I happen to use the WP User Avatar plugin, so I'm hooking into that avatar, but you could use the standard WP avatar.

In the includes/class-wordpress-popular-posts-image.php file, in the elseif ( "first_image" == $source ) section of the private function get_image_file_paths (since I have "First image on post" chosen in the "Tools" settings of the plugin), I made these changes:

Just under global $wpdb; I added $post_author_id = get_post_field( 'post_author', $id );

Then this section just before the closing } for if ( $content = $wpdb->get_var( "SELECT post_content FROM {$wpdb->posts} WHERE ID = {$id};" ) ) { :

elseif ( has_wp_user_avatar($post_author_id) ) {
    $file_path = get_wp_user_avatar_src($post_author_id, 48);  // for 48 pixel size image
    return $file_path;
}

However, if not using the WP User Avatar plugin, this works:

else {
    $file_path = get_avatar_url($post_author_id, 48);
    return $file_path;
}

... and this actually works even when you're using the plugin.

cabrerahector commented 6 years ago

Hey there!

I've communicated with the plugin author before about this idea, but can't find the thread here or on the Wordpress support page (...)

Here, I found it for you: Hook into default image logic and use author avatar if no image instead?

I think a big improvement would be an option to use a post's author avatar before going to the default image, if there's no post image.

In your particular use case it might make sense but I believe the majority of people using the plugin right now will not be expecting to see the author avatar instead of the post thumbnail - they configured the plugin to retrieve the post thumbnail and some may even set a custom default thumbnail, instead they would be seeing the author avatar. What will happen next is people will come to ask how can I set a default image / have WPP use my custom default thumbnail instead of the author avatar?

This is the very reason why I implemented WPP's filter hooks: to give users the freedom to modify the plugin when what WPP offers out-of-the-box doesn't completely cut the deal (and this was actually my answer at WordPress.org).

jamminjames commented 6 years ago

I don't really see how to use filter hooks in the WPP_Image class, how would I do that?

I do still think it would be a nice option a lot of users would like, and your concern about using the post thumbnail first (as well as first image, or whatever), is taken care of, the way I have it set up. Author avatar becomes just be the second to last thing the plugin would pick up, before the default image. And this could be implemented as an option in settings.

Anyway, thanks. You had suggested I try to do it, and I mainly just wanted to let you know how I got it working, in case you wanted to think about adding it.

cabrerahector commented 6 years ago

I don't really see how to use filter hooks in the WPP_Image class, how would I do that?

You don't really need to use it. Here's how I would do it:

/**
 * Customizes WPP's HTML markup
 */
function my_custom_single_popular_post( $post_html, $p, $instance ){

    // Post has a thumbnail, retrieve it
    if ( has_post_thumbnail( $p->id ) ) {
        $thumbnail = '<img src="' . get_the_post_thumbnail_url( $p->id, array(48, 48) ) . '" alt="' . esc_attr( $p->title ) . '">';
    } // Post doesn't have a thumbnail assigned, show author's avatar instead
    else {
        $thumbnail = '<img src="' . get_wp_user_avatar_src( $p->uid, 48 ) . '" alt="' . esc_attr( $p->title ) . '">';
    }

    $output = '<li>' . $thumbnail . '<a href="' . get_permalink($p->id) . '" title="' . esc_attr($p->title) . '">' . $p->title . '</a></li>';   

    return $output;

}
add_filter( 'wpp_post', 'my_custom_single_popular_post', 10, 3 );

This way you don't have to modify WPP's code directly (which I advise against since future plugin updates will undo your changes anyways) and you get what you want. Two birds with one stone :P

jamminjames commented 6 years ago

Thanks, Hector, I of course do agree that it should be done with the filter hook instead. However, this does not do what I want. In the plugin setup, I have chosen the "First image" option, not "Featured image", so it's not a missing post thumbnail I want to look for, but a missing first image. Also, if there is no wp_user_avatar, I do want the default image used. This results in a lot of ugly gravatars instead.

I think I do need to use filter hooks in the WPP_Image class somehow.

cabrerahector commented 6 years ago

If you want to use the first image found on post content instead of the post thumbnail, then you could use something like this to get the first image found in post content, and if none is found then fallback to the author avatar image.

jamminjames commented 6 years ago

But your plugin already finds the first image (if you pick that option), so it seems strange to have to find the first image with code outside the plugin. What I really need is a way to interrupt the plugin logic that finds the default image when there is no first image, and tell it to use the avatar if there is one instead, and if not, THEN the default image. How to hook in at that point is the question.

cabrerahector commented 6 years ago

Yes, stock WPP already does this for you and if it doesn't find any images it'll use the default thumbnail instead. The WPP_Image class, which manages all of this, doesn't have a hook you could use to replace the default thumbnail with a different image -otherwise I would have said something about it long ago- so you have to roll up your own solution instead.

So, you can either go with any of the suggestions I've shared with you here and at WordPress.org or you could hack into WPP to include your custom code.

If you need help with something specific that I haven't covered yet, please don't hesitate to ask.

jamminjames commented 6 years ago

Any chance you will be writing a hook into the WPP_Image class at some point?

cabrerahector commented 6 years ago

If more people show interest in it and / or more use cases where that would be actually really helpful for the majority of users out there arise then yeah, I'll consider it.