Como limitar WP_Query a um resultado no loop?

Estou tentando obter apenas um post e isso precisa ser o mais recente, então aqui está o que estou fazendo:

$basic_args = $wp_query->query_vars; $basic_args['tax_query'] = $wp_query->tax_query; $aditional_args = array( 'post__in' => get_option('sticky_posts'), 'ignore_sticky_posts' => 1, 'order' => 'desc', 'post_status' => 'publish', 'posts_per_page' => 1 ); $normal_args = array_merge($basic_args, $aditional_args); $normal_query = new WP_Query($normal_args); $prev_post_ids = array(); if (!$normal_query->have_posts()) { $normal_args = array_merge($basic_args, array('posts_per_page' => 1)); $normal_query = new WP_Query($normal_args); } echo $normal_query->post_count; // returns 25 if ($normal_query->have_posts()) { while ($normal_query->have_posts()) { .... // here I got 25 results instead of just one } } 

Eu sei que posts_per_page deve limitar o número de posts que recebo, mas não está funcionando para mim e não sei por quê. Como você pode ler, estou recebendo 25 posts no loop em vez de um. Alguém pode me dar algum conselho sobre esse assunto? Eu li isso e isso, mas não está ajudando.

Update1

Eu $normal_query->request como sugerido por @ pieter-goosen e estou recebendo essa consulta SQL incorreta :

 SELECT SQL_CALC_FOUND_ROWS wp_posts.ID FROM wp_posts INNER JOIN wp_term_relationships ON (wp_posts.ID = wp_term_relationships.object_id) INNER JOIN wp_term_relationships AS tt1 ON (wp_posts.ID = tt1.object_id) WHERE 1=1 AND ( wp_term_relationships.term_taxonomy_id IN (6) AND tt1.term_taxonomy_id IN (6) ) AND wp_posts.post_type IN ('opinion', 'post', 'especiales') AND ((wp_posts.post_status = 'publish')) GROUP BY wp_posts.ID ORDER BY wp_posts.post_date DESC LIMIT 0, 25 

Onde o LIMIT é modificado?

Update2

Tenho também debug os $basic_args que têm $wp_query->query_vars e também $normal_args e aqui está o resultado:

 echo '
'; print_r($basic_args); echo '

'; Array ( [category_name] => internacionales [error] => [m] => [p] => 0 [post_parent] => [subpost] => [subpost_id] => [attachment] => [attachment_id] => 0 [name] => [static] => [pagename] => [page_id] => 0 [second] => [minute] => [hour] => [day] => 0 [monthnum] => 0 [year] => 0 [w] => 0 [tag] => [cat] => 409 [tag_id] => [author] => [author_name] => [feed] => [tb] => [paged] => 0 [comments_popup] => [meta_key] => [meta_value] => [preview] => [s] => [sentence] => [title] => [fields] => [menu_order] => [category__in] => Array ( ) [category__not_in] => Array ( ) [category__and] => Array ( ) [post__in] => Array ( ) [post__not_in] => Array ( ) [post_name__in] => Array ( ) [tag__in] => Array ( ) [tag__not_in] => Array ( ) [tag__and] => Array ( ) [tag_slug__in] => Array ( ) [tag_slug__and] => Array ( ) [post_parent__in] => Array ( ) [post_parent__not_in] => Array ( ) [author__in] => Array ( ) [author__not_in] => Array ( ) [ignore_sticky_posts] => [suppress_filters] => [cache_results] => 1 [update_post_term_cache] => 1 [update_post_meta_cache] => 1 [post_type] => [posts_per_page] => 10 [nopaging] => [comments_per_page] => 50 [no_found_rows] => [order] => DESC [tax_query] => WP_Tax_Query Object ( [queries] => Array ( [0] => Array ( [taxonomy] => category [terms] => Array ( [0] => internacionales ) [field] => slug [operator] => IN [include_children] => 1 ) ) [relation] => AND [table_aliases:protected] => Array ( [0] => wp_term_relationships ) [queried_terms] => Array ( [category] => Array ( [terms] => Array ( [0] => internacionales ) [field] => slug ) ) [primary_table] => wp_posts [primary_id_column] => ID ) ) echo '

'; print_r($normal_args); echo '

'; Array ( [category_name] => internacionales [error] => [m] => [p] => 0 [post_parent] => [subpost] => [subpost_id] => [attachment] => [attachment_id] => 0 [name] => [static] => [pagename] => [page_id] => 0 [second] => [minute] => [hour] => [day] => 0 [monthnum] => 0 [year] => 0 [w] => 0 [tag] => [cat] => 409 [tag_id] => [author] => [author_name] => [feed] => [tb] => [paged] => 0 [comments_popup] => [meta_key] => [meta_value] => [preview] => [s] => [sentence] => [title] => [fields] => [menu_order] => [category__in] => Array ( ) [category__not_in] => Array ( ) [category__and] => Array ( ) [post__in] => Array ( ) [post__not_in] => Array ( ) [post_name__in] => Array ( ) [tag__in] => Array ( ) [tag__not_in] => Array ( ) [tag__and] => Array ( ) [tag_slug__in] => Array ( ) [tag_slug__and] => Array ( ) [post_parent__in] => Array ( ) [post_parent__not_in] => Array ( ) [author__in] => Array ( ) [author__not_in] => Array ( ) [ignore_sticky_posts] => 1 [suppress_filters] => [cache_results] => 1 [update_post_term_cache] => 1 [update_post_meta_cache] => 1 [post_type] => [posts_per_page] => 1 [nopaging] => [comments_per_page] => 50 [no_found_rows] => [order] => desc [tax_query] => WP_Tax_Query Object ( [queries] => Array ( [0] => Array ( [taxonomy] => category [terms] => Array ( [0] => internacionales ) [field] => slug [operator] => IN [include_children] => 1 ) ) [relation] => AND [table_aliases:protected] => Array ( [0] => wp_term_relationships ) [queried_terms] => Array ( [category] => Array ( [terms] => Array ( [0] => internacionales ) [field] => slug ) ) [primary_table] => wp_posts [primary_id_column] => ID ) [post_status] => publish )

Como você pode ver, post_per_page é definido como 1 aqui, então por que está tomando esses 25?

Atualização 3

Aparentemente, esse é o código problemático em functions.php :

 function change_wp_search_size($query) { if ($query->is_search) { $query->query_vars['posts_per_page'] = 25; } // Change 25 to the number of posts you would like to show return $query; // Return our modified query variables } add_filter('pre_get_posts', 'change_wp_search_size'); 

Não deveria isso funcionar apenas para pesquisa? Por que atua sobre todos os query_vars o tempo todo?

Solutions Collecting From Web of "Como limitar WP_Query a um resultado no loop?"

pre_get_posts altera todas as consultas, back-end e front-end independentemente.

Há duas verificações muito importantes que uma grande quantidade de pessoas perde, isto é, a verificação !is_admin() que só tem como destino o front-end e, em seguida, a verificação mais importante, is_main_query() que só alterará a consulta principal e não as consultas personalizadas .

Sua afirmação deve parecer algo como o follwoing

 if ( !is_admin() && $query->is_main_query() && $query->is_search() ) { // Your arguments to set } 

Ok, depois das sugestões de @ pieter-goosen , encontrei uma solução, apenas adicionando esta remove_all_filters( 'pre_get_posts' ) antes de executar que WP_Query corrija o problema, espere que ajude a outros