So the problem I was having the other day was that I wanted to be able to output a widget on a WordPress custom theme archive page, but I didn’t know where the user wanted to put it, or what attributes they wanted to pass in, it needed to be really flexible (isn’t that always the way?).
So I thought, I’ll register a new shortcode and call the widget in from there, passing through the attributes as the parameters to keep things simple and transparent.
However, the problem is there’s only a the_widget function, which echo’s the output of the widget, there’s no get_the_widget equivalent (like there is for the_title and get_the_title).
So here’s roughly what I came up with…
function riklewis_shortcode($atts = [], $content = null, $tag = '') {
//validate the attributes expected by the widget
$atts = array_change_key_case((array)$atts, CASE_LOWER);
$atts = shortcode_atts([
'name' => 'default',
'example' => true,
], $atts, $tag);
//output widget to new output buffer
ob_start();
the_widget('widget_name', $atts);
$content = ob_get_contents();
ob_end_clean();
//return widget output
return $content;
}
add_shortcode('riklewis', 'riklewis_shortcode');
As you can see, add_shortcode is called in the normal way to register the shortcode and shortcode_atts is used to validate and define default values. It’s worth noting that this array needs to contain all of the attributes, even if you don’t want to define a default, because any attribute not in that list will be removed.
The key part here is using ob_start, ob_get_contents and ob_end_clean – these functions allow us to create a new output buffer, allow the_widget to output it’s content to it, then grab that and close off the output buffer. We can the return the content as a string, without affecting the main output buffer.