Limitar widget a uma barra lateral registrada específica

4

Eu tenho um widget que eu só quero permissão para ser usado com a barra lateral single.php. Quando fiz referência ao códice para register sidebar , não há como limitar os widgets na matriz. Eu pesquisei com "WordPress limite widget para postar", mas eles são apenas plugins retornados nos meus resultados de pesquisa. Quando eu mudar meus parâmetros de pesquisa para a página para ver se consigo algo retornado, eu sou referência a:

Existe uma maneira de segmentar um Widget para que seja permitido somente o id no register_sidebar ? Eu não quero usar um plugin que eu quero aprender a codificá-lo corretamente.

EDITAR:

Por comentários, tenho um widget personalizado. que está sendo chamado no meu singles.php como <?php get_sidebar( 'foobar' );?> . Quando alguém está no administrador, quero limitar onde o widget pode ser aplicado:

Portanto, na imagem acima, quero que haja apenas a opção Post Sidebar . Eu poderia codificar tudo isso no arquivo sidebar-foobar.php , mas estou tentando aprender a utilizar mais os widgets.

    
por DᴀʀᴛʜVᴀᴅᴇʀ 24.09.2015 / 16:38

2 respostas

2

Meu conhecimento jquery ainda é quase inexistente, então não tenho certeza se a solução funciona que foi sugerido por @Howdy_McGee nos comentários.

De qualquer forma, apenas como referência, do link

  

apenas substitua 'your_widget' pelo nome do seu widget no código abaixo   (dois lugares).

     

'sortreceive' event é chamado apenas quando o widget é adicionado à barra lateral   enquanto 'sortstop' é chamado sempre que você move o widget   dentro da barra lateral ou remova-a.

     

'sortstop' também é chamado quando o widget é adicionado, mas por algum motivo   ui.input não está definido corretamente, então eu usei 'sortreceive' para cobrir isso.

jQuery('div.widgets-sortables').bind('sortstop',function(event,ui){
  var id = jQuery(ui.item).attr('id');
  if (id) {
    var widget_type = id.match(/widget-[0-9]+_(.+)-[0-9]+/i)[1];
    if (widget_type == 'your_widget') {
    // do stuff;
    }
  }
})

jQuery('div.widgets-sortables').bind('sortreceive',function(event,ui){
  var id = jQuery(ui.item).attr('id');
  var widget_type = id.match(/widget-[0-9]+_(.+)-__i__/i)[1];
  if (widget_type == 'your_widget') {
    // do stuff;
  }
})

Trabalhei recentemente em uma resposta onde um widget específico pode ser removido da matriz de widgets de uma barra lateral específica. Aqui, usamos o filtro sidebars_widgets para remover um widget específico de todas as barras laterais, exceto a barra lateral onde deveria estar.

Em suma, um widget que é adicionado incorretamente a uma barra lateral não será exibido no front-end e também não retornará true com um is_active_sidebar() verificar se esse widget é o único widget adicionado a essa barra lateral específica.

Você pode tentar o seguinte código, apenas certifique-se de alterar os valores do widget e da barra lateral de acordo.

add_filter( 'sidebars_widgets', function ( $sidebars_widgets )
{
    // Return our filter when we are on admin screen
    if ( is_admin() )
        return $sidebars_widgets;

    /**
     * Widget we need to target. This should be the name/id we used to register it
     *
     * EXAMPLE
     * parent::__construct(
            'widget_category_posts', 
            _x( 'Category Posts Widget', 'Category Posts Widget' ), 
            [ 'description' => __( 'Display a list of posts from a selected category.' ) ] 
        );
     *
     */
    $custom_widget  = 'widget_category_posts';
    // The sidebar ID we need to run the widget in
    $sidebar_accept = 'sidebar-2';

    // We have come this far, let us wrap this up
    // See if our custom content widget exists is any sidebar, if so, get the array index
    foreach ( $sidebars_widgets as $sidebars_key=>$sidebars_widget ) {
        // Skip the wp_inactive_widgets set, we do not need them
        if ( $sidebars_key == 'wp_inactive_widgets' )
        continue;

        // Only continue our operation if $sidebars_widget are not an empty array
        if ( $sidebars_widget ) {
            foreach ( $sidebars_widget as $k=>$v ) {

                /**
                 * Look for our custom widget, if found, unset it from the $sidebars_widgets array
                 * @see stripos()
                 */
                if ( stripos( $v, $custom_widget ) !== false ) {
                    // If we are on a single page and the sidebar is $sidebar_accept, do not unset
                    if ( is_single() && $sidebars_key == $sidebar_accept )
                        continue;

                    unset( $sidebars_widgets[$sidebars_key][$k] );
                }
            } // endforeach $sidebars_widget
        } // endif $sidebars_widget
    } // endforeach $sidebars_widgets

    return $sidebars_widgets;
});

Em conclusão, esta é apenas uma solução PHP que funciona apenas para o front-end, mas peço-lhe que ainda procure uma solução jquery adequada, em que um widget esteja vinculado apenas a uma barra lateral específica no backend. Como eu disse, a solução jquery do link não foi testada e não sei se realmente funciona

    
por Pieter Goosen 30.09.2015 / 07:33
1

Como complemento aos seus scripts, eu escrevi o script que oculta barras laterais da lista suspensa (não consegui encontrar isso em lugar algum). Eu fiz algumas engenharia reversa do original do WordPress widgets.js para escrever isso.

A solução completa para permitir arrastar & soltar apenas para barras laterais especificadas e para filtrar a lista suspensa (você só precisa colocar isso em seu documento pronto script admin jQuery):

function allowedSidebars(allowed)
{
    // this variable will have index of first visible sidebar
    var first = null;
    $('.widgets-chooser-sidebars li').removeClass('widgets-chooser-selected').each(function(index)
    {
        // the data('sidebarId') is set up by wordpress, let's make us of it
        if(-1 === $.inArray($(this).data('sidebarId'), allowed))
        {
            $(this).hide();
        }
        else if(first == null)
        {
            first = index;
        }
    });
    // choose first visible sidebar as default
    if(first != null)
    {
        $('.widgets-chooser-sidebars li').eq(first).addClass('widgets-chooser-selected');
    }
}
$('#available-widgets .widget .widget-title').on('click.widgets-chooser', function()
{
    var widget = $(this).closest('.widget');
    // we want to run our script only on slideDown, not slideUp
    if(!widget.hasClass('widget-in-question'))
    {
        // there is only one sidebar list per all widgets, so we have to show all the sidebars every time
        $('.widgets-chooser-sidebars li').show();
        switch(widget.find('input[name="id_base"]').val())
        {
            // your widgets here
            case 'your_widget_id':
                // allowed sidebars for widget
                allowedSidebars(['your-sidebar-id', 'your-second-sidebar-id']);
            break;
        }
    }
});
// this will make drag and drop working only for specified sidebars
$('.widget').on('dragcreate dragstart', function( event, ui ) {
    var id = $(this).find('input[name="id_base"]').val();
    // probably you may want to change it to switch
    if(id == 'your_widget_id')
    {
        $(this).draggable({
            connectToSortable: '#your-sidebar-id, #your-second-sidebar-id'
        });
    }
});
    
por icetique 19.05.2016 / 20:34