1

I have this scenario where I need to provide various single-use widgets.

They're all displayed the same way, so I don't feel the need for a different display functions for each widget. However, if I use the same callback on all wp_register_sidebar_widget instances, only the last one is active.

I'm forced to have multiple identical functions, differing only the name. How can I improve it?

add_action( 'widgets_init', 'register_single_use_widgets' );
function register_single_use_widgets() {

  $id = 'first';
  $name = 'First Widget';
  $widget_ops = array( 'description' => 'This is the first widget.' );
  wp_register_sidebar_widget( $id, $name, 'single_widget_display', $widget_ops );

  $id = 'second';
  $name = 'Second Widget';
  $widget_ops = array( 'description' => 'This is the second widget.' );
  wp_register_sidebar_widget( $id, $name, 'single_widget_display2', $widget_ops );

  $id = 'third';
  $name = 'Third Widget';
  $widget_ops = array( 'description' => 'This is the third widget.' );
  wp_register_sidebar_widget( $id, $name, 'single_widget_display3', $widget_ops );

}

function single_widget_display( $args ) {
  $name = $args['widget_name'];
  echo "<p> $name </p>";
}

function single_widget_display2( $args ) {
  $name = $args['widget_name'];
  echo "<p> $name </p>";
}

function single_widget_display3( $args ) {
  $name = $args['widget_name'];
  echo "<p> $name </p>";
}
1
  • wp_register_sidebar_widget is a very old function, and not how normal widgets are registered, where are your classes implementing WP_Widget?
    – Tom J Nowell
    Commented Feb 2, 2018 at 17:00

1 Answer 1

1

It appears that wp_register_sidebar_widget is a very outdated function from early implementations of widgets. Apparently back then widgets could only be used once each and the output callback name seems to be what made a widget unique, despite the existence of an ID. The single-use nature of these widgets doesn't appear to be an intentional feature.

Given it's age I would suggest using the newer API, based on register_widget(). To register 3 widgets with the same output you would create a class for the widget, with some additionaland register 3 different instances of it.

function wpse_292985_widget_display( $args ) {
    echo '<p>' . $args['widget_name'] . '</p>';
}

class WPSE_292985_Widget extends WP_Widget {
    function __construct( $id, $name, $widget_ops ) {
        parent::__construct( $id, $name, $widget_ops );
    }

    function widget( $args, $instance ) {
        wpse_292985_widget_display( $args );
    }
}

function wpse_292985_register_widgets() {
    register_widget( new WPSE_292985_Widget( 
        'first', 
        'First Widget', 
        ['description' => 'This is the first widget.']
    ) );

    register_widget( new WPSE_292985_Widget( 
        'second', 
        'Second Widget', 
        ['description' => 'This is the second widget.']
    ) );

    register_widget( new WPSE_292985_Widget( 
        'third', 
        'Third Widget', 
        ['description' => 'This is the third widget.']
    ) );
}
add_action( 'widgets_init', 'wpse_292985_register_widgets' );

The first thing happening there is defining the function we want the widget to output. It accepts $args as an argument which we'll pass through in our widget class.

The next bit is the class for the Widget. This class is just a copy of the generic WordPress widget class, but we're setting the widget() method here to output our function.

Then we register 3 widgets by creating new instances of our widget class and passing them into register_widget().

1
  • "The single-use nature of these widgets doesn't appear to be an intentional feature": Yeah, I know. But that's exactly what I need. Your code is much more up-to-date, saner, and I believe follows best practices, but... Doesn't produce widgets that can be used only once. Commented Feb 2, 2018 at 17:06

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.