web-dev-qa-db-ja.com

異なるカテゴリ内の異なる投稿ソート順

私は each post/ unique postオーダーを複数のカテゴリーに対して与える必要があります。それぞれのカテゴリーに対応するカスタムがあるカスタムフィールドを使った解決策を想像できます。注文のためのフィールド。

例えば。

カテゴリ:プレイリスト1プレイリスト2プレイリスト3

投稿のカスタムフィールド:Playlist1_Order Playlist2_Order Playlist3_Order

この方法は明らかに簡単には拡張できませんが、誰かがもっとエレガントな解決策を持っているかどうかを知りたいのですが。

バックグラウンド

私は24時間365日の放送を伴うようにサイトを設定しています。ブロードキャストのプレイリストは12時間のループで、週に1回修正されます。 いくつかのショーが追加されて削除され、いくつかのショーの順序が並べ替えられています。 私はショーのカスタム投稿タイプとプレイリストのカスタム分類法を定義するつもりです。 各番組は1つ以上のプレイリストに追加されます。ショーが各プレイリストで一意の順序を持​​つことが可能である必要があります。

(混乱を避けるため、質問は投稿タイプと分類法ではなく投稿とカテゴリに限定することにしました)。

更新

明確にするために、この例を検討してください。 「Rod's Radio Roundup」という記事があります。カテゴリは「Tuesday Lineup」と「Wednesday Lineup」です。火曜日は3回目のショー、水曜日は7回目のショーです。その後、水曜日に出発しますが、木曜日は1番目のスロット、土曜日は5番目のスロットに移動します。そして、このような他の40の投稿があります。

最も重要な質問:あなたはどのようにして単一の投稿に対して、カテゴリごとに複数の注文を管理しますか?

6
user6756

私は最近、この同じ課題を克服しました。私たちは複数のカテゴリの各投稿に対して異なるソート順を保存する方法が必要でした。

Wp_term_relationshipsテーブルに未使用の列term_orderがあります。これはデフォルトの0で、すでに整数としてキャストされています。

用語が投稿に割り当てられると、割り当てられた用語ごとにこのテーブルのエントリが取得されます。 object_ID(post_ID)、term_taxonomy_ID、およびterm orderは0に設定されています。

課題

  1. Term_taxonomy_IDはterm_IDとは異なる場合があるので、各カテゴリのterm_taxonomy_IDを知っておく必要があります。

  2. デフォルトは常に0なので、これをより大きな数に設定する方法が必要です。そうしないと、すべての新しい投稿が常に最初になります。

    • 簡単な方法は、データベースのデフォルトをより大きな数値に変更することです。もう1つの方法は、関数を作成してそれをsave_post、update_post、またはdraft_to_publishフックにアタッチすることです。
  3. term_orderはWP_Queryクラスの一部ではないため、これらの投稿をクエリする方法も必要になります。

    • Posts_whereフィルターを使用するか、カスタム照会関数を作成してください。
  4. これらの投稿を並べ替える方法も必要になります。私が使用したAjaxドラッグアンドドロップ方法の概要を説明しますが、メタボックスまたはカスタムフィールドを使用することもできます。

Ajaxのドラッグ&ドロップソート

管理者用オプションページを作成して投稿をクエリし、それらをカスタムテーブルまたは番号なしリストに出力する必要があります。 Ajaxを使用してこれを実行することもできます。ユーザーは選択ボックスからカテゴリを選択し、そのカテゴリから投稿を読み込むだけで済みます。 (私は注文を保存するためにAjaxとPhp関数を提供するだけです)。

PHPのwp_ajax関数:

add_action ( 'wp_ajax_item_sort', 'wnd_save_item_order' );
    function wnd_save_item_order () {
        global $wpdb;
        $wpdb->flush ();
        $posts = $_POST[ 'order' ];
        $str = str_replace ( "post-", "", $posts );
        $order = explode ( ',', $str );
        $cat_id = (int)$_POST[ 'cat' ];
        $counter = 1;
        foreach ( $order as $item_id ) {

            $wpdb->query ( "UPDATE $wpdb->term_relationships SET term_order = '$counter' WHERE object_id = '$item_id' AND term_taxonomy_id = '$cat_id'" );
            $counter++;
        }
         $response = '<div id="message" class="updated fade"> <p>Sort Order successfully updated</p></div>';
         echo $response;
         die( '<div id="message" class="updated fade"> <p>An error occured, order has not been saved.</p></div>' );
    }

JQueryのAjax:

// Add this to the admin_enque_scripts and do a $pagenow check.
function sort_order_js() { ?> 
  jQuery(document).ready(function($) {
     var catID = $("#cat-select option:selected").val()
      $("#" + catID + "-save-order").bind("click", function() {
      $("#" + catID + "-load-animation").show();

          $.post(ajaxurl, { action:'item_sort', cat: catID, pos: position, order: $("#" + catID + "-sortable").sortable('toArray').toString() },

          function(response) {
              $("#" + catID + "-update-response").text('Updated');
              $("#" + "-load-animation").hide();
               });
                return false;
            });

            <?php } ?>

新しく注文した投稿をどのように入手できますか?

posts_orderbyフィルタ:

add_filter('posts_orderby', 'custom_posts_orderby');
function custom_posts_orderby($order) {
    $order_by = 'wp_term_relationships.term_order';
    $direction = 'DESC';
    $order = " ORDER BY $order_by $direction";
    return $order;
}

カスタムクエリAPI

WP_Queryに似た引数の配列を渡してこの関数を実行すると、post_idsの配列が返されます。

function custom_get_post_ids( $args ) {
        $defaults = array (
            'category_id'               => NULL,
            'exclude_array'             => array (),
            'post_status_array'         => array ( 'publish' ),
            'post_status'               => NULL,
            'post_type_array'           => array ( 'post' ),
            'post_type'                 => NULL,
            'offset'                    => 0,
            'length'                    => 7,
            'order_by'                  => 'wp_term_relationships.term_order',
            'order_direction'           => 'ASC',
            'secondary_order_by'        => 'post_date',
            'secondary_order_direction' => 'DESC',
        );

    $args = wp_parse_args( $args, $defaults );
    extract( $args, EXTR_SKIP );
    if ( isset( $post_type ) ) {
        $post_type_array = array ( $post_type );
    }
    // If the post_status passed to us is a string, convert it to an array
    if ( isset( $post_status ) ) {
        $post_status_array = array ( $post_status );
    }
    global $wpdb;
    $query = 'SELECT wp_posts.ID FROM wp_posts INNER JOIN wp_term_relationships ON (wp_posts.ID = wp_term_relationships.object_id)';
    $query .= ' WHERE wp_term_relationships.term_taxonomy_id IN (' . intval( $category_id ) . ')';
    if ( count( $exclude_array ) > 0 ) {
        $exclude = implode( ',', $exclude_array );
        $query .= ' AND wp_posts.ID NOT IN (' . $exclude . ')';
    }
    $query .= " AND wp_posts.post_type IN('" . implode( "','", $post_type_array ) . "')";
    $query .= " AND wp_posts.post_status IN('" . implode( "','", $post_status_array ) . "')";
        $query .= " ORDER BY $order_by $order_direction";
    if ( ! empty( $secondary_order_by ) ) {
        $query .= ",$secondary_order_by $secondary_order_direction";
    }
    $query .= " LIMIT $offset, $length /*_get_post_ids() */";
    $num_results = $wpdb->query( $query );
    $res = array ();
    foreach ( $wpdb->last_result as $r ) {
        array_Push( $res, intval( $r->ID ) );
    }
    return ( $res );
    }

最後に、注文する通常の投稿数よりもterm_taxonomy_idを大きくするように、新しい投稿を設定するだけです。

function default_sort_order() {
    global $post, $wpdb;
    $categories = get_the_category( $post->ID);
    $id = $post->ID;
        foreach ( $categories as $cat ) {
            $cat_id = $cat->term_taxonomy_id;
            $wpdb->query ( "UPDATE $wpdb->term_relationships SET term_order = 20 WHERE object_id = '$id' AND term_taxonomy_id = '$cat_id'" );

        }
}

まだここ?

この方法はテストされており、大規模な報道機関ではホームページやカテゴリページの表示順序を設定するために使用されています。

4
Chris_O

このようなことは非常に速く複雑になります。WPを使用してライブブロードキャストを整理することは素晴らしいアイデアではないため(広告挿入、ローテーションルール、オンザフライでのライブ変更など)そのようなもののほとんどは、それらのニーズに基づいた特定のAPIを備え、必要に応じてデータをスローするためのXML/JSONフィード(WPなど)を備えたアプリケーションによって適切に処理されます。

注文の問題
この一般的な順序付けとドラッグアンドドロップの順序付けの問題は、過去に提起された問題点のようです。ほとんどのコアチームは、WordPressが時系列であることに同意します。それ以外は開発者向けのプラグイン機能である必要があります。問題は、開発プラットフォームとしてWordPressを使用している人々のlotがあることです。これに遭遇すると、WordPressはCMSになります;)

それで、それは私たちに何を残しますか?

ドラッグアンドドロップは本当に直感的であるため、jQuery UIの.sortable();のようなものをカスタムdbエントリまたはメタフィールドとともに使用するとうまく機能します。デフォルトの投稿ギャラリーエディター(およびメニューエディター)とほぼ同じことができます。ドロップオーダーをドラッグして、手動で数値と並べ替えパラメーター(ASC、DESC)を入力するオプションがあります。名前または任意のWP Query/WPDBパラメーターを含めるように拡張できます。

もっと複雑なものは、手元の実際の要件にかなり特有な何らかのクエリルールシステムに基づいている必要があります。

PostMashOrderly など、これを行うプラグインがいくつかありますが、私が知っているものは本当に包括的なものではないため、多くのテンプレートファイルをハッキングする必要があります。

1
Wyck

私はあなたが「投稿とカテゴリ」を言ったことを知っています、しかし私はあなたが投稿を投稿に結びつけて、そして投稿メタデータとして注文を保存することがあなたがよりうまくいくと思う:

  • 新しい投稿タイプshowを作成します(ただし、代わりにpostを使用できます)。

  • 新しい投稿タイプplaylistを作成します(ただし、代わりにpostを使用できます)。

  • 投稿/再生リストTuesday Lineupを作成し、投稿メタデータshows = 8,73,5,68,994(ショーIDの番号付きリスト)を保存します。 ( ACFリレーションシップフィールド great UIが追加されていますが、それ以外の原則は同じです。)

  • 各投稿/プレイリストを表示するときは、showsの値を読み、それらの投稿を取得し、順番に表示します。

1
sam

これをEXTREME擬似コードで実行するには、次のようにします。

switch($cat_id) {
    case 1:
        $args = "sort rules for cat 1";
        break;
    case 2:
        $args= "sort rules for cat 2";
        break;
    etc...
    default:
        $args= "default sort rules";
        break;
}

$posts = get_posts($args);

注:このメソッドでは、case句を使用して "exceptions"を定義し、defaultを使用して "rule"を定義してください。

0
Joshua

簡単です。 PHP および WordPress get_posts() の場合、いくつかチェックするだけでうまくいきます。

$args['orderby']$args['order']を変更して、ソートに必要な方法をソートすることができます。表示 注文と注文パラメータ

テストしていませんが、うまくいくはずです。

function get_content($type, $categories){
    for($i = 0; $i < count($categories); $i++){
        // configure posts
        $args = array(
            'numberposts'     => -1,
            'offset'          => 0,
            'category_name'   => $categories[$i],
            'include'         => '',
            'exclude'         => '',
            'meta_key'        => '',
            'meta_value'      => '',
            'post_type'       => $type,
            'post_mime_type'  => '',
            'post_parent'     => '',
            'post_status'     => 'publish' 
        );
        // define different sorting methods depending on category
        if($categories[$i] == 'playlist-1'){
            $args['orderby'] = 'post_date';
            $args['order'] = 'DESC';
        } elseif($categories[$i] == 'playlist-2'){
            $args['orderby'] = 'post_date';
            $args['order'] = 'ASC';
        } elseif($categories[$i] == 'playlist-3'){
            $args['orderby'] = 'post_title';
            $args['order'] = 'ASC';
        } 
        // fetch the posts
        $postData[$categories[$i]] = get_posts($args);
    }
    return $postData;
}

// Choose the categories to sort
$categories = array('playlist-1', 'playlist-2', 'playlist-3');

// This will contain all categories and posts inside one array.
$allPosts = get_content('post', $categories);
//print_r($allPosts);

// EXAMPLE: To loop through a set of posts, you will need to access it like so
for($i = 0; $i < count($categories['playlist-1']); $i++){
    echo '<h1>'.$categories['playlist-1'][$i]['post_title'].'</h1>';
    echo apply_filter('the_content', $categories['playlist-1'][$i]['post_content']);
}

OR

分類のソート順でポスターを入手する

    function get_content_taxonomy($tax, $term){
        $wp_query = new WP_Query();
        $wp_query->query(array('posts_per_page' => -1, 'orderby' => 'title', 'order' => 'ASC', 'tax_query' => array(array('taxonomy' => $tax, 'field' => 'slug', 'terms' => $term))));
        $posts = $wp_query->posts;
        if(!empty($posts)){
            $return = $posts;
        }
        return $return;
    }

    // No idea how you have your stuff setup, but it could be like:
    $playlist1 = get_content_taxonomy('playlist', '1');
    // print_r($playlist1);
0
Michael Ecklund