Limite el número de widgets en las barras laterales

17

Si uso un área de widgets personalizada (por ejemplo, pie de página) donde solo hay un número limitado de puntos para widgets (por diseño), ¿puedo limitar la cantidad de widgets que el usuario puede incluir en esa área específica de widgets? No importa si la solución está en el backend o en el front end. Gracias.

Jukov
fuente

Respuestas:

10

Resolví esto en Javascript. Si desea evitarlo por completo, también debe hacerlo en el servidor, ya que puede editar los widgets con Javascript deshabilitado (¡pruébelo!).

Las diferentes barras laterales se verifican cuando sueltas widgets en ellas o las alejas de ellas. Si se llenan, el color de fondo cambia y ya no puede colocar elementos sobre ellos. Si, en el inicio, la barra lateral ya está más que llena (porque ajustó la restricción), el color de fondo se vuelve rojo. Todavía puede arrastrar los widgets lejos de los widgets completos para volverlos vacíos.

Una barra lateral completa y otra más que completa

Pruebe este código para encontrar formas de agregar o eliminar widgets que me perdí. La "magia" en el código jQuery proviene de Aman , quien respondió una pregunta de Stack Overflow que publiqué al respecto .

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 cargarlos:

$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'] ) );
    }
}

Un intento de verificación del lado del servidor (probablemente aún no se haya completado):

$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
fuente
wow +1 ... ¿qué falta con la función del lado del servidor? No lo probé, pero me impresionó.
Kaiser
Quería algo más del lado del servidor, pero cuando lo pienso, tal vez tengas razón. esto debe estar limitado por JS. Trataré de pensar en una solución más robusta, tal vez rechazando por completo las gotas de widgets a través de JS
Jukov
Hay una pregunta sobre su código en Limitar el número de widgets en barras laterales: error .
Charles Clarkson
4

Para ayudarte con tu pregunta, tengo una sugerencia. Usemos el first-footer-widget-areapresente en el sidebar-footer.phparchivo de plantilla Twenty Ten predeterminado como ejemplo.

Como práctica recomendada y segura, primero haga una copia de seguridad para evitar dolores de cabeza.

El código original de la plantilla Twenty Ten para presentar el primer widget de pie de página es:

<?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; ?>

Cambiemos, agregando un código con condicionales para limitar la cantidad de widgets permitidos en esa á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; ?>

Lo que hace este código modificado:

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

cuente la cantidad de widgets en esa barra lateral y establezca algún límite permitido (establecido por usted).

...
<?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 }; ?>
...

Si se alcanzó el límite permitido para los widgets en esa área, se mostrará un mensaje de advertencia que indica que, de lo contrario, se mostrará el widget.

Así que espero haberte ayudado con tu pregunta.

Hans Zimermann
fuente
0

Interesante P. No descubrí mucho en un breve vistazo, pero aquí hay una suposición: print_r( $GLOBALS['wp_registered_sidebars'] );o print_r( $GLOBALS['sidebars'] );o print_r( $GLOBALS['sidebars_widgets'] );...

emperador
fuente
0

Puede hacer lo siguiente para determinar el recuento de widgets.

Función:

$mysidebars = wp_get_sidebars_widgets() - le dará la lista de barras laterales y widgets utilizados en esas barras laterales.

$total_widgets = count( $mysidebars['my-sidebar-id'] ); - le dará el recuento de widgets totales en my-sidebar-id

Espero que esto resuelva tus dudas.

Todd
fuente