web-dev-qa-db-ja.com

adminで子ページを並べ替える

次のような構造の階層型CPTがあります。

- parent item 1
   - child item 1
   - child item 2
   - child item 3
   - child item 4
   - child item 5
- parent item 2
   - child item 1
   - child item 2
   - child item 3
   - child item 4
   - child item 5

各子項目は数値であり、親内の順序に対応する "section_id"というメタキーを持ちます。日付印は互いに約5分離れています。

達成したいのは、各親項目を日付の降順で並べ替えることです。子項目は日付の昇順またはメタsection_idのいずれかで並べ替えます(どちらも同じ結果になるため、うまくいきます)。

pre_get_postsまたはparse_queryを実行すると、どちらか一方を実行できますが、両方を実行することはできません。それは可能ですか?

note これはadmin postテーブルのためだけのもので、フロントエンドのためのものではありません。

6
Norcross

私はWP_Posts_List_Tableクラスをオーバーライドするためのフィルタを見つけることができなかったので、私はこれをすることによってかなりハックな解決策を提案します:

  1. pre_get_posts内の親のみをクエリします。
  2. wpで子供たちに問い合わせて、それに応じて$wp_query->postsを変更してください。

私はおそらく改ページ番号を壊しているので、これにはもう少し作業が必要かもしれません。

// Use a query variable to control when to change the main admin query
add_filter( 'query_vars', 'custom_admin_list_query_vars', 10, 1 );
function custom_admin_list_query_vars( $vars ) {
    array_Push( $vars, 'custom_admin_list_children' );
    return $vars;
}

add_action( 'pre_get_posts', 'custom_admin_pre_get_posts' );
function custom_admin_pre_get_posts( $query ) {

    global $post_type;

    // Change query only if it's a user-triggered query in admin
    if ( ! is_admin()
        || 'page' != $post_type
        || $query->get( 'custom_admin_list_children' ) )
        return false;

    // Query only parents in date order
    $query->set( 'post_parent', 0 );
    $query->set( 'orderby', 'post_date' );
    $query->set( 'order', 'desc' );

}

// Query the children of the parents above
add_action( 'wp', 'custom_admin_list_wp' );
function custom_admin_list_wp() {

    global $post_type, $wp_query;

    if ( ! is_admin() || 'page' != $post_type )
        return false;

    $args = array(
        'post_type' => 'page',
        'numberposts' => -1,
        'custom_admin_list_children' => true,
        'meta_key' => 'section_id',
        'orderby' => 'meta_value_num',
        'order' => 'asc'
    );

    // Get children
    $children = array();
    for( $i = 0; $i < count( $wp_query->posts ); $i++ ) {
        $args['post_parent'] = $wp_query->posts[ $i ]->ID;
        $children[ $i ] = get_posts( $args );
    }

    // Flag as a children with a '--' in front of the title
    foreach( $children as &$c ) {
        if ( !empty( $c->post_title ) )
            $c->post_title = '&mdash;&nbsp;' . $c->post_title;
    }

    // Put everything together
    $posts = array();
    for( $i = 0; $i < count( $wp_query->posts ); $i++ ) {
        $posts[] = $wp_query->posts[ $i ];
        $posts = array_merge( $posts, $children[ $i ] );
    }

    $wp_query->posts = $posts;
    $wp_query->post_count = count( $posts );

}
1
vmassuchetto

階層的な投稿を並べ替える場合は、 "order"フィールドを使用します。これはあなたが好きなようにあなたが子供の投稿の順序を並べ替えることを可能にするでしょう。 1,2,3の代わりに... 10,20,30を使用することをお勧めします...将来の変更のためのスペースを残して。

Wordpressがそのタスクを無痛にするためにドラッグアンドドロップインターフェースを提供すれば、もちろんいいでしょう、しかし私が見ることができる限りでは、それはありません(あるいはおそらくプラグインがあります)。

これはまさにあなたが要求したもの(1つのリストで2種類のソートを行う能力)ではありませんが、うまくいけばそれはあなたの最終目標を達成します。

0
Eugenious