web-dev-qa-db-ja.com

edit-tags.php画面に "余分な"テーブルナビゲーションを追加することは可能ですか?

WP_Posts_List_Table :: extra_tablenav() apply restrict_manage_posts 任意の基準でテーブル内の投稿をフィルタリングするための追加のドロップダウン(または他のマークアップ)を出力するためにプラグインで使用できます。

同様に、WP_(Users|Comments)_List_Tableにも同様の目的でresttric_manage_(users|comment)アクションがあります。

しかし、私が言うことができる限り、 WP_Terms_List_Tablenotを行います。これは正しいです?

私はさまざまなカスタム分類法のtermmetaに大きく依存しているプラ​​グインを書いています。私のプラグインはedit-tags.php?taxonomy=my_custom_taxにカスタムカラムを追加して、それぞれの用語のさまざまなtermmetaの値を表示します。もしユーザーが私のmeta_valueとは別のmeta_keyでタームリストをフィルタリングできれば、それは私のプラグインのUXを大いに強化するでしょう。

自分のやりたいことができるようにWP_Terms_List_Table::extra_tablenav()メソッドとrestrict_manage_termsフィルタを追加することを提案するTracチケットを開く前に、WPSEの誰かが知っているかどうかを見たかったのです。

  1. 実行可能な回避策はありますか?(edit-tags.php?taxonomy=my_custom_taxのカスタムサブクラスを使用するカスタムページにリダイレクトするためにWP_Terms_List_Tableを乗っ取るようなものは含まれません)?
  2. WP_Terms_List_Tableが現在この機能をサポートしていない(良い)理由はありますか?
    1. コアには、標準のWP_Term_List_Table列でフィルターする(良い)理由はないと思いますが、カスタム列を追加することはかなり一般的であり、値でフィルターしたいのは私だけではないと思います。カスタム列内.

編集

私は、カスタム列にmeta_valueを表示するときに、その値で用語リストを効果的にフィルタリングするリンクとしてそれを出力しています。 (WP_Posts_List_Tableのように)ユーザーがドロップダウンから選択できる場合にUXが機能強化されるのは、リストテーブルに表示される特定のページに常にmeta_valueのすべての値が表示されるわけではないからです。現在のページに表示されていない値でフィルタリングするためにリンクを使用するためにIが実行するのは、ランダムなリンクをクリックしてからブラウザのアドレスフィールドに表示されるURLを編集してmeta_valueにすることです。 Iで絞り込みます。痛みがあるだけでなく、すべてのユーザーがこれを実行できることを認識するのに十分な知識があるわけではありません。

私はあなたの質問に対する同じ答えを探し回り、全く同じ問題にぶつかっています、そしてあなたの徹底的な研究に本当に感謝しています。私はこの追加を提案するために間違いなく+1ここにいます!

2)に答えることを試みるために - 私はそれを除外する十分な理由があるとは思わない。私はWordPressの分類学用語は投稿エンティティとユーザーエンティティに比べて機能がひどく欠けていると思い(投稿メタユーザーやユーザーメタの後にメタ用語がずっと後になったように見えます)、そしてその変更を見たいです。

1)に答えるために - これがあなたの解決策よりどれだけより良いであるかわかりません、しかし私が思い付いた回避策はget_terms_argsフィルターを通して分類リストをフィルターにかけ、そして手動でselectを挿入することを含みますクライアントサイドJSのドロップダウン+フィルタボタン。これは私の設定のサンプルです(私の特定のクラスや定数を使わないように修正されています)。

PHPロジック

// @see https://developer.wordpress.org/reference/hooks/get_terms_args/
add_filter( 'get_terms_args', 'taxonomy_filter', 10, 2 );

function taxonomy_filter( $args, $taxonomies ) {
    global $pagenow;
    if ( 'edit-tags.php' !== $pagenow || ! in_array( 'taxonomy-name', $taxonomies, true ) ) { return $args; }

    // Sort by most recently added terms, instead of alphabetically
    $args['orderby'] = 'term_id';
    $args['order'] = 'desc';

    // Filter by term meta
    $meta_key = ( isset( $_GET['meta_key'] ) ) ? sanitize_text_field( $_GET['meta_key'] ) : null;
    $meta_value = ( isset( $_GET['meta_value'] ) ) ? sanitize_text_field( $_GET['meta_value'] ) : null;

    if ( 'meta-filter' === $meta_key && $meta_value ) {
        $args['meta_key'] = $meta_key;
        $args['meta_value'] = $meta_value;
    }

    // Note: for more complex filtering, use the $args['meta_query'] array.

    return $args;
}

この時点で、(例えば)yoursite.com/wp-admin/edit-tags.php?taxonomy=taxonomy-name&meta_key=meta-filter&meta_value=foobarに行くだけでこれがうまくいくのを見ることができるはずです。

クライアントサイドのjQueryロジック

(このファイルを必ずwp_enqueue_script()に含めてください。ただし、$pagenow === 'edit-tags.php'の場合のみ).

/**
 * Param helpers
 */

// Get params in a JS object
var params = {};
window.location.search.substr(1).split( '&' ).forEach(function(item) {
    params[ item.split( '=' )[0] ] = item.split( '=' )[1];
});

// Return param string based on the params object
function setParams() {
    var string = '?';

    for ( key in params ) {
        var value = params[ key ];
        string += key + '=' + value + '&';
    }

    return string.slice(0, -1); // Remove trailing &
}

/**
 * Add dropdown filters + functionality to term tables
 */

if ( 'taxonomy-name' === params.taxonomy ) {
    // Create the dropdown menu & HTML
    $( document.querySelector( '.tablenav .bulkactions' ) ).after( '\
        <div class="alignleft actions"> \
            <select id="js-filter-dropdown"> \
                <option value="">Term Meta Filter</option> \
                <option value="foo">Foo</option> \
                <option value="bar">Bar</option> \
                <option value="baz">Baz</option> \
            </select> \
            <button id="js-filter" class="button" type="button">Filter</button> \
        </div> \
    ' );

    // If we're already filtering the view, have the dropdown reflect that
    var value = decodeURIComponent( params.meta_value ).replace(/\+/g, ' ');
    $( '#js-filter-dropdown' ).find( 'option[value="' + value + '"]' ).prop( 'selected', true );

    // Set up the button action - see taxonomy_filter() for server-side filtering
    $( '#js-filter' ).click(function() {
        var value = $( '#js-filter-dropdown' ).val();

        if ( value ) {
            params.meta_key = 'meta-filter';
            params.meta_value = encodeURIComponent( value );
        } else {
            delete params.meta_key;
            delete params.meta_value;
        }

        window.location.search = setParams();
    });
}

フィルタリングUIのスクリーンショット

Before 

フィルタリングされたテーブルのスクリーンショット

After image 

4
constancecchen

すぐにクラスを見直すと、テーブルの上部にドロップダウンを追加するためにbulk_actions-{$this->screen->id}フィルタをハイジャックできるように見えます。

分類法の場合:

add_filter( 'bulk_actions-edit-category', function( $actions )
{
    echo '<select name="foo" ><option value="bar">Bar</option></select>';

    return $actions;
} );

そうでなければ、インスタンス化されたWP_Terms_List_Tableクラスを拡張する簡単な方法はありません:

$wp_list_table = _get_list_table('WP_Terms_List_Table');

更新:

これは edit category スクリーンのための別の冒険ハックです。それはいくつかのテストを必要とします:-)

add_filter( 'manage_edit-category_columns', function( $columns ) use ( &$wp_list_table )
{    
    // Include the WP_Terms_List_Table class
    require_once ( ABSPATH . 'wp-admin/includes/class-wp-terms-list-table.php' );

    // Extend the WP_Terms_List_Table class
    class WPSE_Terms_List_Table extends WP_Terms_List_Table
    {
        // Override this method
        protected function extra_tablenav( $which )
        {
            echo '<select name="foo" ><option value="bar">Bar</option></select>';
        }
    } 
    // end class

    $obj = new WPSE_Terms_List_Table;
    $obj->prepare_items(); 

    // Let's clone it to the global object
    $wp_list_table = clone $obj;

    return $columns;
} );

さらに、@ winnietherpoohによって言及されているようにget_terms_argsでフィルタリングし、@ Paul 'Sparrow Hawk' Bironによって言及されているようにredirect_term_locationfilterでロケーションを調整する必要があります。

3
birgire