Может ли виджет в Customizer быть «одноразовым» (т. Е. Отключен после добавления 1 экземпляра)?

Я нахожусь в ночном поиске, чтобы создать настраиваемый одноразовый виджет .

Как только один экземпляр его был добавлен на панель боковой панели в Настройке , его элемент управления на панели Доступные виджеты должен быть отображен как отключенный (или, альтернативно, , полностью исчезают).

Вот как это будет выглядеть (обратите внимание на визуальный «отключенный» виджет справа):

 ...

Пользовательский виджет зарегистрирован и все, но я застрял в одноразовом требовании.

функции

  • Масштаб не является проблемой. Вполне допустимо считать только одну зарегистрированную боковую панель. Подход может заключаться в том, чтобы ограничить использование виджета либо 1 на боковую панель, либо 1 на все зарегистрированные боковые панели - оба будут одинаково хороши на данный момент.
  • Страница Widgets на внутреннем сервере не является проблемой. Это не требуется для одинаково хорошо работать на странице Widgets в Внешний вид на фоны. Он должен работать только в Настройщике.

Вопросы

  1. Около 250 лет назад все виджеты были «одноразовыми». Кто-нибудь знает о законном способе вернуть эти времена и сделать собственный виджет, который будет использоваться только через 1x через API-интерфейс Widget?
  2. Если нет (что я предполагаю после того, как я вырыл большое количество файлов ядра), я бы, вероятно, отложил бы подход, основанный на CSS (указатель-события, наложение псевдоэлементов, что угодно). Помогла ли какая-либо любезная помощь моим very ограниченным знаниям Customizer /JavaScript с базовым подходом к тому, как добавить /удалить выделенный класс CSS в элемент управления виджета на панели «Доступные» (тот, справа), когда экземпляр указанного виджета был добавлен /удален на панель боковой панели?

То, что я пробовал до сих пор

  • Прокопайте яркий кусок основных файлов.
  • Прочитайте это , и это , но ни один из них не кажется практичным.
  • Трюк с событиями jQuery widget-added, widget-updated и widget-synced, но пропустите событие для «виджета».

Спасибо за тонну!


Обновление: не поставили мое доказательство концепции на публичное репо, конечно, сделают.

Решение

Я завернул решение, любезно предоставленное kraftner ниже в доказательстве концептуального плагина на GitHub .

8 голосов | спросил glueckpress 28 22017vEurope/Moscow11bEurope/MoscowTue, 28 Nov 2017 21:00:49 +0300 2017, 21:00:49

1 ответ


5

Подход

Итак, я изучил это, и мой подход таков:

  1. При запуске настраивателя пройдите через все боковые панели и отключите виджет, как только вы найдете его использование
  2. Всякий раз, когда боковая панель изменяется, сделайте это снова.

Отказ

Это имеет следующие ограничения:

  1. Это первый раз, когда я играл в JS API для Customizer. Поэтому я мог бы делать неэффективные вещи здесь, но эй, это работает;)
  2. Только заботится о Настройщике (как указано в вопросе)
  3. Не делает никакой проверки на стороне сервера. Он просто скрывает пользовательский интерфейс, поэтому, если вы беспокоитесь о том, что кто-то обходит пользовательский интерфейс, это неполное /небезопасное.
  4. Отключение виджета глобально - любое использование на любой боковой панели отключает виджет глобально.

Код

Теперь, когда у нас есть Отказ от ответственности, давайте посмотрим на код:

(function() {
    wp.customize.bind( 'ready', function() {

        var api = wp.customize,
            widgetId = 'foo_widget',
            widget = wp.customize.Widgets.availableWidgets.findWhere( { id_base: widgetId } );

        /**
         * Counts how often a widget is used based on an array of Widget IDs.
         *
         * @param widgetIds
         * @returns {number}
         */
        var countWidgetUses = function( widgetIds ){

            var widgetUsedCount = 0;

            widgetIds.forEach(function(id){

                if( id.indexOf( widgetId ) == 0 ){
                    widgetUsedCount++;
                }

            });

            return widgetUsedCount;

        };

        var isSidebar = function( setting ) {
            return (
                0 === setting.id.indexOf( 'sidebars_widgets[' )
                &&
                setting.id !== 'sidebars_widgets[wp_inactive_widgets]'
            );
        };

        var updateState = function(){

            //Enable by default...
            widget.set('is_disabled', false );

            api.each( function( setting ) {
                if ( isSidebar( setting ) ) {
                    //...and disable as soon as we encounter any usage of the widget.
                    if( countWidgetUses( setting.get() ) > 0 ) widget.set('is_disabled', true );
                }
            } );

        };

        /**
         * Listen to changes to any sidebar.
         */
        api.each( function( setting ) {
            if ( isSidebar( setting ) ) {
                setting.bind( updateState );
            }
        } );

        updateState();

    });
})( jQuery );

Sidenote: для добавления скрипта используйте действие customize_controls_enqueue_scripts.


Возможно, вы могли бы расширить это, чтобы ограничить его работой a на боковую панель вместо глобального. Я бы сказал, слушают активацию боковой панели, а затем подсчитывают виджетов на этой боковой панели. Но я не нашел времени для изучения этого.

ответил kraftner 1 FriEurope/Moscow2017-12-01T15:53:32+03:00Europe/Moscow12bEurope/MoscowFri, 01 Dec 2017 15:53:32 +0300 2017, 15:53:32

Похожие вопросы

Популярные теги

security × 330linux × 316macos × 2827 × 268performance × 244command-line × 241sql-server × 235joomla-3.x × 222java × 189c++ × 186windows × 180cisco × 168bash × 158c# × 142gmail × 139arduino-uno × 139javascript × 134ssh × 133seo × 132mysql × 132