按分类和元值对帖子进行排序

时间:2014-03-07 作者:Chris

有可能order posts by Meta Value.

有可能order posts by more than one value.

由于下面的代码,可以按分类法排序。

但是我如何才能将下面的代码更改为order bytaxonomy AND meta_value?

Added to functions.php

function orderby_tax_clauses( $clauses, $wp_query ) {
global $wpdb;
$taxonomies = get_taxonomies();
foreach ($taxonomies as $taxonomy) {
    if ( isset( $wp_query->query[\'orderby\'] ) && $taxonomy == $wp_query->query[\'orderby\']     ) {
            $clauses[\'join\'] .=<<<SQL
LEFT OUTER JOIN {$wpdb->term_relationships} ON {$wpdb->posts}.ID={$wpdb-    >term_relationships}.object_id
LEFT OUTER JOIN {$wpdb->term_taxonomy} USING (term_taxonomy_id)
LEFT OUTER JOIN {$wpdb->terms} USING (term_id)
SQL;
            $clauses[\'where\'] .= " AND (taxonomy = \'{$taxonomy}\' OR taxonomy IS NULL)";
            $clauses[\'groupby\'] = "object_id";
            $clauses[\'orderby\'] = "GROUP_CONCAT({$wpdb->terms}.name ORDER BY name ASC) ";
            $clauses[\'orderby\'] .= ( \'ASC\' == strtoupper( $wp_query->get(\'order\') ) ) ?     \'ASC\' : \'DESC\';
        }
    }
    return $clauses;
}

    add_filter(\'posts_clauses\', \'orderby_tax_clauses\', 10, 2 );

Added to index.php

<?php $args = array(
\'post_type\' => \'custom_post_type\',
\'posts_per_page\' => -1,
\'meta_key\' => \'_EventStartDate\',
\'orderby\' => \'taxonomy_cat\',
\'order\' => asc
);
$the_query = new WP_Query( $args );

if ( $the_query->have_posts() ) : while ( $the_query->have_posts() ) : $the_query-    >the_post(); ?>

etc. etc.

Changing this doesn\'t work

\'orderby\' => \'taxonomy_cat meta_value\',

1 个回复
最合适的回答,由SO网友:gmazzap 整理而成

在您的代码中

if ( isset( $wp_query->query[\'orderby\'] ) && $taxonomy == $wp_query->query[\'orderby\'] 
这使得您的代码无法处理多个订单字段,因为如果

\'orderby\' => \'taxonomy_cat meta_value\'
那么$taxonomy == $wp_query->query[\'orderby\'] 从来都不是真的。

此外,我发现循环所有分类法只是为了找到排序依据的分类法,性能很低,而且不太可靠。

因此,我对您的代码进行了一些编辑:当您想要为分类法排序时,您的arg应该如下所示:

\'orderby\' => \'taxonomy.taxonomy_cat\'
感谢\'taxonomy.\' 易于识别分类法,无需遍历所有分类法。

之后,WordPress只允许传递一个参数作为\'order\' 参数,所以当您传递多个\'orderby\' 参数,则结果可能不是预期的结果。

因此,我编辑了您的代码以接受另一个参数:\'ordertax\'. 确保这是可选的,因此如果不传递它,将使用“order”参数。如果\'orderby\' 不包含任何分类参数。如果使用多个\'orderby\' 未通过的arguemnts\'ordertax\', 所有参数都是基于顺序的\'order\' 参数(或默认值“DESC”),因此使用

\'orderby\' => \'taxonomy.taxonomy_cat meta_value\',
\'order\' => \'ASC\'
"ORDERBY taxonomy_cat ASC, meta_value ASC", 使用

\'orderby\' => \'taxonomy.taxonomy_cat meta_value\',
\'ordertax\' => \'DESC\'
\'order\' => \'ASC\'
"ORDERBY taxonomy_cat DESC, meta_value ASC".

下面是代码:

function orderby_tax_clauses( $clauses, $wp_query ) {
  $orderby_arg = $wp_query->get(\'orderby\');
  if ( ! empty( $orderby_arg ) && substr_count( $orderby_arg, \'taxonomy.\' ) ) {
    global $wpdb;
    $bytax = "GROUP_CONCAT({$wpdb->terms}.name ORDER BY name ASC)";
    $array = explode( \' \', $orderby_arg ); 
    if ( ! isset( $array[1] ) ) {
      $array = array( $bytax, "{$wpdb->posts}.post_date" );
      $taxonomy = str_replace( \'taxonomy.\', \'\', $orderby_arg );
    } else {
      foreach ( $array as $i => $t ) {
        if ( substr_count( $t, \'taxonomy.\' ) )  {
          $taxonomy = str_replace( \'taxonomy.\', \'\', $t );
          $array[$i] = $bytax;
        } elseif ( $t === \'meta_value\' || $t === \'meta_value_num\' ) {
          $cast = ( $t === \'meta_value_num\' ) ? \'SIGNED\' : \'CHAR\';
          $array[$i] = "CAST( {$wpdb->postmeta}.meta_value AS {$cast} )";
        } else {
          $array[$i] = "{$wpdb->posts}.{$t}";
        }
      }
    }
    $order = strtoupper( $wp_query->get(\'order\') ) === \'ASC\' ? \' ASC\' : \' DESC\';
    $ot = strtoupper( $wp_query->get(\'ordertax\') );
    $ordertax = $ot === \'DESC\' || $ot === \'ASC\' ? " $ot" : " $order";
    $clauses[\'orderby\'] = implode(\', \',
      array_map( function($a) use ( $ordertax, $order ) {
        return ( strpos($a, \'GROUP_CONCAT\') === 0 ) ? $a . $ordertax : $a . $order;
      }, $array )
    );
    $clauses[\'join\'] .= " LEFT OUTER JOIN {$wpdb->term_relationships} ";
    $clauses[\'join\'] .= "ON {$wpdb->posts}.ID = {$wpdb->term_relationships}.object_id";
    $clauses[\'join\'] .= " LEFT OUTER JOIN {$wpdb->term_taxonomy} ";
    $clauses[\'join\'] .= "USING (term_taxonomy_id)";
    $clauses[\'join\'] .= " LEFT OUTER JOIN {$wpdb->terms} USING (term_id)";
    $clauses[\'groupby\'] = "object_id";
    $clauses[\'where\'] .= " AND (taxonomy = \'{$taxonomy}\' OR taxonomy IS NULL)";
  }
  return $clauses;
}
使用方法如下:

$args = array(
  \'post_type\'      => \'custom_post_type\',
  \'posts_per_page\' => -1,
  \'meta_key\'       => \'_EventStartDate\',
  \'orderby\'        => \'taxonomy.taxonomy_cat meta_value\',
  \'ordertax\'       => \'ASC\',
  \'order\'          => \'DESC\'
);

add_filter( \'posts_clauses\', \'orderby_tax_clauses\', 10, 2 );
$the_query = new WP_Query( $args );
remove_filter( \'posts_clauses\', \'orderby_tax_clauses\', 10, 2 );
请注意,将我的代码(就像您的代码一样)与包含分类查询的WP\\U查询一起使用可能会破坏某些东西。。。因此,重要的是在使用滤清器后将其拆下。

结束