Widgets are used inside registered widget areas. Let's display them in other areas.
Widgets, whether those provided by WordPress or by a plugin or a theme, are an easy way to display some content. The difficulty is that the can only be used in a widget area. Well, I’ll demonstrate that you can actually put them anywhere you want.
At the time of this post my blog posts don’t list related posts. I don’t want to use an automated system as they can be a drain on a site – I plan to use a custom CMB2 metabox to select 3 related posts. While this will store the post ID it won’t display them. Instead of reinventing the wheel I am considering using an existing widget e.g. one from Genesis framework. Then comes the challenge of how to invoke the widget.
The widget() function is all you need
I looked at the code for a few WordPress widgets. They are all PHP classes that extend the WP_Widget class. At a minimum the new class must provide a widget() function to generate the markup. The function requires 2 arguments – $args and $instance. This can’t be too hard.
What is $args?
When you register a widget area with register_sidebar() you provide some markup that will be prepended to the widget (‘before_widget‘), to the title (‘before_title’) and markup for after the widget (‘after_widget‘) and after the title (‘after_title‘) . The four pieces of markup generally act as a wrapper for the widget and its title.
The defaults for these can be found in the register_sidebar() function in wp-includes/widgets.php
What is $instance?
The $instance array is different for each type of widget. It contains the settings for an instance of that widget. For example, you could add a widget to a sidebar multiple times and set a different title for each instance.
As each widget has different settings there is no standard for the $instance array. You can look at the update() function in the widget source code to see what array elements it references. These will be the ones that $instance will need to contain.
Taking a very simple widget – the Meta one from WordPress. Its update() function only references the ‘title‘ element.
Here is a quick demo. This code uses the new ‘wp_body_open‘ action to place the widget directly after the opening <body> tag. It is a silly example but one that should work with most themes.
Here’s what that code produces on Twenty Nineteen:
Recent Posts widget – more $instance elements
The Meta widget is simple as it only has a ‘title‘ setting. The Recent Posts widget update() function references three settings: ‘title‘, ‘number‘ and ‘show_date.’ For this widget they are self explanatory but for others you’ll need to look at the form() function to determine the possible values for the settings.
In this example I’ll put the widget at the bottom of the content area. It will demonstrate invoking a widget in a filter. A widget’s widget() function simply outputs the markup so I will have to use ob_start() and ob_get_contents() to capture it.
This is the Sample Page in Twenty Nineteen:
As I mentioned at the top of this post, I might use this code to create a ‘Related Posts‘ section at the end of my blog posts. I would call the widget’s widget() function multiple times, passing the post ID in the $instance array.