I know that the plugin Widget Logic does exactly that.
Dissecting its code, the excerpt bellow will output a textarea in all 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>";
}