カスタマイザーのウィジェットを「使い捨て」にすることはできますか(つまり、1つのインスタンスが追加された後に無効化されます)?


8

私は、カスタムの使い捨てウィジェットを作成するために毎晩クエストをしています

カスタマイザのサイドバーパネルにそのインスタンスの1つが追加されるとすぐに、[利用可能なウィジェット]パネルのコントロールが無効として表示されます(または、完全に非表示になります)。

これは、次のようになります(右側の視覚的に「無効」なウィジェットに注意してください)。

…

カスタムウィジェットはすべて登録されていますが、使い捨ての要件に行き詰まっています。

スペック

  • スケールは問題ではありません。登録されているサイドバーを1つだけと仮定しても問題ありません。このアプローチでは、ウィジェットの使用をサイドバーごとに1つ、またはすべての登録済みサイドバーごとに1つに制限することができます。現時点ではどちらも同じように問題ありません。
  • バックエンドのウィジェットページは問題ありません。これは、バックエンドの[ 外観]の [ ウィジェット]ページで同じように機能する必要はありません。カスタマイザでのみ機能する必要があります。

ご質問

  1. 約250年前、すべてのウィジェットは「使い捨て」でした。それらの時代を取り戻し、カスタムウィジェットをWidget APIを介して1回だけ使用する正当な方法を知っている人はいますか?
  2. そうでない場合(かなりの量のコアファイルを掘り下げた後で想定しています)、CSSベースのアプローチ(ポインターイベント、疑似要素オーバーレイなど)を使用します。上記のウィジェットのインスタンスが作成されたら、「利用可能な」パネル(右側のパネル)のウィジェットコントロールに専用のCSSクラスを追加/削除する方法に関する基本的なアプローチを使用して、非常に限られたカスタマイザ/ JavaScriptの知識を助けてください。サイドバーパネルに追加/削除されましたか?

これまでに試したこと

  • コアファイルのかなりの部分を掘り下げます。
  • これこれを読んでください。しかしどちらも実用的ではないようです。
  • jQueryのイベントに手を加えwidget-addedwidget-updated、とwidget-synced、しかし、「ウィジェットを削除」のイベントを欠場。

トンありがとう!


更新:概念実証はまだ公開レポに公開していませんが、もちろん実行します。

解決

以下のクラフトナーが親切に共有したソリューションを、GitHubの概念実証プラグインにラップしました。


WP_Widgetたとえば、代わりにクラシックウィジェットAPIを使用することもできます。例:gist.github.com/westonruter/7141599
Weston Ruter

回答:


5

アプローチ

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

  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アクションを使用してスクリプトを追加します。


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


素晴らしい!私は言葉に困っています。これは魅力のように機能し、私のケースを完全に解決します。完全に機能する例を期待していなかったでしょう、本当にありがとう!
glueckpress 2017

1
良い質問(明確な説明、スクリーンショット、努力の証明)は完全な回答に値します。このコメントは、質問に対する適切な回答を得るためのヒントとして他の人に残します。;)
クラフトナー2017
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.