2

I want to add thumbnail to WordPress default recent posts widget, and I want to do it using any available filter. Is there any filter know to this subject/topic

1
  • There is no direct filter to modify/add any data in the default WordPress recent posts widget.
    – bravokeyl
    Aug 6, 2016 at 11:49

2 Answers 2

5

Here's one way to do it through the the_title filter. We can limit the scope to the Recent Posts widget, by initialize it within the widget_posts_args filter and then remove it again after the loop.

/**
 * Recent Posts Widget: Append Thumbs
 */
add_filter( 'widget_posts_args', function( array $args )
{
    add_filter( 'the_title', 'wpse_prepend_thumbnail', 10, 2 );
    add_action( 'loop_end',  'wpse_clean_up' );
    return $args;
} );

where we define

function wpse_prepend_thumbnail( $title, $post_id )
{
    static $instance = 0;

    // Append thumbnail every second time (odd)
    if( 1 === $instance++ % 2 && has_post_thumbnail( $post_id ) )
        $title = get_the_post_thumbnail( $post_id ) . $title;

    return $title;
} 

and

function wpse_clean_up( \WP_Query $q )
{
    remove_filter( current_filter(), __FUNCTION__ );
    remove_filter( 'the_title', 'wpse_add_thumnail', 10 );
} 

Note that because of this check in the WP_Widget_Recent_Posts::widget() method:

get_the_title() ? the_title() : the_ID()

the the_title filter is applied two times for each item. That's why we only apply the thumbnail appending for the odd cases.

Also note that this approach assumes non empty titles.

Otherwise it's more flexible to just create/extend a new widget to our needs instead.

6
  • Is there a way to select only post type "post?" My widget has been selecting a custom post type as well that does not need to be showing. The weird thing is that it has only been happening on Category pages, posts and pages show correctly.
    – jonbon
    Dec 20, 2016 at 12:44
  • You might have some plugin/theme code that's modifying your widget output, e.g. via pre_get_posts hook. You can adjust the $args in the widget_posts_args filter, e.g. $args['post_type'] = 'post'; @jonbon
    – birgire
    Dec 20, 2016 at 12:47
  • @birgire awesome, I'm going to try that now.
    – jonbon
    Dec 20, 2016 at 12:47
  • @birgire so it should look like add_filter( 'widget_posts_args', function( array $args['post_type'] = 'post'; )
    – jonbon
    Dec 20, 2016 at 12:49
  • e.g. add_filter( 'widget_posts_args', function( $args ) { $args['post_type'] = 'post'; return $args; } ); if that doesn't work you might need to use the pre_get_posts hook with some late priority, to override the code that's modifying your WP_Query in the widget. But better yet to find the code in your setup that's changing this. This would be better served as a new question. @jonbon
    – birgire
    Dec 20, 2016 at 12:53
0

No filter available.


Checking the /wp-includes/widgets/class-wp-recent-posts-widget.php the following is the code that outputs the widget

$r = new WP_Query( apply_filters( 'widget_posts_args', array(
    'posts_per_page'      => $number,
    'no_found_rows'       => true,
    'post_status'         => 'publish',
    'ignore_sticky_posts' => true
) ) );

if ($r->have_posts()) :
?>
<?php echo $args['before_widget']; ?>
<?php if ( $title ) {
    echo $args['before_title'] . $title . $args['after_title'];
} ?>
<ul>
<?php while ( $r->have_posts() ) : $r->the_post(); ?>
    <li>
        <a href="<?php the_permalink(); ?>"><?php get_the_title() ? the_title() : the_ID(); ?></a>
    <?php if ( $show_date ) : ?>
        <span class="post-date"><?php echo get_the_date(); ?></span>
    <?php endif; ?>
    </li>
<?php endwhile; ?>
</ul>
<?php echo $args['after_widget']; ?>
<?php
// Reset the global $the_post as this query will have stomped on it
wp_reset_postdata();

endif;

Which obviously has no filter to insert some thumbnail or anything in the loop.

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.