WordPress.org

Make WordPress Core

Opened 10 years ago

Closed 10 years ago

Last modified 9 years ago

#9701 closed feature request (fixed)

Add a the_widget() function to output a generic widget anywhere in a template

Reported by: Viper007Bond Owned by: azaozz
Milestone: 2.8 Priority: low
Severity: minor Version: 2.8
Component: Widgets Keywords: has-patch tested dev-feedback
Focuses: Cc:

Description

For those of us who don't use widgets (for whatever reason), it'd be nice if we could display the recent comments without having to do a bit of hacking to get the widget to work.

I propose the code be moved to a function that's called by the widget.

Attachments (4)

9701-plugin.php (4.4 KB) - added by hakre 10 years ago.
Plugin for Demonstration of a the_widget() Prototype
9701-plugin.2.php (4.6 KB) - added by hakre 10 years ago.
Corrected Demonstration / Test Plugin. Widget now instantiates correctly.
9701.diff (1.4 KB) - added by Denis-de-Bernardy 10 years ago.
9701.2.diff (911 bytes) - added by Denis-de-Bernardy 10 years ago.
fix the sprintf when $args[before_widget] is passed

Download all attachments as: .zip

Change History (28)

#1 @Denis-de-Bernardy
10 years ago

  • Milestone changed from Unassigned to Future Release

#2 @hakre
10 years ago

Wouldn't it be nice to have a function in the global namespace to display any widget with it's options passed by an array? like so

$name    = 'Recent Comments';
$options = array('title' => 'The 20 most Recent Comments', 'number' => 20);
display_widget($name, $options);

#3 @Denis-de-Bernardy
10 years ago

+1. Plus, the new widgets class makes that a lot simpler.

#4 @azaozz
10 years ago

Yes, this should be quite easy. All default widgets can be run as template tags with preset values, even no need to save options (no UI for that anyways).

#5 @hakre
10 years ago

I'm just writing a patch for that. It looks really easy.

@hakre
10 years ago

Plugin for Demonstration of a the_widget() Prototype

#6 @hakre
10 years ago

Install the attached Plugin and you will see the output of a the_widget() test-implementation that does exactly what it is intended for:

the_widget('WP_Widget_Recent_Posts'); // Widget by Classname
the_widget('Recent Comments'); // Widget by Name

#7 @Denis-de-Bernardy
10 years ago

seems extraordinarily complex. in my own plugins, I usually have a function around that goes:

function my_widget($instance = array()) {
  $args = array('before_widget' => '<div>', 'after_widget' => '</div>', etc.);
  my_widget::widget($args, $instance);
}

#8 @hakre
10 years ago

well your code is a static function call with hardcoded values. You want to code that fragment multiple times to mimic every widget? even the ones you do not know the classnames or widget names from? and what about configuring $args?

if you take that into account, i doub you would name the code "extraordinarily complex".

with my suggestion i wanted to ensure that the widget works as it should, like an instance of a widget, in it's own sidebar environment, fully configureable and callable by widget-name, not only by class.

this is done sothat it works with _any_ registered widget. and it is possible to configure the sidebar args. your example uses hardcoded values therefore. next to this, the standard filter that can decide wether or not a widget should be displayed has been implemented to better mimic the stand widget display procedure.

the rest in the attachment is just plugin and test-widget code. so basically, this one function is how it looks like, and I do not think it is that complex:

/** widget template tag
 * 
 * get a configured widgets output without the need of a sidebar and backend administration. 
 * 
 * NOTE: this is development code
 * 
 * @global WP_Widget_Factory $wp_widget_factory 
 * @global array $wp_registered_sidebars
 * 
 * @param string $widget   widget identifier
 * @param array  $settings optional widget settings
 * @param array  $args     optional sidebar options  
 * @return void
 */
function the_widget($widget, $settings = array(), $args = array()) {
	
	/* sanitize input */
	$widget = (string) $widget;
	if (!strlen($widget))
		return;
	if (!is_array($settings))
		return;
	if (!is_array($args))
		return;

	/* globals */	
	global $wp_widget_factory, $wp_registered_sidebars;	
	
	/* pull default (def) sidebar options (args) */	
	$sidebar_id = register_sidebar( array('name' => uniqid('temp-')) );	
	$def  = $wp_registered_sidebars[$sidebar_id];
	$args = array_merge($def, $args);
							
	/* get widget ($instance) */
 	$instance = null;
	if (isset($wp_widget_factory->widgets[$widget])) {
		$instance = $wp_widget_factory->widgets[$widget];
	} else {
		foreach($wp_widget_factory->widgets as $value)
			if (isset($value->name))
				if ($value->name == $widget) {
					$instance = $value;
					break;
				}
	}
	
	/*  display widget */
	if (is_a($instance, 'WP_Widget')) {
		$settings = apply_filters('widget_display_callback', $settings, $instance);   
		if ( false !== $settings )
			$instance->widget($args, $settings);
	}	
	
	unregister_sidebar($sidebar_id);
}

@hakre
10 years ago

Corrected Demonstration / Test Plugin. Widget now instantiates correctly.

#9 @Denis-de-Bernardy
10 years ago

  • Keywords has-patch added; needs-patch removed
  • Milestone changed from Future Release to 2.8

I still fail to see the point in registering a fake sidebar. :-)

Suggested alternative patch attached.

#10 @Denis-de-Bernardy
10 years ago

  • Summary changed from Pull the "Recent Comments" code out of the widget and into it's own function to Add a the_widget() to output a generic widget anywhere in a template

#11 @Denis-de-Bernardy
10 years ago

  • Priority changed from normal to low
  • Severity changed from normal to minor
  • Summary changed from Add a the_widget() to output a generic widget anywhere in a template to Add a the_widget() function to output a generic widget anywhere in a template
  • Type changed from enhancement to feature request

#12 @Denis-de-Bernardy
10 years ago

  • Keywords tested dev-feedback added

#13 @ryan
10 years ago

  • Owner set to azaozz

9701.diff seems good to me. Andrew?

#14 @Denis-de-Bernardy
10 years ago

oh wait, patch actually has an issue.

if ( in_the_loop() ) {

should be:

if ( !in_the_loop() ) {

fixing this right away. :-)

#15 @Denis-de-Bernardy
10 years ago

err, nevermind that. it's just getting late.

#16 @azaozz
10 years ago

It has actually a typo too and the default tag when in the sidebar should preferably be <li>, otherwise <div> in or out of the loop. Looking at it now.

#17 @Denis-de-Bernardy
10 years ago

lol. make that *very* late. :-)

#18 @Denis-de-Bernardy
10 years ago

the div tag might be the best one to use at all times, on second thoughts. it's reasonably safe to assume that sidebars are using sidebar widgets nowadays.

#19 @azaozz
10 years ago

  • Resolution set to fixed
  • Status changed from new to closed

(In [11317]) Add a function to output a generic widget anywhere in a template, props Denis-de-Bernardy, fixes #9701

#20 @azaozz
10 years ago

Sounds good, removed the in_the_loop() conditional.

@Denis-de-Bernardy
10 years ago

fix the sprintf when $args[before_widget] is passed

#21 @Denis-de-Bernardy
10 years ago

mm... the sprintf() call might be wrongly placed. I attached a patch to make this work:

the_widget('foo', $instance, array('before_widget' => '<li class="foo %s">', 'after_widget' => '</li>');

or then, you're assuming that this syntax will be used (in which case nevermind, and not re-opening for this reason):

the_widget('foo', $instance, array('before_widget' => '<li>', 'after_widget' => '</li>');

#22 follow-up: @Denis-de-Bernardy
10 years ago

both options are valid I think. it can safely be assumed that, if the user wants a specific class, he'll add it.

#23 in reply to: ↑ 22 @azaozz
10 years ago

Replying to Denis-de-Bernardy:

both options are valid I think. it can safely be assumed that, if the user wants a specific class, he'll add it.

Yes, exactly. No need to

sprintf('<div class="my-custom-class">', $widget_obj->widget_options['classname']);

#24 @Denis-de-Bernardy
10 years ago

ok, then it's good to know I'm starting to get a feel of your mindset. :-)

Note: See TracTickets for help on using tickets.