Limitar o número de widgets nas barras laterais

17

Se eu usar uma área widgetizada personalizada (por exemplo, rodapé) em que há apenas um número limitado de pontos para widgets (por design), posso limitar o número de widgets que o usuário pode incluir nessa área widgetizada específica? Não importa se a solução está no back-end ou no front-end. Obrigado.

Jukov
fonte

Respostas:

10

Eu resolvi isso em Javascript. Se você deseja evitá-lo completamente, também deve fazê-lo no servidor, porque é possível editar os widgets com o Javascript desativado (experimente!).

As diferentes barras laterais são verificadas quando você solta os widgets neles ou para longe deles. Se eles ficarem cheios, a cor do plano de fundo será alterada e você não poderá mais soltar itens neles. Se, na inicialização, a barra lateral já estiver mais do que cheia (porque você restringiu a restrição), a cor do plano de fundo ficará vermelha. Você ainda pode arrastar os widgets para longe dos widgets completos para torná-los vazios novamente.

Uma barra lateral cheia e uma mais que cheia

Teste este código para encontrar maneiras de adicionar ou remover widgets que eu perdi. A "mágica" no código jQuery vem de Aman , que respondeu a uma pergunta Stack Overflow eu postei sobre isso .

Javascript:

jQuery( function( $ ) {
    var sidebarLimits = {
        'sidebar-1': 2,
        'sidebar-2': 2,
    };
    var realSidebars = $( '#widgets-right div.widgets-sortables' );
    var availableWidgets = $( '#widget-list' ).children( '.widget' );

    var checkLength = function( sidebar, delta ) {
        var sidebarId = sidebar.id;
        if ( undefined === sidebarLimits[sidebarId] ) {
            return;
        }

        // This is a limited sidebar
        // Find out how many widgets it already has
        var widgets = $( sidebar ).sortable( 'toArray' );
        $( sidebar ).toggleClass( 'sidebar-full', sidebarLimits[sidebarId] <= widgets.length + (delta || 0) );
        $( sidebar ).toggleClass( 'sidebar-morethanfull', sidebarLimits[sidebarId] < widgets.length + (delta || 0) );

        var notFullSidebars = $( 'div.widgets-sortables' ).not( '.sidebar-full' );
        availableWidgets.draggable( 'option', 'connectToSortable', notFullSidebars );
        realSidebars.sortable( 'option', 'connectWith', notFullSidebars );
    }

    // Check existing sidebars on startup
    realSidebars.map( function() {
        checkLength( this );
    } );

    // Update when dragging to this (sort-receive)
    // and away to another sortable (sort-remove)
    realSidebars.bind( 'sortreceive sortremove', function( event, ui ) {
        checkLength( this );
    } );

    // Update when dragging back to the "Available widgets" stack
    realSidebars.bind( 'sortstop', function( event, ui ) {
        if ( ui.item.hasClass( 'deleting' ) ) {
            checkLength( this, -1 );
        }
    } );

    // Update when the "Delete" link is clicked
    $( 'a.widget-control-remove' ).live( 'click', function() {
        checkLength( $( this ).closest( 'div.widgets-sortables' )[0], -1 );
    } );
} );

CSS:

.sidebar-full
{
    background-color: #cfe1ef !important;
}

.sidebar-morethanfull
{
    background-color: #c43 !important;
}

PHP para carregá-los:

$wpse19907_file = $plugin;
add_action( 'admin_enqueue_scripts', 'wpse19907_admin_enqueue_scripts' );
function wpse19907_admin_enqueue_scripts( $hook_suffix )
{
    if ( 'widgets.php' == $hook_suffix ) {
        wp_enqueue_script( 'wpse-19907', plugins_url( 'wpse-19907.js', $GLOBALS['wpse19907_file'] ), array(), false, true );
        wp_enqueue_style( 'wpse-19907', plugins_url( 'wpse-19907.css', $GLOBALS['wpse19907_file'] ) );
    }
}

Uma tentativa de verificação do lado do servidor (provavelmente ainda não concluída):

$wpse19907_sidebars_max_widgets = array(
    'sidebar-1' => 2,
);

add_action( 'sidebar_admin_setup', 'wpse19907_sidebar_admin_setup' );
function wpse19907_sidebar_admin_setup()
{
    if ( ! isset( $_POST['action'] ) || 'save-widget' != $_POST['action'] || empty( $_POST['add_new'] ) ) {
        return;
    }

    // We're adding a new widget to a sidebar
    global $wpse19907_sidebars_max_widgets;
    $sidebar_id = $_POST['sidebar'];

    if ( ! array_key_exists( $sidebar_id, $wpse19907_sidebars_max_widgets ) ) {
        return;
    }

    $sidebar = wp_get_sidebars_widgets();
    $sidebar = isset( $sidebars[$sidebar_id] ) ? $sidebars[$sidebar_id] : array();

    if ( count( $sidebar ) <= $wpse19907_sidebars_max_widgets[$sidebar_id] ) {
        die( 'mx' ); // Length must be shorter than 2, and unique
    }
}
Jan Fabry
fonte
uau +1 ... o que está faltando com a função do lado do servidor? Não tentei, mas interessada.
kaiser
Eu queria algo mais do lado do servidor, mas quando penso nisso, talvez você esteja certo. isso precisa ser limitado pelo JS. Vou tentar pensar em uma solução mais robusta, talvez não permitindo gotas de widgets totalmente via JS
Jukov
Há uma pergunta sobre o seu código no número limite de widgets nas barras laterais - bug .
Charles Clarkson
4

para ajudá-lo com sua pergunta, tenho uma sugestão. Vamos usar o first-footer-widget-areapresente no sidebar-footer.phparquivo de modelo padrão Twenty Ten como um exemplo.

Como uma boa prática e segura, faça um backup primeiro para evitar dores de cabeça.

O código do modelo Twenty Ten original para apresentar o widget do primeiro rodapé é:

<?php if ( is_active_sidebar( 'first-footer-widget-area' ) ) : ?>
       <div id="first" class="widget-area">
        <ul class="xoxo">
            <?php dynamic_sidebar( 'first-footer-widget-area' ); ?>
        </ul>
       </div><!-- #first .widget-area -->
<?php endif; ?>

Vamos mudar, adicionando algum código com condicionais para limitar o número de widgets permitidos nessa área.

<?php if ( is_active_sidebar( 'first-footer-widget-area' ) ) : ?>
    <div id="first" class="widget-area">
    <?php
           $mysidebars = wp_get_sidebars_widgets();
           $total_widgets = count( $mysidebars['first-footer-widget-area'] );
           $limit_allowed=2;
    ?>
        <ul class="xoxo">
            <?php  if ($total_widgets > $limit_allowed) {
                echo 'Your '.$total_widgets.' added widgets goes over the allowed limit: <strong>'.$limit_allowed.'</trong>';
                } else { ?>
            <?php dynamic_sidebar( 'first-footer-widget-area' ); ?>
          <?php }; ?>
        </ul>

        </div><!-- #first .widget-area -->
<?php endif; ?>

O que esse código modificado faz:

$mysidebars = wp_get_sidebars_widgets();
$total_widgets = count( $mysidebars['first-footer-widget-area'] );
$limit_allowed=2;

conte o número de widgets nessa barra lateral e estabeleça algum limite permitido (definido por você).

...
<?php  if ($total_widgets > $limit_allowed) {
            echo 'Your '.$total_widgets.' added widgets goes over the allowed limit: <strong>'.$limit_allowed.'</trong>';
       } else { ?>
            <?php dynamic_sidebar( 'first-footer-widget-area' ); ?>
<?php }; ?>
...

Se o limite permitido para widgets nessa área for atingido, será exibida uma mensagem avisando que o limite é limite, caso contrário o widget será mostrado.

Então, espero ter ajudado com sua pergunta.

Hans Zimermann
fonte
0

Interessante P. Não descobri muito de uma breve olhada, mas aqui está um palpite: print_r( $GLOBALS['wp_registered_sidebars'] );ou print_r( $GLOBALS['sidebars'] );ou print_r( $GLOBALS['sidebars_widgets'] );...

kaiser
fonte
0

Você pode fazer as coisas abaixo para determinar a contagem de widgets.

Função:

$mysidebars = wp_get_sidebars_widgets() - fornecerá a lista de barras laterais e widgets usados ​​nessas barras laterais.

$total_widgets = count( $mysidebars['my-sidebar-id'] ); - fornecerá a contagem do total de widgets em my-sidebar-id

Espero que isso resolva suas dúvidas.

Todd
fonte