Is there a way to allow only certain type of widgets in the sidebars?

For example, I want Sidebar A to display nothing but one text widget and Sidebar B to display anything but text widgets. How can I do that?

Thanks.

Related posts

2 comments

  1. It is possible to hook to sidebars_widgets and find which widget is in which sidebar.

    function dump_sidebar($a) {
      echo '<pre>'.var_export($a,true).'</pre>';
    }
    add_action( 'sidebars_widgets', 'dump_sidebar');
    

    By checking that array you could eliminate particular widgets.

    function limit_sidebar_wpse_101279($sidebars_widgets) {
      if (!empty($sidebars_widgets['sidebar-1'])) {
        foreach ($sidebars_widgets['sidebar-1'] as $k =>$v) {
          if ('pages' == substr($v,0,5)) {
            unset($sidebars_widgets['sidebar-1'][$k]);
          }
        }
      }
      return $sidebars_widgets;
    }
    add_action( 'sidebars_widgets', 'limit_sidebar_wpse_101279');
    

    That works front end, and back end, but does not prevent a widget from being dragged into the wrong sidebar on the back end. That is, you can still drag a widget into the wrong sidebar and have it appear to work, but it will be removed on next page load. To solve that issue you will need to construct some Javascript to prevent the drag or issue some kind of warning.

  2. WordPress admin panel has three widgets area:

    1. all available widgets
    2. registered sidebars
    3. inactive widgets

    In order to set a widget undroppable when it’s coming from “all available widget” or “inactive widgets” to a “wrong” sidebar simply use .widget class and an id to identify it.
    I need to set the “Custom Recent Posts” widget undroppable so:

    Drag from: available widgets area, inactive widgets area

    $('.widget').on( 'dragcreate dragstart', function( event, ui ){
      id =  $(this).find( 'input[name="id_base"]').val();
      if( id == 'custom_recent_posts' ){ //check if the widget is the right one
        $(this).draggable({
          connectToSortable: '#primary-sidebar, #wp_inactive_widgets'//limit drop event only to these sidebars
        })
      }
    });
    

    That’s ok, but what’s happen with the active widgets?
    These widgets are not affected by “drag”, but “sort”. This part was little tricky, it is possible that my solution is not cool, but it works : )
    I need to set “Custom Recent Posts” widget not sortable ( you do a drag, in jquery logic is a sort ):

    Drag/Sort from within the active widgets:

    $( '.widgets-sortables' ).on( 'sortactivate sort', function( event, ui ){
      id = $(ui.item).find( 'input[name="id_base"]').val();
      if ( id == 'custom_recent_posts'){//identifying the wrong or right widget
    
          if ( $(ui.sender).attr( 'id' ) != 'primary-sidebar' ){// if it's coming from a sidebar that is not his "right" place, set 'connectWith' option to this sidebar and the inactive widgets area
            $(this).sortable('option', 'connectWith', '#primary-sidebar, #wp_inactive_widgets');
            $(this).sortable('refresh');
          }else{//else set 'connectWith' to false
            $(this).sortable('option', 'connectWith', false);
            $(this).sortable('refresh');
          }
    
      }else{// else default behavior 
        $(this).sortable('option', 'connectWith', 'div.widgets-sortables');
        $(this).sortable('refresh');
      } 
    });
    

    I needed the same logic within my project, I’m testing now and it seems to work like expected try it : )
    Hope it helps

Comments are closed.