We covered how to run a shortcode in a widget. But what about inserting a widget with a shortcode? I recently had this situation come up. I had a single page where I just wanted to be able to chuck in a widget without the whole rigmarole of creating a special widgetized area and probably a custom page template for that widgetized area and such. I wanted to just put [widget widget_name="my_widget"] in the pages content and have that widget pop in. Turns out it wasn’t as easy I wanted it to be, but it’s not that bad…
The answer was creating a custom function for the functions.php file which would output any widget by name. There is a function just for that: the_widget() (incomplete codex page).
The logic
- Test if widget exists
- If it does…
- Start capturing output
- Output widget
- End capturing output
- Return captured output
- If it doesn’t exist…
- Output fail message
The code for functions.php
function widget($atts) {
global $wp_widget_factory;
extract(shortcode_atts(array(
'widget_name' => FALSE
), $atts));
$widget_name = wp_specialchars($widget_name);
if (!is_a($wp_widget_factory->widgets[$widget_name], 'WP_Widget')):
$wp_class = 'WP_Widget_'.ucwords(strtolower($class));
if (!is_a($wp_widget_factory->widgets[$wp_class], 'WP_Widget')):
return '<p>'.sprintf(__("%s: Widget class not found. Make sure this widget exists and the class name is correct"),'<strong>'.$class.'</strong>').'</p>';
else:
$class = $wp_class;
endif;
endif;
ob_start();
the_widget($widget_name, $instance, array('widget_id'=>'arbitrary-instance-'.$id,
'before_widget' => '',
'after_widget' => '',
'before_title' => '',
'after_title' => ''
));
$output = ob_get_contents();
ob_end_clean();
return $output;
}
add_shortcode('widget','widget');
Usage
Now in Post/Page content, you can use the widget just by referencing it by name:
[widget widget_name="Your_Custom_Widget"]
![[ Digging into WordPress ]](http://digwp.com/wp-content/themes/DiggingIntoWordPress-2/images/sidebarbook.png)



Great post!, thanks! :)
Chris, this is awesome. Thanks!
I’ve wondered how difficult it would be to wedge a widget into a content page. :D
Thanks for sharing Chris! Just what I was looking for.
By the way, slight typo on 2.4. above.
What if you need to call the same widget more than once? How do you handle the name collisions?
Did you try it and it failed? I would think it would be fine, but I haven’t tested that yet.
Hey Chris
Can you call this via php at all?
Maybe something like this?
<?php widget(widget_name=Your_Custom_Widget') ; ?></code>Check out the function in the code above:
the_widget
Is there a way to include an
$instancein the shortcode?An example of the full version would be:
<?php the_widget('WP_Widget_Text', $instance, $args); ?>If so, then you could narrow the call using
instance:
* title
* text
* filter
So in addition to calling the widget, I would like to specify which version of the widget.
Is it something like this you were looking for?
extract(shortcode_atts(array('widget_name' => FALSE,'instance' => ''), $atts));$instance = str_ireplace("&", '&' ,$instance);then you can set the instances for the widget.
Usage
[widget widget_name="WP_Widget_Pages" instance="title=Pages&sortby=menu_order&exclude=2,41"]This is very handy and something I may need to turn into a plugin so that folk don’t need to dabble with the code.
Might be worth doing a spot of self promotion too (sorry ;-) ) for a plugin I have written that let’s you include a whole widgetised area inline insde wordpress page/post content… if you’re interested check out the Widgets on Pages plugin over at wordpress.org.
I’d be interested in hearing your views on this.
This is great, thanks.
I’d like to second Michael’s question.
I don’t understand how to call a particular text widget. Is there any way to specify ID or similar?
many thanks
I wish I had a perfect answer… The data exists so there is SOME way to do it. With this code though we are basically creating a new instance of the widget when it is called, not calling a pre-existing widget as defined in the Widgets area of the admin.
The first occurrence of
$class(insprintf()) is undefined. And where do you get the$instancefrom?Why did you give the function
widget()such a generic name?I might be well out to sea here, but I thought you could only call shortcodes on WordPress.com blogs, not self-hosted ones? I tried, just in case, and all that happens is I get the shortcode outputted as text. Any ideas? Am I missing something obvious?
Thanks
C
am i doing something wrong? i tried to insert the code into functions.php and it broke my entire installation
I have released a plugin, Widget Instance ,that addresses the question that Michael Krapf and Neil asked in the comment thread and that Chris Coyier left unanswered as far as providing an implementation.