Ограничить количество виджетов на боковых панелях

17

Если я использую настраиваемую область виджетов (например, нижний колонтитул), где имеется только ограниченное количество мест для виджетов (по конструкции), могу ли я ограничить количество виджетов, которые пользователь может включить в эту конкретную область виджетов? Не имеет значения, находится ли решение на бэкэнде или на переднем конце. Спасибо.

Jukov
источник

Ответы:

10

Я решил это в Javascript. Если вы хотите полностью предотвратить это, вы также должны сделать это на стороне сервера, потому что вы можете редактировать виджеты с отключенным Javascript (попробуйте!).

Различные боковые панели проверяются, когда вы перетаскиваете виджеты на них или подальше от них. Если они заполнятся, цвет фона изменится, и вы больше не сможете оставлять на них элементы. Если при запуске боковая панель уже переполнена (поскольку вы ужесточили ограничение), цвет фона становится красным. Вы все еще можете перетащить виджеты из полных виджетов, чтобы они снова стали пустыми.

Одна полная и одна более полная боковая панель

Пожалуйста, проверьте этот код, чтобы найти способы добавить или удалить виджеты, которые я пропустил. «Волшебство» в коде jQuery происходит от Амана , который ответил на вопрос о переполнении стека , который я опубликовал по этому поводу .

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 для их загрузки:

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

Попытка проверки на стороне сервера (возможно, еще не завершена):

$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
    }
}
Ян Фабри
источник
вау +1 ... чего не хватает с функцией на стороне сервера? Не пробовал, но заинтересовался.
Кайзер
Я хотел чего-то большего от серверной стороны, но когда я думаю об этом, возможно, вы правы. это должно быть ограничено JS. Я попытаюсь придумать более надежное решение, может быть, вообще не разрешать выпадение виджетов через JS
Jukov
Есть вопрос о вашем коде в Ограничении количества виджетов в боковых панелях - ошибка .
Чарльз Кларксон
5

чтобы помочь вам с вашим вопросом, у меня есть предложение. Давайте использовать first-footer-widget-areaподарок в стандартном sidebar-footer.phpфайле шаблона Twenty Ten как пример.

В качестве хорошей практики и безопасности сначала сделайте резервную копию, чтобы избежать головной боли.

Исходный код шаблона Twenty Ten для представления первого виджета нижнего колонтитула:

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

Давайте изменим, добавив код с условными выражениями, чтобы ограничить количество виджетов, разрешенных в этой области.

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

Что делает этот модифицированный код:

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

посчитайте количество виджетов в этой боковой панели и установите допустимый предел (установленный вами).

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

Если предел, разрешенный для виджетов в этой области, был достигнут, то будет отображаться сообщение с предупреждением, ограничивающее, в противном случае виджет будет отображаться.

Поэтому я надеюсь, что помог с вашим вопросом.

Ханс Цимерманн
источник
0

Интересно В. Не очень много узнал при кратком обзоре, но вот предположение: print_r( $GLOBALS['wp_registered_sidebars'] );или print_r( $GLOBALS['sidebars'] );или print_r( $GLOBALS['sidebars_widgets'] );...

кайзер
источник
0

Вы можете сделать следующие вещи, чтобы определить количество виджетов.

Функция:

$mysidebars = wp_get_sidebars_widgets() - даст вам список боковых панелей и виджетов, используемых на этих боковых панелях.

$total_widgets = count( $mysidebars['my-sidebar-id'] ); - подсчитает общее количество виджетов в my-sidebar-id

Я надеюсь, что это решит ваши сомнения.

Тодд
источник