Batasi jumlah Widget di Sidebars

17

Jika saya menggunakan area khusus widget (misalnya footer) di mana hanya ada sedikit tempat untuk widget (menurut desain), dapatkah saya membatasi jumlah widget yang dapat dimasukkan pengguna dalam area widget khusus itu? Tidak masalah apakah solusinya ada di backend atau ujung depan. Terima kasih.

Jukov
sumber

Jawaban:

10

Saya memecahkan ini dalam Javascript. Jika Anda ingin benar-benar mencegahnya Anda juga harus melakukannya di sisi server, karena Anda dapat mengedit widget dengan Javascript dinonaktifkan (coba saja!).

Bilah sisi yang berbeda diperiksa saat Anda menjatuhkan widget kepadanya atau menjauh darinya. Jika mereka penuh, warna latar belakang berubah dan Anda tidak bisa lagi menjatuhkan item pada mereka. Jika, saat startup, bilah samping sudah lebih dari penuh (karena Anda memperketat batasannya), warna latar menjadi merah. Anda masih dapat menyeret widget dari widget penuh untuk membuatnya kosong lagi.

Satu sidebar penuh dan satu lebih dari penuh

Silakan uji kode ini, untuk menemukan cara untuk menambah atau menghapus widget yang saya lewatkan. "Ajaib" dalam kode jQuery berasal dari Aman , yang menjawab pertanyaan Stack Overflow yang saya posting tentang itu .

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

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

Upaya pemeriksaan sisi server (mungkin belum selesai):

$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
sumber
wow +1 ... apa yang hilang dengan fungsi sisi server? Tidak mencobanya, tetapi bersyafaat.
kaiser
Saya menginginkan sesuatu yang lebih dari sisi server, tetapi ketika saya memikirkannya, mungkin Anda benar. ini perlu dibatasi oleh JS. Saya akan mencoba memikirkan solusi yang lebih kuat, mungkin melarang tetes widget sama sekali melalui JS
Jukov
Ada pertanyaan tentang kode Anda di Limit number of Widgets in Sidebars - bug .
Charles Clarkson
4

untuk membantu Anda dengan pertanyaan Anda, saya punya saran. Mari kita gunakan first-footer-widget-areahadiah dalam sidebar-footer.phpfile templat Twenty Ten default seperti contoh.

Sebagai praktik yang baik dan aman, pertama-tama buat cadangan untuk menghindari sakit kepala.

Kode template Twenty Ten yang asli untuk menyajikan widget footer pertama adalah:

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

Mari kita ubah, menambahkan beberapa kode dengan persyaratan untuk membatasi jumlah widget yang diizinkan di area itu.

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

Apa yang dilakukan oleh kode yang dimodifikasi ini:

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

hitung jumlah widget di bilah sisi itu dan tentukan beberapa batas yang diizinkan (ditetapkan oleh Anda).

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

Jika batas yang diizinkan untuk widget di area itu tercapai, maka akan muncul pesan peringatan bahwa batas lain widget akan ditampilkan.

Jadi saya harap saya telah membantu dengan pertanyaan Anda.

Hans Zimermann
sumber
0

Interessting Q. Tidak menemukan keluar banyak di sekilas, tapi di sini menebak: print_r( $GLOBALS['wp_registered_sidebars'] );atau print_r( $GLOBALS['sidebars'] );atau print_r( $GLOBALS['sidebars_widgets'] );...

kaisar
sumber
0

Anda dapat melakukan hal-hal di bawah ini untuk menentukan jumlah widget.

Fungsi:

$mysidebars = wp_get_sidebars_widgets() - akan memberi Anda daftar bilah sisi dan widget yang digunakan pada bilah sisi itu.

$total_widgets = count( $mysidebars['my-sidebar-id'] ); - akan memberi Anda hitungan total widget di my-sidebar-id

Saya harap ini akan menyelesaikan keraguan Anda.

Todd
sumber