1

I created my Custom Widget with a category filter select. The widget show me the related posts of the current taxonomy term and filter by the selected category.

I would like to hide the widget title if the widget is empty (if there's no related posts).

How can I do?

Here's my code:

public function widget( $args, $instance ) {
        $title = apply_filters( 'widget_title', $instance['title'] );
        $limit = $instance['limit'];
        $cat = $instance['cat'];
        $show_thumbnail = isset( $instance['show_thumbnail'] ) ? $instance['show_thumbnail'] : false;

            echo $args[ 'before_widget' ];      


                if ( !empty( $title ) ) 
                echo $args['before_title'] . $title . $args['after_title']; 

                $cat_select = array( 
                'numberposts' => $limit,
                'cat' => $cat,  
            ); ?>

               /******* function to get the posts of current taxonomy term *******/
                <?php if ( function_exists( 'get_related_posts_widget' ) ) { ?>

                    <?php $related_posts = get_related_posts_widget( 'authors', $cat_select );
                        if ( $related_posts ) { ?>


                            <ul class="related-cat">
                            <!-- Widget loop -->

Thank you in advance


EDIT

I use the code you suggested me here

And I call the function get_related_posts_widget from functions.php. I adapted the query with the selected cat ($cat).

public function widget( $args, $instance ) {
        $title = apply_filters( 'widget_title', $instance['title'] );
        $limit = $instance['limit'];
        $cat = $instance['cat'];
        $show_thumbnail = isset( $instance['show_thumbnail'] ) ? $instance['show_thumbnail'] : false;

            echo $args[ 'before_widget' ];       

                $cat_select = array( 
                'numberposts' => $limit,
                'cat' => $cat,  
            );

                if ( function_exists( 'get_related_posts_widget' ) ) { ?>
                    <?php $related_posts = get_related_posts( 'authors', $cat_select ); 
                        if ( $related_posts ) {
                            if ( !empty( $title ) ) 
                            echo $args['before_title'] . $title . $args['after_title']; ?>

                                <ul class="related-cat">
                                    <?php foreach ( $related_posts as $post ) {
                                        setup_postdata( $post ); ?>
                                        <li>
                                            <?php if ( $show_thumbnail ) : ?>
                                            <figure class="post-thumbnail">
                                                <?php the_post_thumbnail('tie-large'); ?>                                               
                                            </figure>
                                            <?php endif; ?>
                                            <h3><a href="<?php echo get_the_permalink($post->ID); ?>"> <?php echo get_the_title($post->ID);?> </a></h3>
                                        </li>
                                    <?php } //foreach ( $related_posts as $post ) ?>
                                </ul>


                        <?php } // end if ?>
                    <?php echo $args[ 'after_widget' ]; ?>          

           <?php } // end if function   ?>

    <?php } // end Widget Function

It's like the $after_widget doesn't work.


SOLVE

Thanks to @PieterGoosen! Read his code below. Wonderful!

1

I always move my filters inside my query, this will inhibit them from showing anything when my query returns no results. You just need to move the following

echo $args[ 'before_widget' ];      

if ( !empty( $title ) ) 
   echo $args['before_title'] . $title . $args['after_title']; 

to just after this line

if ( $related_posts ) { ?>

EDIT

I have quickly rewritten one of my widgets to accommodate my related posts function. I have commented a few places where there was issues. Hope this help

<?php
/**
 * Related_Posts_Widget widget class
 *
 * Displays posts from a selected category
 *
 * @since 1.0.0
*/
class Related_Posts_Widget extends WP_Widget 
{

    public function __construct() 
    {
        parent::__construct(
            'widget_related_posts', 
            _x( 'Related Posts Widget', 'Related Posts Widget' ), 
            [ 'description' => __( 'Display a list of related posts.' ) ] 
        );
        $this->alt_option_name = 'widget_related_posts';

        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_rel_posts', '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'] : __( 'Related Posts' );
        /** This filter is documented in wp-includes/default-widgets.php */
        $title          = apply_filters( 'widget_title', $title, $instance, $this->id_base );
        $number         = ( ! empty( $instance['number'] ) ) ? absint( $instance['number'] ) : 5;
        if ( ! $number ) {
            $number = 5;
        }
        $cat_id         = $instance['cat_id'];
        $thumbnail      = $instance['thumbnail'] ? true : false; 

        /**
         * Filter the arguments for the Related Posts Widget.
         *
         * @since 1.0.0
         *
         */
        $cat_select = [ 
            'numberposts' => $number,
            'cat'         => $cat,  
        ];

        if ( function_exists( 'get_related_posts' ) ) { // This line was wrong, get_related_posts_widget should be get_related_posts
            $related_posts = get_related_posts( 'authors', $cat_select ); 
                if ( $related_posts ) {

                    echo $args['before_widget'];
                    if ( $title ) { // This should not be !$title
                        echo $args['before_title'] . $title . $args['after_title'];
                    }               
                    ?>

                    <ul class="related-cat">
                        <?php foreach ( $related_posts as $post ) {
                            setup_postdata( $post ); ?>
                            <li>
                                <?php if ( $thumbnail ) : ?>
                                <figure class="post-thumbnail">
                                    <?php the_post_thumbnail( 'tie-large' ); ?>                                               
                                </figure>
                                <?php endif; ?>
                                <h3><a href="<?php echo get_the_permalink( $post->ID ); ?>"> <?php echo get_the_title( $post->ID );?> </a></h3>
                            </li>
                        <?php } //foreach ( $related_posts as $post ) ?>
                    </ul>


                    <?php 
                } // end if     

            wp_reset_postdata(); // You forgot this, this is very very very important

            echo $args['after_widget']; 
        }

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

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

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

        return $instance;
    }

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

    public function form( $instance ) 
    {

        $title      = isset( $instance['title'] ) ? esc_attr( $instance['title'] ) : '';
        $number     = isset( $instance['number'] ) ? absint( $instance['number'] ) : 5;
        $cat_id     = isset( $instance['cat_id'] ) ? absint( $instance['cat_id'] ) : 1;
        $thumbnail  = isset( $instance['thumbnail'] ) ? $instance['thumbnail'] : false; 
        ?>

        <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>

        <p>
            <label for="<?php echo $this->get_field_id( 'number' ); ?>"><?php _e( 'Number of posts to show:' ); ?></label>
            <input id="<?php echo $this->get_field_id( 'number' ); ?>" name="<?php echo $this->get_field_name( 'number' ); ?>" type="text" value="<?php echo $number; ?>" size="3" />
        </p>

        <p>
            <label for="<?php echo $this->get_field_id('cat_id'); ?>"><?php _e( 'Category Name:' )?></label>
            <select id="<?php echo $this->get_field_id('cat_id'); ?>" name="<?php echo $this->get_field_name('cat_id'); ?>">
                <?php 
                $this->categories = get_categories();
                foreach ( $this->categories as $cat ) {
                    $selected = ( $cat->term_id == esc_attr( $cat_id ) ) ? ' selected = "selected" ' : '';
                    $option = '<option '.$selected .'value="' . $cat->term_id;
                    $option = $option .'">';
                    $option = $option .$cat->name;
                    $option = $option .'</option>';
                    echo $option;
                }
                ?>
            </select>
        </p>

        <p>
            <label for="<?php echo $this->get_field_id('thumbnail'); ?>"><?php _e( 'Hide post thumbnail' ); ?></label>
            <?php $checked = ( $thumbnail ) ? ' checked=\"checked\" ' : ''; ?>
            <input type="checkbox" id="<?php echo $this->get_field_id( 'thumbnail' ); ?>" name="<?php echo $this->get_field_name( 'thumbnail' ); ?>" value="true" <?php echo $checked; ?> />    
        </p>

    <?php
    }

}

add_action( 'widgets_init', function () 
{
    register_widget( 'Related_Posts_Widget' );
});
  • I tried but when I put the title after if ( $related_posts ) { ?> all the others widgets going outside the sidebar.. I don't know why.. Maybe something about the theme. Anyway I try again and I'll let you know. Thank you – Elena Jul 28 '15 at 12:25
  • Search my profile, I have written a couple of widgets this year, check your widget against mine, maybe your problem is somewhere else. :-) – Pieter Goosen Jul 28 '15 at 12:30
  • I can't get out of it.. :( When my widget has posts it looks good in the right DIV and the others widgets look good too. But when I put the echo $args['before_title'] . $title . $args['after_title']; after if ( $related_posts ) { ?> the others widgets are outside the sidebar.. Do you have some specific links where I can check? I found something but maybe you know better which of your widgets I can check against mine.. Thank you very much – Elena Jul 28 '15 at 13:50
  • Post your complete widget code – Pieter Goosen Jul 28 '15 at 14:28
  • I edit the code above @PieterGoosen – Elena Jul 28 '15 at 14:44

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.