it-swarm.com.de

Kann ich mit der Funktion pre_get_posts einen Beitrag per Metaschlüssel ausschließen?

Ich sehe, dass viele Leute pre_get_posts hook anstelle von query_posts bevorzugen. Der folgende Code funktioniert und zeigt alle Beiträge, die den Metaschlüssel "featured" haben.

function show_featured_posts ( $query ) {
    if ( $query->is_main_query() ) {
       $query->set( 'meta_key', 'featured' );
       $query->set( 'meta_value', 'yes' );
    }
}

add_action( 'pre_get_posts', 'show_featured_posts' );

Aber ich möchte, dass die Posts, die 'featured' meta_key haben, von der Hauptabfrage ausgeschlossen werden. Gibt es dafür einen einfachen Weg?

24
Carlisle

Ich sehe, dass viele Leute es vorziehen, den Haken pre_get_posts anstelle von query_posts zu verwenden

Yay!

pre_get_posts filtert also ein WP_Query Objekt , was bedeutet, dass alles, das Sie über query_posts() ausführen können, Sie über $query->set() und $query->get() ausführen können. Insbesondere können wir das Attribut meta_query verwenden (siehe Codex ):

$meta_query = array(
                 array(
                    'key'=>'featured',
                    'value'=>'yes',
                    'compare'=>'!=',
                 ),
);
$query->set('meta_query',$meta_query);

Aber ... dies ersetzt die ursprüngliche "Meta-Abfrage" (falls vorhanden). Wenn Sie also die ursprüngliche Meta-Abfrage nicht vollständig ersetzen möchten, empfehle ich Folgendes:

//Get original meta query
$meta_query = $query->get('meta_query');

//Add our meta query to the original meta queries
$meta_query[] = array(
                    'key'=>'featured',
                    'value'=>'yes',
                    'compare'=>'!=',
                );
$query->set('meta_query',$meta_query);

Auf diese Weise fügen wir unsere Meta-Abfrage neben vorhandenen Meta-Abfragen hinzu.

Möglicherweise möchten Sie die Eigenschaft relation von $meta_query nicht auf AND oder OR setzen (um Posts zurückzugeben, die alle oder mindestens eine Metaabfrage erfüllen).

*Hinweis:Dieser Abfragetyp gibt Beiträge mit dem Metaschlüssel 'featured' zurück, deren Wert jedoch nicht yes ist. Er enthält keine Beiträge mit dem Zusatz 'featured'. Metaschlüssel existiert nicht. Du wirst in der Lage sein, dies in 3.5 zu tun .

33
Stephen Harris

Ich möchte meine vorübergehende Lösung für vorgestellte Posts veröffentlichen, falls einige Leute davon Gebrauch machen. Ich verwende hier keinen pre_get_posts hook, aber auch keinen query_posts. Das Problem ist, dass ich mit der Hauptabfrage spielen und eine SQL-Abfrage ausführen muss. Ich würde mich freuen, wenn Experten den Code überprüfen und mir mitteilen könnten, ob er in Ordnung ist und keine Leistungsprobleme verursacht. Es wird auch toll sein, wenn jemand einen besseren Ansatz hat und ihn mit uns teilt.

Abfrage für vorgestellte Beiträge erstellen

<?php 

$featured_query = new WP_query( array(
    'meta_key'       =>'featured', 
    'meta_value'     =>'yes', 
    'posts_per_page' => 5, 
    'no_found_rows'  => true
    )
);

while ($featured_query->have_posts()) : 

    $featured_query->the_post(); 
    //Stuff...

endwhile; 
wp_reset_postdata(); 

?>

Erstellen Sie die Hauptabfrage, schließen Sie die Posts mit dem angegebenen meta_key aus, beschränken Sie den Ausschluss auf die letzten 5 Posts und zeigen Sie alle anderen an.

<?php 

$excludeposts = $wpdb->get_col( "SELECT post_id FROM $wpdb->postmeta WHERE meta_key = 'featured' AND meta_value != '' ORDER BY post_id DESC LIMIT 0, 5" );

$main_query = new WP_Query( array(
    'post__not_in' => $excludeposts, 
    'paged' => $paged 
    ) 
);  

while ($main_query->have_posts()) : 

    $main_query->the_post();
    //Stuff...

endwhile;

?>
2
Carlisle

Als Antwort auf @Carlisle können Sie die folgenden Schritte ausführen, wenn Sie die letzten 5 als "Hervorgehoben" gekennzeichneten Beiträge ausschließen möchten. Ändern Sie die posts_per_page in die Anzahl der auszuschließenden Beiträge und die meta_query in die Art und Weise, wie Sie die vorgestellte Kategorie bestimmen.

function cmp_exclude_featured_posts($query) {
    $exclude = array();  //Create empty array for post ids to exclude
    if ( $query->is_main_query() ) {
            $featured = get_posts(array(
                'post_type' => 'post',
                'meta_query' => array(
                    array(
                        'key' => 'featured',
                        'value' => '1',
                        'compare' => '==',
                    ),
                ),
                'posts_per_page' => 2
            ));

            foreach($featured as $hide) {
                $exclude[] = $hide->ID;
            }   

            $query->set('post__not_in', $exclude);
        }
}

add_filter( 'pre_get_posts', 'cmp_exclude_featured_posts' );
0
cpeckens