Posso escludere un articolo tramite meta key usando la funzione pre_get_posts?

10 nov 2012, 01:55:57
Visualizzazioni: 36.3K
Voti: 33

Vedo che molte persone preferiscono usare l'hook pre_get_posts invece di query_posts. Il codice seguente funziona e mostra tutti i post che hanno la meta key "featured"

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

Ma voglio che i post che hanno la meta_key 'featured' vengano esclusi dalla query principale. C'è un modo semplice per farlo?

0
Tutte le risposte alla domanda 3
4
46

Vedo che molte persone preferiscono usare l'hook pre_get_posts invece di query_posts

Evviva!

Quindi pre_get_posts filtra un WP_Query object il che significa che qualsiasi cosa tu possa fare con query_posts() puoi farla tramite $query->set() e $query->get(). In particolare possiamo utilizzare l'attributo meta_query (vedi Codex):

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

Ma... questo sostituisce la 'meta query' originale (se ne aveva una). Quindi a meno che tu non voglia sostituire completamente la meta query originale, suggerisco:

//Ottieni la meta query originale
$meta_query = $query->get('meta_query');

//Aggiungi la nostra meta query alle meta query esistenti
$meta_query[] = array(
                    'key'=>'featured',
                    'value'=>'yes',
                    'compare'=>'!=',
                );
$query->set('meta_query',$meta_query);

In questo modo aggiungiamo la nostra meta query insieme a quelle esistenti.

Potresti voler/non voler impostare la proprietà relation di $meta_query a AND o OR (per restituire post che soddisfano tutte, o almeno una, delle meta query).

* Nota: Questo tipo di query restituirà post con la meta key 'featured', ma il cui valore non è yes. Non includerà post dove la meta key 'featured' non esiste. Sarai in grado di farlo nella versione 3.5.

10 nov 2012 12:32:19
Commenti

Quindi non c'è modo di verificare se un meta_key per un post esiste o no / è vuoto o no? Dovrò aspettare la 3.5. allora. Grazie per la tua risposta.

Carlisle Carlisle
10 nov 2012 14:57:03

Creerò semplicemente una meta box con opzioni e No e 'No' sarà selezionato di default. Quando voglio mettere in evidenza un post selezionerò . Tuttavia, voglio che gli ultimi 5 post rimangano in evidenza e gli altri vengano visualizzati nella query principale. Non voglio tornare indietro e cambiare la selezione ogni volta, quindi devo trovare un modo per escludere solo i 5 post più recenti. Vedo molte domande simili su stackexchange e dovrebbe esserci un modo semplice per gestire questi post in evidenza. (un modo che non influisca sulle prestazioni generali, non crei molte query o non richieda query SQL miste)

Carlisle Carlisle
10 nov 2012 15:38:45

BTW non sono sicuro che sia una buona idea creare un meta_key aggiuntivo con valore o No per tutti i post. Sarebbe bello escludere quei post che semplicemente non hanno la chiave featured.

Carlisle Carlisle
10 nov 2012 15:44:55

Questa funzione ha smesso di funzionare sul mio sito dopo l'aggiornamento a PHP 7, generando un errore Uncaught Error: [] operator not supported for strings poiché l'originale meta_query risultava null. Puoi risolvere il problema facendo fallback a un array vuoto se non esiste, sostituendo $meta_query = $query->get('meta_query'); con $meta_query = ( is_array( $query->get('meta_query') ) ) ? $query->get('meta_query') : [];.

Kevin Nugent Kevin Nugent
22 feb 2018 13:59:06
0

Voglio condividere la mia soluzione temporanea per i post in evidenza nel caso possa essere utile ad altri. Non utilizzo l'hook pre_get_posts qui, ma nemmeno query_posts. Il problema è che devo lavorare con la query principale e devo eseguire una parte di query SQL. Sarei felice se degli esperti potessero controllare il codice e farmi sapere se va bene e non causerà problemi di prestazioni. Sarebbe anche fantastico se qualcuno avesse un approccio migliore e lo condividesse con noi.

Creare la query per i post in evidenza

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

endwhile; 
wp_reset_postdata(); 

?>

Creare la query principale, escludere i post che hanno il meta_key featured, limitare l'esclusione ai 5 post più recenti e mostrare tutti gli altri.

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

endwhile;

?>
10 nov 2012 18:27:34
0

In risposta a @Carlisle, se vuoi escludere i 5 post più recenti contrassegnati come in evidenza, potresti fare quanto segue. Modifica posts_per_page con il numero di post che vuoi escludere e meta_query con il modo in cui stai designando la categoria in evidenza.

function cmp_exclude_featured_posts($query) {
    $exclude = array();  //Crea un array vuoto per gli ID dei post da escludere
    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' );
29 apr 2015 21:21:09