Ogranicz liczbę widżetów na paskach bocznych

17

Jeśli korzystam z niestandardowego obszaru widżetu (na przykład stopki), w którym istnieje tylko ograniczona liczba miejsc dla widżetów (zgodnie z projektem), czy mogę ograniczyć liczbę widżetów, które użytkownik może uwzględnić w tym konkretnym obszarze widżetów? Nie ma znaczenia, czy rozwiązanie znajduje się na zapleczu, czy na froncie. Dziękuję Ci.

Jukow
źródło

Odpowiedzi:

10

Rozwiązałem to w JavaScript. Jeśli chcesz całkowicie temu zapobiec, powinieneś to zrobić również po stronie serwera, ponieważ możesz edytować widżety przy wyłączonym Javascript (wypróbuj!).

Różne paski boczne są sprawdzane, gdy upuszczasz do nich widżety lub z dala od nich. Jeśli się zapełni, kolor tła zmienia się i nie można już na nie upuszczać przedmiotów. Jeśli podczas uruchamiania pasek boczny jest już więcej niż pełny (ponieważ zaostrzyłeś ograniczenie), kolor tła staje się czerwony. Nadal możesz przeciągać widżety z pełnych widżetów, aby ponownie je opróżnić.

Jeden pełny i jeden więcej niż pełny pasek boczny

Przetestuj ten kod, aby znaleźć sposoby dodawania lub usuwania widżetów, które przegapiłem. „Magia” w kodzie jQuery pochodzi od Amana , który odpowiedział na postawione przeze mnie pytanie dotyczące przepełnienia stosu .

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, aby je załadować:

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

Próba sprawdzenia po stronie serwera (prawdopodobnie jeszcze nie zakończona):

$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
źródło
wow +1 ... czego brakuje w funkcji po stronie serwera? Nie wypróbowałem, ale zainteresowałem się.
kaiser
Chciałem czegoś więcej po stronie serwera, ale kiedy o tym myślę, może masz rację. musi to być ograniczone przez JS. Spróbuję wymyślić bardziej solidne rozwiązanie, być może całkowite niedopuszczenie kropli widżetów za pośrednictwem JS
Jukov,
Istnieje pytanie dotyczące Twojego kodu w Ogranicz liczbę widżetów na paskach bocznych - błąd .
Charles Clarkson
5

Mam nadzieję, że pomogę ci w twoim pytaniu. Użyjmy first-footer-widget-areateraźniejszości w domyślnym sidebar-footer.phppliku szablonu Dwadzieścia Dziesięciu jako przykład.

Jako dobrą praktykę i bezpieczne najpierw wykonaj kopię zapasową, aby uniknąć bólu głowy.

Oryginalny kod szablonu Twenty Ten do prezentacji widgetu pierwszej stopki to:

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

Zmieńmy, dodając kod z warunkami, aby ograniczyć liczbę widżetów dozwolonych w tym obszarze.

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

Do czego służy ten zmodyfikowany kod:

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

policz liczbę widżetów na tym pasku bocznym i ustal dozwolony limit (ustalany przez ciebie).

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

Jeśli limit dozwolony dla widżetów w tym obszarze został osiągnięty, pojawi się komunikat ostrzegawczy, że w przeciwnym razie widżet zostanie wyświetlony.

Mam więc nadzieję, że pomogłem w twoim pytaniu.

Hans Zimermann
źródło
0

Interesujące pytanie. Krótko się nie dowiedziałem, ale zgaduję: print_r( $GLOBALS['wp_registered_sidebars'] );lub print_r( $GLOBALS['sidebars'] );lub print_r( $GLOBALS['sidebars_widgets'] );...

kajzer
źródło
0

Możesz wykonać poniższe czynności, aby określić liczbę widżetów.

Funkcjonować:

$mysidebars = wp_get_sidebars_widgets() - wyświetli listę pasków bocznych i widżetów używanych na tych paskach.

$total_widgets = count( $mysidebars['my-sidebar-id'] ); - poda ci całkowitą liczbę widżetów w moim identyfikatorze paska bocznego

Mam nadzieję, że rozwiąże to twoje wątpliwości.

Todd
źródło