web-dev-qa-db-ja.com

カスタマイザ内のウィジェットは「シングルユース」(つまり、1つのインスタンスが追加された後に無効)にすることはできますか?

私は毎晩、{カスタムの使い捨てウィジェットを作成しようとしています。

その1つのインスタンスがサイドバーパネルカスタマイザ内に追加されるとすぐに、Available Widgetsパネル上のそのコントロールは無効として表示される(または完全に消える)になります。

これはどのように見えるかです(右側の視覚的に「無効にされた」ウィジェットに注意してください)

… 

カスタムウィジェットは登録済みですべてですが、私は使い捨ての要件にこだわっています。

スペック

  • スケールは問題ではありません。登録されているサイドバーを1つだけと仮定しても問題ありません。このアプローチは、ウィジェットの使用をサイドバーあたり1つ、またはall登録済みサイドバーごとに1つに制限することができます。どちらも今のところ同様に問題ありません。
  • バックエンドのWidgetsページは問題ありません。 _これは、バックエンドのAppearanceの下のWidgetsページで同様に機能するためには必要ありません。カスタマイザ内で動作するだけです。

質問

  1. 約250年前、すべてのウィジェットは「使い捨て」でした。誰かがそれらの時代を取り戻してカスタムウィジェットをウィジェットAPIを通して1倍しか使わないようにするための合法的な方法を知っていますか?
  2. そうでなければ(かなりの量のコアファイルを掘った後に仮定しているのであれば)、おそらくCSSベースのアプローチ(ポインタイベント、疑似要素オーバーレイなど)に頼るでしょう。 どんな種類の魂も私の非常に限定されたカスタマイザ/ JavaScriptの知識を「利用可能な」パネルのウィジェットコントロールに追加/削除する方法に関する基本的なアプローチで手助けしますか?ウィジェットのインスタンスがサイドバーパネルに追加/削除されたら?

これまでに試したこと

  • かなりの量のコアファイルを掘り下げます。
  • これ 、および これ を読んでください、しかしどちらも実用的ではないようです。
  • JQueryイベントのwidget-addedwidget-updated、およびwidget-syncedに悩まされていますが、「widget deleted」のイベントを見逃しています。

事前にありがとうトン!


最新情報:私の概念実証をまだ公共の場で行っているわけではないが、もちろんそうするだろう。

溶液

以下のkraftnerの親切な解決策をGitHubの proof of conceptプラグインで包みました

8
glueckpress

アプローチ

それで、私はこれを調べました、そして、私のアプローチはこれです:

  1. カスタマイザを起動するときは、すべてのサイドバーを見て、使い方が見つかったらすぐにウィジェットを無効にします。
  2. サイドバーが変更されたときはいつでもやり直してください。

免責事項

これには以下の制限があります。

  1. これが私がカスタマイザのJS APIで遊ぶのに初めて手を出したのです。それで、私はここで非効率的なことをしているかもしれません、しかし、それはうまくいきます;)
  2. カスタマイザについてのみ気にする(質問に記載)
  3. いかなる種類のサーバー側検証も行いません。それは単にUIを隠しているだけなので、誰かがUIを迂回することを心配しているならば、これは不完全/安全ではありません。
  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 );

サイドノート:customize_controls_enqueue_scriptsアクションを使ってスクリプトを追加してください。


これを拡張して、グローバルではなくサイドバーごとのベースで動作するように制限することができます。サイドバーのアクティブ化を聞いてから、そのサイドバーのウィジェットを数えます。しかし、私もそれを調べる時間がありませんでした。

5
kraftner