Ordonarea Postărilor după Taxonomie și Valoare Meta

7 mar. 2014, 17:50:18
Vizualizări: 13.6K
Voturi: 3

Este posibil să ordonezi postările după Valoare Meta.

Este posibil să ordonezi postările după mai multe valori.

Și datorită codului de mai jos, este posibil să ordonezi după taxonomie.

Dar cum pot modifica codul de mai jos pentru a ordona atât după taxonomie, cât și după meta_value?

Adăugat în 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 );

Adăugat în 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.

Modificarea acestui lucru nu funcționează

'orderby' => 'taxonomy_cat meta_value',
0
Toate răspunsurile la întrebare 1
0

În codul tău, există

if ( isset( $wp_query->query['orderby'] ) && $taxonomy == $wp_query->query['orderby'] 

care face ca codul tău să nu funcționeze cu mai multe câmpuri de ordonare, deoarece dacă setezi

'orderby' => 'taxonomy_cat meta_value'

atunci $taxonomy == $wp_query->query['orderby'] nu este niciodată adevărat.

În plus, consider că parcurgerea tuturor taxonomiilor doar cu scopul de a găsi taxonomia după care să ordonezi este ineficientă și nu foarte sigură.

Așadar, am editat puțin codul tău: când vrei să ordonezi după o taxonomie, argumentul tău ar trebui să fie ceva de genul:

'orderby' => 'taxonomy.taxonomy_cat'

datorită 'taxonomy.' este ușor să recunoști taxonomia și nu este nevoie să parcurgi toate taxonomiile.

Pe de altă parte, WordPress permite să treci doar un singur argument ca 'order', așa că atunci când treci mai multe argumente 'orderby', rezultatul poate să nu fie cel așteptat.

De aceea, am editat codul tău pentru a accepta un argument suplimentar: 'ordertax'. Desigur, acesta este opțional, deci dacă nu îl treci, se va folosi argumentul 'order'. De asemenea, este ignorat dacă 'orderby' nu conține niciun argument de taxonomie. Dacă folosești mai multe argumente 'orderby' fără a trece 'ordertax', toate argumentele vor fi ordonate în funcție de argumentul 'order' (sau implicit 'DESC'), deci folosind

'orderby' => 'taxonomy.taxonomy_cat meta_value',
'order' => 'ASC'

înseamnă "ORDERBY taxonomy_cat ASC, meta_value ASC", iar folosind

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

înseamnă "ORDERBY taxonomy_cat DESC, meta_value ASC".

Acum, iată codul:

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

Folosește-l astfel:

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

Reține că folosirea codului meu (la fel ca și a tău) cu un WP_Query care conține o interogare de taxonomie poate cauza probleme... din acest motiv este important să elimini filtrul după ce l-ai folosit.

7 mar. 2014 23:51:32