web-dev-qa-db-ja.com

特定の登録済みサイドバーにウィジェットを制限する

私はsingle.phpサイドバーと一緒にしか使用できないようにしたいウィジェットを持っています。 register sidebar のコーデックスを参照したとき、配列内のウィジェットを制限する方法はありません。私は "投稿するWordPress制限ウィジェット"で研究しましたが、それらは私の検索結果で返されるプラグインにすぎません。何かを返すことができるかどうかを確認するために検索パラメータをpageに変更すると、次のようになります。

register_sidebaridに対してのみ許可されるようにWidgetをターゲットにできる方法はありますか?適切にコーディングする方法を学びたいプラグインを使用したくありません。

編集:

コメントごとに私はカスタムウィジェットを持っています。それは私のsingles.phpでは<?php get_sidebar( 'foobar' );?>と呼ばれています。誰かが管理者であるとき、私はウィジェットがどこに適用されることができるかを制限したいです:

enter image description here 

そのため、上の画像ではPost Sidebarのオプションしかないようにしたいと思います。これらすべてをsidebar-foobar.phpファイルにハードコーディングすることはできましたが、私はウィジェットをもっと活用する方法を学ぼうとしています。

私のjqueryの知識はまだほとんど存在しないので、 解決策 がコメントで@Howdy_McGeeによって示唆されているかどうかはわかりません。

とにかく、リンクからの適切な参照の問題として、

下のコードの'your_widget'をあなたのウィジェットの名前に置き換えてください(2箇所)。

'sortreceive'イベントは、ウィジェットがサイドバーに追加されたときにのみ呼び出されますが、'sortstop'は、ウィジェットをサイドバーの内側に移動したり削除したりするたびに呼び出されます。

ウィジェットが追加されたときにも'sortstop'が呼び出されますが、何らかの理由でui.inputが正しく設定されていないので、それをカバーするために 'sortreceive'を使用しました。

jQuery('div.widgets-sortables').bind('sortstop',function(event,ui){
  var id = jQuery(ui.item).attr('id');
  if (id) {
    var widget_type = id.match(/widget-[0-9]+_(.+)-[0-9]+/i)[1];
    if (widget_type == 'your_widget') {
    // do stuff;
    }
  }
})

jQuery('div.widgets-sortables').bind('sortreceive',function(event,ui){
  var id = jQuery(ui.item).attr('id');
  var widget_type = id.match(/widget-[0-9]+_(.+)-__i__/i)[1];
  if (widget_type == 'your_widget') {
    // do stuff;
  }
})

私は最近 回答 に取り組んでいます - 特定のウィジェットは特定のサイドバーからのウィジェットの配列から削除することができます。ここでは、sidebars_widgetsフィルタを使用して、サイドバーを除くすべてのサイドバーから特定のウィジェットを削除します。

つまり、サイドバーに誤って追加されたウィジェットはフロントエンドに表示されず、そのウィジェットがその特定のサイドバーに追加された唯一のウィジェットである場合はis_active_sidebar()チェックでtrueも返されません。

次のコードを試すことができます。それに応じてウィジェットとサイドバーの値を必ず変更してください。

add_filter( 'sidebars_widgets', function ( $sidebars_widgets )
{
    // Return our filter when we are on admin screen
    if ( is_admin() )
        return $sidebars_widgets;

    /**
     * Widget we need to target. This should be the name/id we used to register it
     *
     * EXAMPLE
     * parent::__construct(
            'widget_category_posts', 
            _x( 'Category Posts Widget', 'Category Posts Widget' ), 
            [ 'description' => __( 'Display a list of posts from a selected category.' ) ] 
        );
     *
     */
    $custom_widget  = 'widget_category_posts';
    // The sidebar ID we need to run the widget in
    $sidebar_accept = 'sidebar-2';

    // We have come this far, let us wrap this up
    // See if our custom content widget exists is any sidebar, if so, get the array index
    foreach ( $sidebars_widgets as $sidebars_key=>$sidebars_widget ) {
        // Skip the wp_inactive_widgets set, we do not need them
        if ( $sidebars_key == 'wp_inactive_widgets' )
        continue;

        // Only continue our operation if $sidebars_widget are not an empty array
        if ( $sidebars_widget ) {
            foreach ( $sidebars_widget as $k=>$v ) {

                /**
                 * Look for our custom widget, if found, unset it from the $sidebars_widgets array
                 * @see stripos()
                 */
                if ( stripos( $v, $custom_widget ) !== false ) {
                    // If we are on a single page and the sidebar is $sidebar_accept, do not unset
                    if ( is_single() && $sidebars_key == $sidebar_accept )
                        continue;

                    unset( $sidebars_widgets[$sidebars_key][$k] );
                }
            } // endforeach $sidebars_widget
        } // endif $sidebars_widget
    } // endforeach $sidebars_widgets

    return $sidebars_widgets;
});

結論として、これはフロントエンドに対してのみ有効なPHP回避策ですが、ウィジェットがバックエンドの特定のサイドバーにのみバインドされている適切なjqueryソリューションを探すことをお勧めします。 。私が言ったように、リンクからのjqueryソリューションはテストされておらず、本当にうまくいくかどうかはわかりません。

2
Pieter Goosen

あなたのスクリプトに加えて、私はサイドバーをドロップダウンリストから隠すスクリプトを書きました(私はこれをどこにも見つけることができませんでした)。私はこれを書くためにオリジナルのwidgets.js Wordpressコードのリバースエンジニアリングを行いました。

指定されたサイドバーだけにドラッグ&ドロップし、ドロップダウンリストをフィルタリングすることを可能にするための完全なソリューション(あなたはこれをあなたのドキュメント準備ができたjQuery管理スクリプトに入れる必要があるだけです):

function allowedSidebars(allowed)
{
    // this variable will have index of first visible sidebar
    var first = null;
    $('.widgets-chooser-sidebars li').removeClass('widgets-chooser-selected').each(function(index)
    {
        // the data('sidebarId') is set up by wordpress, let's make us of it
        if(-1 === $.inArray($(this).data('sidebarId'), allowed))
        {
            $(this).hide();
        }
        else if(first == null)
        {
            first = index;
        }
    });
    // choose first visible sidebar as default
    if(first != null)
    {
        $('.widgets-chooser-sidebars li').eq(first).addClass('widgets-chooser-selected');
    }
}
$('#available-widgets .widget .widget-title').on('click.widgets-chooser', function()
{
    var widget = $(this).closest('.widget');
    // we want to run our script only on slideDown, not slideUp
    if(!widget.hasClass('widget-in-question'))
    {
        // there is only one sidebar list per all widgets, so we have to show all the sidebars every time
        $('.widgets-chooser-sidebars li').show();
        switch(widget.find('input[name="id_base"]').val())
        {
            // your widgets here
            case 'your_widget_id':
                // allowed sidebars for widget
                allowedSidebars(['your-sidebar-id', 'your-second-sidebar-id']);
            break;
        }
    }
});
// this will make drag and drop working only for specified sidebars
$('.widget').on('dragcreate dragstart', function( event, ui ) {
    var id = $(this).find('input[name="id_base"]').val();
    // probably you may want to change it to switch
    if(id == 'your_widget_id')
    {
        $(this).draggable({
            connectToSortable: '#your-sidebar-id, #your-second-sidebar-id'
        });
    }
});
1
icetique