Devo usar Pre Get Posts ou WP_Query

28

Eu tenho a seguinte consulta que eu chamo no meu modelo taxonomy.php via query_brands_geo('dealers', 'publish', '1', $taxtype, $geo, $brands);

Esta função funciona perfeitamente. No entanto, depois de ler o codex para postagens de consulta, ele mencionou pre_get_posts como uma maneira preferida de alterar a consulta padrão. Os pre_get_posts seriam mais eficientes que a minha função wp_query abaixo?

Se sim, como eu construiria o pre_get_posts e passaria minha variável e consulta abaixo?

function my_custom_query($posttype, $poststatus, $paidvalue, $taxtype, $geo, $brands) {
   global $wp_query; 
   $wp_query = new WP_Query();
   $args = array( 
      'post_type' => $posttype, 
      'post_status' => array($poststatus), 
      'orderby' => 'rand', 
      'posts_per_page' => 30, 
      'meta_query' => array( 
         array( 
            'key' => 'wpcf-paid', 
            'value' => array($paidvalue), 
            'compare' => 'IN', 
            ) 
      ), 
      'tax_query' => array( 
         'relation' => 'AND', 
         array( 
            'taxonomy' => $taxtype, 
            'field' => 'slug', 
            'terms' => $geo 
         ), 
         array( 
            'taxonomy' => 'brands', 
            'field' => 'slug', 
            'terms' => $brands 
         ) 
      ) 
   ); 

   return $wp_query->query($args); 
} 
    
por user1609391 18.12.2012 / 23:08
fonte

3 respostas

14

pre_get_posts executará a mesma consulta, portanto, ambos levarão o mesmo tempo. Mas, se você utilizar a ação pre_get_posts , você salvará uma ou mais consultas SQL. Agora, o WordPress está executando a consulta padrão e, em seguida, você executa sua consulta com essa função que substitui os resultados da consulta padrão (resultante, a consulta padrão é inútil). Abaixo está como você pode mover seu $args para

function custom_pre_get_posts($query, $posttype='dealers', $poststatus='publish', $paidvalue='1', $taxtype='any_default_value', $geo='any_default_value', $brands='any_default_value') {

    // filter your request here.
    if($query->is_category) {

        $args = array(
            'post_type' => $posttype,
            'post_status' => array($poststatus),
            'orderby' => 'rand',
            'posts_per_page' => 30,
            'meta_query' => array(
                array(
                    'key' => 'wpcf-paid',
                    'value' => array($paidvalue),
                    'compare' => 'IN',
                )
            ),
            'tax_query' => array(
                'relation' => 'AND',
                array(
                    'taxonomy' => $taxtype,
                    'field' => 'slug',
                    'terms' => $geo
                ),
                array(
                    'taxonomy' => 'brands',
                    'field' => 'slug',
                    'terms' => $brands
                )
            )
        );
        $query->query_vars = $args;
    }
}
add_action('pre_get_posts', 'custom_pre_get_posts');
    
por M-R 19.12.2012 / 09:41
fonte
10

Resposta tardia, pois a resposta mais votada irá quebrar sua consulta e simplesmente não será verdadeira em alguns pontos importantes.

A main WP_Query e seus filtros

Primeiro, o WordPress usa internamente query_posts() (um wrapper fino em torno de WP_Query que não deveria ser usado em temas ou plugins) para fazer um WP_Query . Este WP_Query está agindo como o loop / consulta principal. Essa consulta será executada em vários filtros e ações até que a cadeia de consulta SQL real seja criada. Um deles é pre_get_posts . Outros são posts_clauses , posts_where , etc., que também permitem que você intercepte o processo de criação da string de consulta.

Um profundo olhar para o que acontece dentro do núcleo

  

O WordPress executa a função wp() (em wp-includes/functions.php ), que chama $wp->main() ( $wp é um objeto da classe WP, que é definido em wp-includes/class-wp.php ). Isso diz ao WordPress para:

     
  1. Analise o URL em uma especificação de consulta usando WP->parse_request() - mais sobre isso abaixo.
  2.   
  3. Defina todas as variáveis is_ usadas por Tags condicionais usando $wp_query->parse_query() ( $wp_query é um objeto de class WP_Query , que é definido em wp-includes/query.php ). Note que, apesar do nome desta função, neste caso WP_Query->parse_query não faz qualquer análise para nós, já que isso é feito antes por WP->parse_request() .
  4.   
  5. Converta a especificação da consulta em uma consulta de banco de dados MySQL e execute a consulta do banco de dados para obter a lista de postagens, na função WP_Query- > get_posts (). Salve as postagens no objeto $ wp_query a serem usadas no loop do WordPress.
  6.   

Fonte Codex

Conclusão

Se você realmente quiser modificar a consulta principal, poderá usar uma grande variedade de filtros. Basta usar $query->set( 'some_key', 'some_value' ); para alterar os dados ou usar $query->get( 'some_key' ); para recuperar os dados para fazer verificações condicionais. Isso evitará que você faça uma segunda consulta, pois está alterando somente a consulta SQL.

Se você precisar fazer uma consulta adicional , use o objeto WP_Query . Isso adicionará outra consulta ao banco de dados.

Exemplo

Como as respostas sempre funcionam melhor com um exemplo, você aqui tem uma muito boa (props para Brad Touesnard), que simplesmente estende o objeto principal e, portanto, é bastante reutilizável (faça um plug-in):

class My_Book_Query extends WP_Query
{
    function __construct( $args = array() )
    {
        // Forced/default args
        $args = array_merge( $args, array(
            'posts_per_page' => -1
        ) );

        add_filter( 'posts_fields', array( $this, 'posts_fields' ) );

        parent::__construct( $args );
    }

    public function posts_fields( $sql )
    {
        return "{$sql}, {$GLOBALS['wpdb']->terms}.name AS 'book_category'";
    }
}

Você pode então executar sua segunda / consulta adicional, como você pode ver no exemplo a seguir. Não se esqueça de redefinir sua consulta depois.

$book_query = new My_Book_Query();
if ( $book_query->have_posts() )
{
    while ( $book_query->have_posts() )
    {
        $book_query->the_post();
        # ...do stuff...
    } // endwhile;
    wp_reset_postdata();
} // endif;
    
por kaiser 10.03.2013 / 16:24
fonte
6

Por favor, verifique as respostas em Quando usar WP_query (), query_posts () e pre_get_posts .

É um ótimo recurso se você tiver alguma dúvida em mente.

    
por fischi 19.12.2012 / 09:51
fonte