WordPress, why no get_the_widget?

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
  the_widget('widget_name', $atts);
  $content = ob_get_contents();

  //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_startob_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.