Czy mogę wykluczyć post za pomocą meta-klucza za pomocą funkcji pre_get_posts?


24

Widzę, że wiele osób woli używać pre_get_postshaczyka zamiast query_posts. Poniższy kod działa i pokazuje wszystkie posty, które mają „polecany” meta klucz

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

Chcę jednak, aby posty zawierające featured„meta_key” były wykluczone z głównego zapytania. Czy jest na to łatwy sposób?

Odpowiedzi:


33

Widzę, że wiele osób woli używać zaczepu pre_get_posts zamiast query_posts

Tak!

Tak pre_get_postsfiltruje WP_Queryobiektu , co oznacza niczego można zrobić poprzez query_posts()można zrobić poprzez $query->set()a $query->get(). W szczególności możemy skorzystać z meta_queryatrybutu (patrz Kodeks ):

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

Ale… to zastępuje oryginalne „meta kwerenda” (jeśli taka miała). Więc jeśli nie chcesz całkowicie zastąpić oryginalnego zapytania meta, sugeruję:

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

W ten sposób dodajemy nasze zapytanie do meta obok istniejących zapytań do meta.

Możesz / możesz nie chcieć ustawić relationwłaściwości $meta_queryna ANDlub OR(aby zwracać posty, które spełniają wszystkie, lub przynajmniej jedno, meta-zapytania).

* Uwaga: ten typ zapytania zwróci posty z „polecanym” meta kluczem, ale którego wartość nie jest yes. Nie będzie zawierać postów, w których „polecany” meta klucz nie istnieje. Będziesz mógł to zrobić w 3.5 .


Więc nie ma sposobu, aby sprawdzić, czy meta_klucz do wpisu istnieje, czy nie / jest pusty, czy nie? Będę musiał czekać 3.5. następnie. Dzięki za odpowiedź.
— Carlisle,

Ja po prostu utworzyć pole z meta Yesi Noopcje i „nie” będzie domyślnie zaznaczona. Kiedy chcę polecić post, wybiorę Yes. Chcę jednak, aby 5 ostatnich postów pozostało polecanych, a inne będą wyświetlane w głównym zapytaniu. Nie chcę wracać i zmieniać wyboru za każdym razem, więc muszę znaleźć sposób na wykluczenie tylko ostatnich 5 postów. Widzę wiele podobnych pytań na temat stackexchange i powinien istnieć łatwy sposób zarządzania tymi polecanymi postami. (sposób, który nie wpływa na ogólną wydajność, nie tworzy wielu zapytań ani nie wymaga mieszanych zapytań SQL)
— Carlisle,

BTW Nie jestem pewien, czy dobrym pomysłem jest utworzenie dodatkowego meta_key z Yeslub Nowartości dla wszystkich postów. Byłoby wspaniale wykluczyć te posty, które po prostu nie mają featuredklucza.
— Carlisle,

Ta funkcja właśnie zepsuła się na mojej stronie po aktualizacji do PHP 7, zgłaszając Uncaught Error: [] operator not supported for stringsbłąd, ponieważ oryginał meta_querywracał jako zerowy. Można to obejść przez sięgnięcie do pustej tablicy, jeśli żaden nie istnieje przełączania się $meta_query = $query->get('meta_query');na $meta_query = ( is_array( $query->get('meta_query') ) ) ? $query->get('meta_query') : [];.
— Kevin Nugent,

2

Chcę opublikować moje tymczasowe rozwiązanie dla polecanych postów na wypadek, gdyby niektóre osoby mogły z niego skorzystać. Nie używam pre_get_poststutaj haczyka, ale też nie query_posts. Problem polega na tym, że muszę grać z głównym zapytaniem i uruchomić kawałek zapytania SQL. Byłbym szczęśliwy, gdyby jakikolwiek ekspert mógł sprawdzić kod i dać mi znać, czy jest w porządku i nie spowoduje żadnych problemów z wydajnością. Będzie również świetnie, jeśli ktoś będzie miał lepsze podejście i podzieli się nim z nami.

Utwórz zapytanie o polecane posty

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

?>

Utwórz główne zapytanie, wyklucz posty z poleconym meta_key, ogranicz wykluczenie do 5 najnowszych postów i pokaż wszystkie inne.

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

?>

0

W odpowiedzi na @Carlisle, jeśli chcesz wykluczyć 5 najnowszych postów oznaczonych jako polecane, możesz wykonać następujące czynności. Zmień stronę posts_per_page na liczbę, które chcesz wykluczyć, a meta_query na sposób oznaczania polecanej kategorii.

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' );
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.