不同类别的帖子排序顺序不同

时间:2011-07-05 作者:user6756

我需要为每个帖子提供一个唯一的多类别(每个帖子)的帖子顺序。我可以想象一个使用自定义字段的解决方案,其中每个类别都有一个对应的订单自定义字段。

E、 g。

类别:播放列表1播放列表2播放列表3

帖子的自定义字段:playlay1\\u orderplaylay2\\u Order playlay3\\u Order

这种方法显然不容易扩展,所以我想知道是否有人有更优雅的解决方案。

背景

我正在建立一个网站,以配合全天候广播。广播的播放列表是一个每周修改一次的12小时循环。Some shows are added & removed and the order of some shows is re-arranged. 我打算定义节目的自定义帖子类型和播放列表的自定义分类。Each show will be added to one or more playlists. It must be possible for the show to have a unique order in each playlist.

(我决定将问题限制在帖子和类别,而不是帖子类型和分类,以避免混淆)。

更新要澄清,请考虑此示例。有一个帖子叫做“罗德电台综合报道”它属于“周二阵容”和“周三阵容”类别周二是第三场,周三是第七场。之后,它会在周三离开,但会在周四进入第一个位置,周六进入第五个位置。还有40个类似的帖子。

关键问题:如何维护单个帖子的多个订单,每个类别一个?

5 个回复
SO网友:Chris_O

我最近克服了同样的挑战。我们需要一种方法来为多个类别中的每个帖子保存不同的排序顺序

wp\\U term\\U relationships表中有一个未使用的列,term_order 默认值为0,已转换为整数。

当一个术语被分配给一篇文章时,它会在该表中为分配的每个术语获取一个条目。object\\u ID(post\\u ID)、term\\u taxonomy\\u ID和term order设置为0。

挑战:

  1. 术语\\u分类ID有时与术语\\u ID不同,因此您必须了解每个类别的术语\\u分类ID。

    由于默认值始终为0,您需要一种方法将其设置为更高的数字,否则您的所有新帖子都会排在第一位。

    简单的方法就是将数据库默认值更改为更高的数字。另一种方法是创建函数并将其附加到save\\u post、update\\u post或draft\\u to\\u publish挂钩term_order 不是WP\\U查询类的一部分。

    使用posts\\u where筛选或编写自定义查询函数

Ajax拖放排序:

您需要创建一个管理选项页面,查询帖子,并将其输出到自定义表或无序列表。您还可以使用Ajax来运行它,这样用户只需从选择框中选择一个类别,然后从该类别加载帖子。(我只提供Ajax和Php函数来保存订单)。

PHP wp\\U 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\\U 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;
}
可以运行此函数,向其传递一个类似于WP\\u query的参数数组,它将返回一个post\\u id数组

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\\u taxonomy\\u 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\'" );

        }
}
还在这里这种方法已经过测试,并被一家大型新闻机构用来设置主页和分类页上的显示顺序。

SO网友:Wyck

像这样的事情很快变得复杂起来,这可能就是为什么OP从未返回的原因,因为使用WP组织直播不是一个好主意(广告插入、轮换规则、实时更改等)。大多数这些东西都可以由一个应用程序更好地处理,该应用程序有一个基于这些需求的特定API,并且有XML/JSON提要,可以在需要时将数据发送给其他人(比如放入WP)。

The Order issue<一般的排序和拖放排序问题似乎是过去提出的一个痛处,大多数核心团队都同意WordPress应该保持时间顺序。其他任何东西都应该是开发人员的插件功能,问题是lot 在使用WordPress作为开发平台的人中,有人会遇到这种情况,WordPress是一种CMS,对吧;)

那么这给我们留下了什么呢?

拖放非常直观,所以使用类似jQuery UI的.sortable(); 使用自定义db条目或元字段可以很好地工作。您可以执行与默认的post gallery编辑器(和菜单编辑器)几乎相同的操作,其中您可以选择拖放顺序,还可以手动输入数字和排序参数(ASC、DESC),您可以扩展该参数以包括名称或任何WP Query/WPDB 参数

任何更复杂的东西都必须基于某种查询规则系统,该系统将非常特定于手头的实际需求。

我看到一些插件可以做到这一点,比如PostMashOrderly, 但据我所知,没有什么是真正全面的,因此需要对大量模板文件进行黑客攻击。

SO网友:sam

我知道你说的是“帖子和类别”,但我认为你会更好地将帖子连接到帖子,并将顺序存储为帖子元数据:

创建新的帖子类型,show (推荐,但您可以使用post 相反)

创建新的帖子类型,playlist (推荐,但您可以使用post 相反)

创建帖子/播放列表、星期二列表并保存帖子元数据shows = 8,73,5,68,994(显示ID的有序列表)。(TheACF Relationship Field 添加great UI,但没有它,原理是一样的。)

显示每个帖子/播放列表时,请读取shows, 获取这些帖子,并按顺序显示它们。

SO网友:Joshua

要在极端的psuedo代码中执行此操作,请尝试:

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 子句和带有default.

SO网友:Michael Ecklund

易于理解的PHP forWordPress get_posts() 几张支票就可以了。

你可以改变$args[\'orderby\']$args[\'order\'] 按您需要的方式进行排序。看法Order & Orderby Parameters

还没有测试,但应该可以!

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\']);
}

按分类排序顺序获取帖子

    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);

结束