Add featured image to sidebar [closed]

Instead of modifying the sidebar or templates itself, why not create a plugin with a widget that does just what you need. This way

  • you don’t hard code and keeps thing dynamic. This will also allow you to move the widget around at will

  • you keep your templates clean, simple and maintainable

  • do it the correct way. Stuff like widgets, registering custom post types and taxonomies and shortcodes should always be registered in a plugin and not inside a theme

I have written a very basic widget template a while ago which you can check out here. We can use this as a basis to create our custom widget. I will comment the parts where you an modify the output. You can also alter the widget as needed.

Lets look at the plugin (simply create a file in your plugins folder, add this code and activate the plugin)

NOTE: All code is untested and might be buggy. Also, you will need to have PHP 5.4+ installed for this to work

<?php
/*
Plugin Name: Blog Page Featured Image
Plugin URI:  https://wordpress.stackexchange.com/q/219344/31545
Description: Displays the blog page's feaured image in the sidear
Version:     1.0.0
Author:      Pieter Goosen
Author URI:  https://wordpress.stackexchange.com/users/31545/pieter-goosen
License:     GPL2
License URI: https://www.gnu.org/licenses/gpl-2.0.html
*/

class Blog_Page_Featured_Image extends WP_Widget 
{

    public function __construct() 
    {
        parent::__construct(
            'widget_blog_page_featured_image', 
            _x( 'Blog Page Featured Image', 'Blog page featured image' ), 
            [ 'description' => __( 'Displays the featured image for the pge set as blog page.' ) ] 
        );
        $this->alt_option_name="widget_blog_page_featured_image";

        add_action( 'save_post',    [$this, 'flush_widget_cache'] );
        add_action( 'deleted_post', [$this, 'flush_widget_cache'] );
        add_action( 'switch_theme', [$this, 'flush_widget_cache'] );
    }

    public function widget( $args, $instance ) 
    {
        $cache = [];
        if ( ! $this->is_preview() ) {
            $cache = wp_cache_get( 'widget_bpfi', 'widget' );
        }

        if ( ! is_array( $cache ) ) {
            $cache = [];
        }

        if ( ! isset( $args['widget_id'] ) ) {
            $args['widget_id'] = $this->id;
        }

        if ( isset( $cache[ $args['widget_id'] ] ) ) {
            echo $cache[ $args['widget_id'] ];
            return;
        }

        ob_start();

        $title          = ( ! empty( $instance['title'] ) ) ? $instance['title'] : __( 'Blog Page Featured Image' );
        /** This filter is documented in wp-includes/default-widgets.php */
        $title          = apply_filters( 'widget_title', $title, $instance, $this->id_base );

        // ADD YOUR CUSTOM PHP CODE HERE FOR EXECUTION TO DISPLAY ON FRONT END
        // First make sure this is the page set as blogpage
        if (    'page' === get_option('show_on_front')
             && is_home()
        ) { // We are on the blogpage
            // Get the current page object
            $page_object = $GLOBALS['wp_the_query']->get_queried_object();

            // Make sure that the current page IS the one set as blogpage
            if ( $page_object->ID === (int) get_option( 'page_for_posts' ) ) {
                /**
                 * Now that we are sure we are on the posts page, lets get and display
                 * its featured image. We will also first make sure that we
                 * actually have one set
                 */
                if ( has_post_thumbnail( $page_object->ID ) )
                    echo get_the_post_thumbnail( $page_object->ID );
            }
        }

        echo $args['after_widget']; 

        if ( ! $this->is_preview() ) {
            $cache[ $args['widget_id'] ] = ob_get_flush();
            wp_cache_set( 'widget_bpfi', $cache, 'widget' );
        } else {
            ob_end_flush();
        }
    }

    public function update( $new_instance, $old_instance ) 
    {
        $instance                   = $old_instance;
        $instance['title']          = strip_tags( $new_instance['title'] );
        $this->flush_widget_cache();

        $alloptions = wp_cache_get( 'alloptions', 'options' );
        if ( isset($alloptions['widget_blog_page_featured_image']) )
            delete_option('widget_blog_page_featured_image');

        return $instance;
    }

    public function flush_widget_cache() 
    {
        wp_cache_delete('widget_bpfi', 'widget');
    }

    public function form( $instance ) 
    {

        $title      = isset( $instance['title'] ) ? esc_attr( $instance['title'] ) : '';
        ?>

        <p>
            <label for="<?php echo $this->get_field_id( 'title' ); ?>"><?php _e( 'Title:' ); ?></label>
            <input class="widefat" id="<?php echo $this->get_field_id( 'title' ); ?>" name="<?php echo $this->get_field_name( 'title' ); ?>" type="text" value="<?php echo $title; ?>" />
        </p>

    <?php
    }

}

add_action( 'widgets_init', function () 
{
    register_widget( 'Blog_Page_Featured_Image' );
});

What I also like to do is to always completely remove a widget when it is is totally out of context to avoid the sidebar from rendering a blank space when no other widgets are displayed

We can try the same approach as I have described here. You can just add this at the bottom of the plugin

add_filter( 'sidebars_widgets', function ( $sidebars_widgets )
{
    // Return our filter when we are on admin screen
    if ( is_admin() )
        return $sidebars_widgets;

    // Make sure we are not on the blog page, if we are, bail
    if (    'page' === get_option('show_on_front')
         && is_home()
         && $GLOBALS['wp_the_query']->get_queried_object_id() === (int) get_option( 'page_for_posts' ) 
    )
        return $sidebars_widgets;

    /**
     * Widget we need to target. This should be the name/id we used to register it
     *
     * EXAMPLE
     *   parent::__construct(
            'widget_blog_page_featured_image', 
            _x( 'Blog Page Featured Image', 'Blog page featured image' ), 
            [ 'description' => __( 'Displays the featured image for the pge set as blog page.' ) ] 
        );
     *
     */
    $custom_widget="widget_blog_page_featured_image";

    // See if our custom widget exists is any sidebar, if so, get the array index
    foreach ( $sidebars_widgets as $sidebars_key=>$sidebars_widget ) {
        // Skip the wp_inactive_widgets set, we do not need them
        if ( $sidebars_key == 'wp_inactive_widgets' )
        continue;

        // Only continue our operation if $sidebars_widget are not an empty array
        if ( $sidebars_widget ) {
            foreach ( $sidebars_widget as $k=>$v ) {

                /**
                 * Look for our custom widget, if found, unset it from the $sidebars_widgets array
                 * @see stripos()
                 */
                if ( stripos( $v, $custom_widget ) !== false ) 
                    unset( $sidebars_widgets[$sidebars_key][$k] );
            } // endforeach $sidebars_widget
        } // endif $sidebars_widget
    } // endforeach $sidebars_widgets

    return $sidebars_widgets;
});

EDIT

The code above is now tested and working as expected

Leave a Comment