Posso excluir uma postagem por meta-chave usando a função pre_get_posts?

24

Vejo que muitas pessoas preferem usar pre_get_postsgancho em vez de query_posts. O código abaixo funciona e mostra todas as postagens com meta-chave "em destaque"

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

Mas quero que as postagens com ' featured' meta_key sejam excluídas da consulta principal. Existe uma maneira fácil para isso?

Carlisle
fonte

Respostas:

33

Vejo que muitas pessoas preferem usar o gancho pre_get_posts em vez de query_posts

Yay!

Então pre_get_postsfiltra um WP_Queryobjeto, o que significa que qualquer coisa que você possa fazer via, query_posts()pode fazer via $query->set()e $query->get(). Em particular, podemos fazer uso do meta_queryatributo (consulte Codex ):

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

Mas .. isso substitui a 'meta query' original (se houver). Portanto, a menos que você queira substituir completamente a meta consulta original, sugiro:

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

Dessa forma, adicionamos nossa meta consulta ao lado das meta consultas existentes.

Você pode ou não querer definir a relationpropriedade de $meta_querycomo ANDou OR(para retornar postagens que atendam a todas, ou pelo menos uma, meta consultas).

* Nota: este tipo de consulta retornará postagens com a meta-chave 'em destaque', mas cujo valor não é yes. Não incluirá postagens onde a meta-chave 'em destaque' não existe. Você poderá fazer isso na versão 3.5 .

Stephen Harris
fonte
Portanto, não há como verificar se uma meta_key para uma postagem existe ou não / está vazia ou não? Vou ter que esperar 3.5. então. Obrigado pela sua resposta.
Carlisle #
Vou simplesmente criar uma caixa de meta com Yese Noopções e 'Não' será selecionada por padrão. Quando desejar destacar uma postagem, selecionarei Yes. No entanto, quero que as últimas 5 postagens permaneçam em destaque e outras sejam exibidas na consulta principal. Não quero voltar e alterar a seleção todas as vezes, por isso tenho que encontrar uma maneira de excluir apenas as 5 postagens mais recentes. Vejo muitas perguntas semelhantes no stackexchange e deve haver uma maneira fácil de gerenciar essas postagens em destaque. (uma forma que não afeta o desempenho geral, não cria muitas consultas ou exigir consultas SQL mistos)
Carlisle
BTW, não tenho certeza se é uma boa ideia criar uma meta_key extra com Yesou Novalor para todas as postagens. Seria ótimo excluir as postagens que simplesmente não possuem a featuredchave.
Carlisle
Esta função foi interrompida no meu site após a atualização para o PHP 7, gerando um Uncaught Error: [] operator not supported for stringserro, pois o original meta_queryvoltava como nulo. Você pode obter em torno dele, caindo para trás para uma matriz vazia se não existe nenhum comutação para fora $meta_query = $query->get('meta_query');para $meta_query = ( is_array( $query->get('meta_query') ) ) ? $query->get('meta_query') : [];.
Kevin Nugent
2

Quero postar minha solução temporária para as postagens em destaque, caso algumas pessoas possam fazer uso dela. Eu não uso pre_get_postsgancho aqui, mas query_poststambém não . O problema é que eu tenho que brincar com a consulta principal e executar uma parte da consulta sql. Ficaria feliz se algum especialista pudesse verificar o código e me informar se está correto e não causará problemas de desempenho. Também será ótimo se alguém tiver uma abordagem melhor e compartilhá-la conosco.

Criar consulta de postagens em destaque

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

?>

Crie a consulta principal, exclua as postagens com a meta_key em destaque, limite a exclusão a 5 postagens mais recentes e mostre todas as outras.

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

?>
Carlisle
fonte
0

Em resposta @Carlisle, se você quiser excluir as 5 postagens mais recentes marcadas como em destaque, faça o seguinte. Mude o posts_per_page para quantos você deseja excluir e a meta_query para como você está designando a categoria em destaque.

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