1

Problem:

  • I'm extending Twenty Seventeen and I added a new widget area ("call to action") above the content on the homepage. On the homepage I display that sidebar where I want it, but on other pages I want these (important) widgets to show in the default Twenty Seventeen sidebar.
  • So far what I've done is insert a new widget area above the main one for non-home screens to display my widgets. This comes with various CSS/HTML hassles and deviation from the parent theme that I don't want to deal with.
  • What I really want is for my "call to action" widgets to be injected directly into the other sidebar, so that they behave exactly as if they were added there directly.

So basically this boils down to There must be a way to use functions.php filter code to retrieve the widgets saved in one sidebar, then inject them into another sidebar before it is displayed.

This could be useful for all kinds of scenarios where you want the same widget(s) in multiple sidebars depending on context, especially when you are dealing with an inflexible parent theme that doesn't have "enough sidebars".

Note that I don't need to be told about "Widget control" plugins or the Jetpack option that lets you show/hide individual widgets depending on context. What I need is a way to control which other sidebars a widget will show in.

Plugin suggestions welcome if they solve the key problem.

Thanks! I'll try to figure this out for myself either way and will reply if I get a satisfactory solution :)

1

Here's an (untested) idea where we inject the sidebar-inject sidebar before sidebar-target sidebar with help of the dynamic_sidebar_before hook :

add_action( 'dynamic_sidebar_before', 'wpse_inject_sidebar', 10, 2 );

function wpse_inject_sidebar( $index, $has_widgets )
{   
    // Only target front-end
    if( is_admin() )
        return;

    // Only target 'sidebar-target'
    if( 'sidebar-target' !== $index )
        return;

    // Make sure 'sidebar-inject' is active
    if( ! is_active_sidebar( 'sidebar-inject' ) ) 
        return;

    // Avoid recursive loop
    remove_action( 'dynamic_sidebar_before', 'wpse_inject_sidebar', 10 );

    // Inject  'sidebar-inject' 
    dynamic_sidebar( 'sidebar-inject' );

    // Re-hook it again
    add_action( 'dynamic_sidebar_before', 'wpse_inject_sidebar', 10, 2 );       
}

Here we watch out for a recursive loop, by removing the action before calling dynamic_sidebar() inside the hook's callback.

But by targeting only 'sidebar-target' here and making sure it's different from 'sidebar-inject', we actually avoid a recursive loop.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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