0
votes

I have a widget that shows related posts in the sidebar. I would like to manipulate the widget's wp_query parameters using a shortcode in the page.

The reason I would like to do so is that it's a multipages post (with page breaks) and each page is related to a different category. I would like the widget to show recommended posts according to the specific page.

I am not sure how to make the widget evaluate the shortcode ($a["cat"]) before running the wp_query.

Shortcode function:

    //[bartag cat="computers"]
function bartag_func( $atts ) {
        $a = shortcode_atts( array('cat' => ''), $atts );

        return $a['cat'];
}
add_shortcode( 'bartag', 'bartag_func' );

The widget function:

class related_articles_Widget extends WP_Widget {

    /**
     * Register widget with WordPress.
     */
    function __construct() {
        parent::__construct(
            'related_articles_Widget', // Base ID
            esc_html__( 'related_articles_Widget', 'text_domain' ), // Name
            array( 'description' => esc_html__( '', 'text_domain' ), ) // Args
        );
    }

    public function widget( $args, $instance ) {
        echo $args['before_widget'];


        $args = array( 'post_type' => 'post', 
                'posts_per_page' => 3,
                'category_name' => $a['cat']
                ) 

            $loop = new WP_Query( $args );

            while ( $loop->have_posts() ) : $loop->the_post(); 

            get_template_part( 'template-parts/content', 'small-article-template');

        endwhile; 
        wp_reset_query();
        }

    } 

function register_related_articles_Widget() {
    register_widget( 'related_articles_Widget' );
}
add_action( 'widgets_init', 'register_related_articles_Widget' );
1

1 Answers

0
votes

Declare the shortcode in your class. I just did this the other day and used this tutorial to help: https://code.tutsplus.com/articles/create-wordpress-plugins-with-oop-techniques--net-20153

EDIT: I would add a separate function called get_widget_contents($cat);

function get_widget_contents($cat) { 
    $args = array( 'post_type' => 'post', 
            'posts_per_page' => 3,
            'category_name' => $cat
            );

        $loop = new WP_Query( $args );

        while ( $loop->have_posts() ) : $loop->the_post(); 

        get_template_part( 'template-parts/content', 'small-article-template');

    endwhile; 
    wp_reset_query();
}

Then in your shortcode function do this:

function bartag_func( $atts ) {
    $a = shortcode_atts( array('cat' => ''), $atts );

    return get_widget_contents($a['cat']);
}
add_shortcode( 'bartag', 'bartag_func' );

And your widget function would just call the separate function as well:

public function widget( $args, $instance ) {
    echo $args['before_widget'];
    echo get_widget_contents();
}

I have not tested this but this should work. Not sure what your get_template_part does. For a shortcode you might need to return a string of HTML so it puts it in the right spot. If that is the case, just wrap the whole thing in a ob_start() and ob_get_clean()