How To Add an Extra Field in All WordPress Available Widgets?

I know that the plugin Widget Logic does exactly that.

Dissecting its code, the excerpt bellow will output a textarea in all widgets.

adding textarea in all available widgets

But please note that:

  • this is just a proof of concept, and the “save field” control is not present
  • the best solution is probably making a fork of the plugin and removing the unneeded functionality and adding your own
  • the plugin code is not exactly easy to read
if ( is_admin() )
{
    add_action( 'sidebar_admin_setup', 'widget_logic_expand_control' );
}

// CALLED VIA 'sidebar_admin_setup' ACTION
// adds in the admin control per widget, but also processes import/export
function widget_logic_expand_control()
{   
    global $wp_registered_widgets, $wp_registered_widget_controls, $wl_options;

    // ADD EXTRA WIDGET LOGIC FIELD TO EACH WIDGET CONTROL
    // pop the widget id on the params array (as it's not in the main params so not provided to the callback)
    foreach ( $wp_registered_widgets as $id => $widget )
    {   // controll-less widgets need an empty function so the callback function is called.
        if (!$wp_registered_widget_controls[$id])
            wp_register_widget_control($id,$widget['name'], 'widget_logic_empty_control');
        $wp_registered_widget_controls[$id]['callback_wl_redirect'] = $wp_registered_widget_controls[$id]['callback'];
        $wp_registered_widget_controls[$id]['callback'] = 'widget_logic_extra_control';
        array_push( $wp_registered_widget_controls[$id]['params'], $id );   
    }

}

// added to widget functionality in 'widget_logic_expand_control' (above)
function widget_logic_empty_control() {}

// added to widget functionality in 'widget_logic_expand_control' (above)
function widget_logic_extra_control()
{   
    global $wp_registered_widget_controls, $wl_options;

    $params = func_get_args();
    $id = array_pop($params);

    // go to the original control function
    $callback = $wp_registered_widget_controls[$id]['callback_wl_redirect'];
    if ( is_callable($callback) )
        call_user_func_array($callback, $params);       

    $value = !empty( $wl_options[$id] ) ? htmlspecialchars( stripslashes( $wl_options[$id ] ),ENT_QUOTES ) : '';

    // dealing with multiple widgets - get the number. if -1 this is the 'template' for the admin interface
    $number=$params[0]['number'];
    if ($number==-1) {
        $number="%i%"; 
        $value="";
    }
    $id_disp=$id;
    if ( isset($number) ) 
        $id_disp = $wp_registered_widget_controls[$id]['id_base'].'-'.$number;

    // output our extra widget logic field
    echo "<p><label for="".$id_disp."-widget_logic">My logic <textarea class="widefat" type="text" name="".$id_disp."-widget_logic" id='".$id_disp."-widget_logic' >".$value."</textarea></label></p>";
}

Leave a Comment