Add copies of the same text widget instance to multiple sidebars

Note: This is not the popular question about how to create multiple instances of a widget. I have a text widget that I am using to display “business hours”. This text needs to go in multiple sidebars and is likely to change often enough to be a nuisance to change it in multiple places. Is there a way to use the same instance of a text widget on more than one sidebar?

Any alternatives that use tokens or some other kind of pointer would also be a solution.

Related posts

Leave a Reply

2 comments

  1. A possible solution would be to enable shortcodes in the Text Widget.

    add_filter( 'widget_text', 'do_shortcode', 11 );
    

    Then put the same shortcode (i.e.: “[business_hours]“) in all text widgets, and all of them will display the same content.

    It’s even possible to add some Conditionals Tags inside the shortcode definition to show different things according to the context where it is being displayed.

  2. I searched for a hook or filter that might help achieve that but could not find any. There is however dynamic_sidebar action but it will be fired after each widget display making its use not practical. So I wrote this helper function which mimics the way WordPress outputs widgets in the sidebar, call this function after the call of dynamic_sidebar() where you want a copy of the widget to appear in your the theme:

    /*
     * Duplicate Widget in Dynamic Sidebar.
     *
     * Make a copy of selected widget and display it in a selected sidebar, help make
     * edits to multiple identical widgets easier.
     *
     * @param string $widget_id Required, the ID of the widget to duplicate.
     * @param int|string $sidebar_index Optional, default is 1. Name or ID of dynamic sidebar.
     * @param string $copy Optional, default to the order the function was called, custom html id
     *  for the widget element.
    */
    
    function ad_duplicate_widget($widget_id, $sidebar_index = 1, $copy = '') {
        global $wp_registered_widgets, $wp_registered_sidebars;
        static $i = 0;
        $i++;
        if ($copy == '')
            $copy = $i;
        //$sidebars_widgets = wp_get_sidebars_widgets();
        if (is_int($sidebar_index)) {
            $sidebar_index = "sidebar-$sidebar_index";
        } else { 
            $sidebar_index = sanitize_title($sidebar_index);
            foreach ($wp_registered_sidebars as $key => $value) {
                if ( sanitize_title($value['name']) == $sidebar_index ) {
                    $sidebar_index = $key;
                    break;
                }
            }
        }
        $sidebar = $wp_registered_sidebars[$sidebar_index];
        $widget = $wp_registered_widgets[$widget_id];
        $def_params = array(
            'widget_id' => $widget_id,
            'widget_name' => $widget['name']
        );
        $params = array_merge(array(array_merge($sidebar, $def_params)), $widget['params']);
        $classname = $widget['classname'];
        $classname_ = '';
        if ( is_string($classname) )
            $classname_ .= '_' . $classname;
        elseif ( is_object($classname) )
            $classname_ .= '_' . get_class($classname);
        $new_id = $widget_id . '-' . $copy;
        $params[0]['before_widget'] = sprintf($params[0]['before_widget'], $new_id, $classname_);
        $callback = $widget['callback'];
        if ( is_callable($callback) ) {
            call_user_func_array($callback, $params);
        }
    }
    

    Usage

    Place this function in functions.php file and then call ad_duplicate_widget($widget_id, $sidebar_index, $copy) right after the call of dynamic_sidebar() where you want to copy your widget. $widget_id is the html id attribute of the widget element. $sidebar_index can be either the index of the sidebar (number) or the sidebar name (string). $copy is the custom html id appended to widget id.

    Example

    If you have a text widget of id 'text-5' that is displayed in the main sidebar of the blog and you want to display it in Sidebar Right sidebar, call this function after the dynamic_sidebar('Sidebar Right') call, which maybe called from sidebar.php or sidebar-right.php file:

    dynamic_sidebar('Sidebar Right');
    
    ad_duplicate_widget('text-5', 'Sidebar Right');
    

    This will create a copy of the widget in Sidebar Right sidebar, and any edit of the original widget will apply to both widgets.