it-swarm.com.de

Fragen Sie nach, ob eine Liste zuerst nach Metaschlüssel sortiert werden soll (sofern vorhanden), und zeigen Sie die verbleibenden Beiträge ohne Metaschlüssel nach Titel sortiert an

Ich arbeite an einer benutzerdefinierten Taxonomiebegriffseitenvorlage, in der die mit dem Begriff verbundenen Elemente nach Veröffentlichungsdatum sortiert werden sollen (benutzerdefiniertes Datumsfeld) - und wenn mehrere Elemente am selben Tag vorhanden sind (Formatierung wie JJJJ-MM- DD), um diese nach Titel und schließlich nach Titel zu sortieren, wenn das benutzerdefinierte Feld nicht ausgefüllt wurde (ältere Elemente).

Also habe ich es auf hundert verschiedene Arten mit einer WP_query versucht und es gibt die meisten Ergebnisse so zurück, wie ich sie haben möchte - aber in diesem Fall gibt es nur die Elemente zurück, die den meta_key von publication_date haben. Alle anderen Elemente werden ignoriert und nicht angezeigt. Ich habe eine meta_query mit der Relation "oder" ausprobiert und das publication_date als EXISTS und NOT EXISTS verglichen, aber das ergab 0 Ergebnisse für mich.

Außerdem wird auf der Site noch 3.5.2 ausgeführt, und sie möchten kein Upgrade durchführen.

Hier ist meine letzte Abfrage, mit der ich die Posts erhalte, bei denen das benutzerdefinierte Feld publication_date in der richtigen Reihenfolge angezeigt wird:

$term = get_queried_object(); // find the term of the taxonomy page we are on
$wp_query = new WP_Query( array(
'post_type' => 'resource',
'tax_query' => array(
    array(
        'taxonomy' => 'resource_types',
        'field' => 'slug',
        'terms' => $term->name,
    )), 

'meta_key' => 'publication_date',
'orderby' => 'meta_value_num',
'order' => 'DESC',
'paged' => $paged,
'posts_per_page' => '10',
));

Ich habe auch versucht, wpdb zu verwenden und eine SQL-Abfrage auszuführen, bin mir aber nicht sicher, wie ich das erreichen soll. Wenn mir jemand helfen könnte, wäre das großartig!

Danke im Voraus.

19
CSSgirl

Vielen Dank für Ihre Hilfe!

Am Ende brachte mir die folgende Abfrage die gewünschten Ergebnisse - die Beiträge sollten zuerst in einem benutzerdefinierten Feld von "publication_date" angezeigt und sortiert werden - sortiert nach dem Datum und wenn es mehrere vom selben Datum gab (z. B. 4 markiert) Juni 2013), würde es diese nach Titel sortieren. Nachdem alle Posts mit ausgefülltem Veröffentlichungsdatum durchlaufen wurden, werden die verbleibenden Posts in alphabetischer Reihenfolge nach Titel durchlaufen.

Dadurch erhalte ich die in derselben Abfrage festgelegten Ergebnisse und behalte meine Paginierung bei:

$term = get_queried_object();
the_post();
$wp_query = new WP_Query( array(
'post_type' => 'resource',
    'tax_query' => array(
        array(
            'taxonomy' => 'resource_types',
            'field' => 'slug',
            'terms' => $term->name,
        )),
 'meta_query' => array(
       'relation' => 'OR',
        array( //check to see if date has been filled out
                'key' => 'publication_date',
                'compare' => '=',
                'value' => date('Y-m-d')
            ),
          array( //if no date has been added show these posts too
                'key' => 'publication_date',
                'value' => date('Y-m-d'),
                'compare' => 'NOT EXISTS'
            )
        ),
'meta_key' => 'publication_date',
'orderby' => 'meta_value title',
'order' => 'ASC',
'paged' => $paged,
'posts_per_page' => '10',
));
17
CSSgirl

Einige Jahre später funktionierte der von CSSGirl gepostete Code nicht für mich, da es einige Posts gab, bei denen der Metaschlüssel nicht vorhanden war oder der Metaschlüssel leer war. Daher musste ich dies tun, um alle Posts nach Datum zu ordnen und zeigen Sie zuerst diejenigen mit einer Metaschlüsselwertanzeige an:

$args          = array(
'post_type'   => $type,
'post_status' => 'publish',
'nopaging'    => TRUE,
'meta_query'  => array(
    'relation' => 'OR',
    array(
        'key'     => $meta_key,
        'compare' => 'NOT EXISTS',
    ),
    array(
        'relation' => 'OR',
        array(
            'key'   => $meta_key,
            'value' => 'on',
        ),
        array(
            'key'     => $meta_key,
            'value'   => 'on',
            'compare' => '!=',
        ),
    ),
),
'orderby'     => array( 'meta_value' => 'DESC', 'date' => 'DESC' ),
);
6
Ciprian Tepes

Ich denke, Sie müssten 2 separate Loops machen. Sie können alle in der ersten Schleife gefundenen Beiträge erfassen und sie einfach genug aus der sekundären Schleife ausschließen:

$found_posts = array();
while($loop->have_posts()): $loop->the_post();
    // loop stuff
    $found_posts[] = get_the_id();
endwhile;

wp_reset_query();

$args = array(
    // other args
    'post__not_in' => $found_posts,
);

Führen Sie dann Ihre zweite Schleife aus.

1
GhostToast

Gibt es einen Grund, warum Sie den Metaschlüssel publication_date nicht für jeden Beitrag nur mit einem leeren Wert erzwingen können?

In Ihrer save_post -Aktion würden Sie also den Metaschlüssel hinzufügen/aktualisieren, unabhängig davon, ob der $_POST -Wert leer ist oder nicht.

Sie müssten ein Update-Skript ausführen, um Ihre älteren Beiträge zu durchlaufen und den Schlüssel mit einem leeren Wert hinzuzufügen. Beispiel:

add_action( 'admin_init', 'update_old_posts' );
function update_old_posts() {
    if ( ! isset( $_GET[ 'update_old_posts' ] ) )
         return;

    foreach( get_posts() as $post ) {
        if ( false === get_post_meta( $post->ID, 'publication_date', true ) ) {
             update_post_meta( $post->ID, 'publication_date', '' );
             echo "Updated {$post->post_title} <br />";
        }
    }

    die;
}

Führen Sie es aus, indem Sie zu http://example.com/wp-admin/?update_old_posts navigieren.

Dann können Sie die gleiche Abfrage verwenden, die Sie haben. Wenn Sie einen zusätzlichen Filter hinzufügen möchten, damit Sie nach verschiedenen Spalten in verschiedene Richtungen sortieren können, ist es für mich sinnvoll, nach Datum in absteigender Reihenfolge und nach Titel in aufsteigender Reihenfolge zu sortieren.

add_filter( 'posts_orderby', 'multicolumn_orderby', 10, 2 );
function multicolumn_orderby( $orderby, $query ) {
    global $wpdb;

    // check it's the right query
    if ( $query->get( 'meta_key' ) == 'publication_date' ) {
         $orderby = "$wpdb->postmeta.meta_value+0 DESC, $wpdb->posts.post_title ASC";
    }

    return $orderby;
}
0
sanchothefat

Ich habe eine benutzerdefinierte where-Klausel erstellt. Ich habe es mit $wp_query->request direkt vor meiner Hauptschleife getestet. Ich kenne SQL nicht so gut, aber das schien die Dinge zum Laufen zu bringen.

add_action('pre_get_posts', 'add_trending_sort', 11, 1);
function add_trending_sort($query){
  if(!$query->is_main_query())
    return;

  //Overwrite query arguments
  $query->set('meta_query', array(
    array(
      'key' => 'TRENDING',
      //'value' => 'asdfasdf',//may need a value for older versions of WordPress
      'compare' => 'NOT EXISTS',
    )
  ));
  $query->set('orderby', 'meta_value_num date');
  $query->set('order', 'DESC');
}

add_filter('posts_where', 'add_trending_where');
function add_trending_where($where = ''){
  global $wpdb, $wp_query;
  if(!$wp_query->is_main_query())//Not sure if this really works.  Should be OK
    return $where;

  $where .= " OR ( $wpdb->postmeta.meta_key = 'TRENDING' )";

  // Don't run this twice
  remove_filter('posts_where', 'add_trending_where');

  return $where;
}

Alternativ können Sie compare auf 'EXISTS' setzen und die Zeile in add_trending_where in $where .= " OR ($wpdb->postmeta.post_id IS NULL)"; ändern. Dann müssten Sie nur den Wert des Schlüssels an einer Stelle ändern. Echo $wp_query->request und spiele herum, wenn du das besser verstehen oder optimieren willst.

BEARBEITEN: Mir ist gerade aufgefallen, dass dies nicht funktioniert, wenn für die Abfrage meta_key eingestellt ist. Sie könnten $query->set('meta_key', NULL); verwenden, wenn Sie müssen.

EDIT 2: Ich habe dies mit der obigen Methode funktioniert. Aus irgendeinem Grund war es zuerst nicht (vielleicht wurde meta_key gesetzt ... ich weiß es nicht).

add_action('pre_get_posts', 'add_trending_sort', 11, 1);
function add_trending_sort($query){
  // Bail if not the main "hidden" query, as opposed to a 'new WP_Query()' call
  if(!$query->is_main_query())
    return;

  // Set meta_query to get shares for orderby, and also get non-shared content.
  $query->set('meta_query', array(
    'relation' => 'OR',
    array(
      'key' => 'TRENDING',
      'compare' => 'NOT EXISTS',
    ),
    array(
      'key' => 'TRENDING',
      'compare' => 'EXISTS',
    )
  ));
  //$query->set('meta_key', NULL);
  $query->set('orderby', array('meta_value_num' => 'DESC', 'date' => 'DESC'));
}
0
Ryan Taylor