Query_posts () should be avoided?

I read that query_posts() should be avoided in favor of wp_query() and pre_get_posts() . I’m not sure that I’m at war with Loop and don’t quite understand the code.

Does the code below query_posts() ? If so, and since query_posts() should be avoided, can you suggest a method that does not use query_posts() but still does the same thing?

This code in functions.php used to sort messages randomly or by price.

 function my_custom_query($query){ if ( $query->is_home() && $query->is_main_query() ) { $sort= $_GET['sort']; if($sort == "pricelow"){ $query->set( 'meta_key', 'price' ); $query->set( 'orderby', 'meta_value_num' ); $query->set( 'order', 'ASC' ); } if($sort == "random"){ $query->set( 'orderby', 'rand' ); } } } add_action( 'pre_get_posts', 'my_custom_query' ); 

.
Link A (Random) and Link B (Price) are placed on my menu using this code. Thus, a visitor to the site can sort messages simply by clicking on the link.

 <a href="http://website.com/?sort=A">Random</a> <a href="http://website.com/?sort=B">Price</a> 
+2
php wordpress wp-query
source share
2 answers

I made a very detailed explanation on this topic at WPSE, and for the sake of the value and benefits it can have for SO users, here is a complete post copied from this question on WPSE. For fun, here is the link to the full WPSE post: Some doubts about how the main request and user request work in this custom theme?

Your actual question is mainly to run a custom query and when to use the main query. Allows you to break it into three parts.

PART ONE

When to run a custom query (this is not a final list)

  • To create custom content sliders

  • To create a displayable content area on a page

  • On page.php templates if you need to display posts

  • If you need custom content on a static homepage

  • Display related, popular or informational messages

  • Any other additional or additional content is outside the scope of the main request.

When to use the main request.

To display main content on

  • On the home page and page set as the blog page in the backend

  • All archive pages containing templates, such as archive.php, category.php, author.php, taxonomy.php, tag.php and date.php

PART TWO

To select all the assigned entries, I use this line, which creates a new WP_Query object that defines a query with a specific tag:

So, from what I understood, this is not the main WordPres request, but this is a new request created by me. From what I understood, it is better to create a new request (as done) and not use the main request when I want to perform such operations

Correctly. This is beyond the scope of the main request. This is additional or additional content that cannot be created using the main request. You MUST ALWAYS use WP_Query or get_posts to create your custom queries.

NEVER USE query_posts to create custom queries or even any other query. My emphasis.

Note. This feature is not intended for use by plugins or themes. As explained below, there are more efficient, more efficient options for modifying the main request. query_posts () is a too simplistic and problematic way to modify the main page request by replacing it with a new instance of the request. It is inefficient (re-runs SQL queries), and in some cases it will fail (especially when working with pagination).

Moving

Okay, I continue. I show all messages that have no sign, for this I use this piece of code, which, on the contrary, modifies the main request:

 query_posts( array( 'tag__not_in' => array ( $term->term_id ))); 

So I think this is pretty terrible. It's true?

This is all wrong, and your statement, unfortunately, is true. As stated earlier, NEVER use query_posts . It executes a complete new request, which is bad for performance, and in most cases it breaks pagination, which is an integral part of the main request for the page to work correctly.

This is your main content, so you should use the main request with a default loop, which should look like that, and that’s all you need

 <?php if (have_posts()) : // Start the Loop. while (have_posts()) : the_post(); get_template_part('content', get_post_format()); endwhile; else : // If no content, include the "No posts found" template. get_template_part('content', 'none'); endif; ?> 

You can completely get rid of this part, delete it, write it down and forget about it

 <? // get the term using the slug and the tag taxonomy $term = get_term_by( 'slug', 'featured', 'post_tag' ); // pass the term_id to tag__not_in query_posts( array( 'tag__not_in' => array ( $term->term_id ))); ?> 

OK, as soon as you do this, you will see that the messages from the function tag are displayed on your home page using the main request and the default loop.

The correct way to remove this tag from the home page is pre_get_posts . This is the correct way to modify the main request , and you should always use it to make changes to your main content outline.

So, the code with pre_get_posts correct, and this is the function you should use. Only one thing: always check that you are not on the admin page, because pre_get_posts also changes the back end. So this is the correct code to use in functions.php to delete messages tagged from the main page

 function exclude_featured_tag( $query ) { if ( !is_admin() && $query->is_home() && $query->is_main_query() ) { $query->set( 'tag__not_in', 'array(ID OF THE FEATURED TAG)' ); } } add_action( 'pre_get_posts', 'exclude_featured_tag' ); 

PART THREE

Additional reading material that will be useful in the future

+4
source share

Creating a new WP_Query () object is always wonderful.

 $sort= $_GET['sort']; if($sort == "pricelow"){ $sort_args = array('meta_key' => 'price', 'orderby' => 'meta_value_num', 'order', 'ASC'); $new_query = new WP_Query($sort_args); } blah blah blah... 

No, I do not regret it. I did not see the pre_get_posts hook.

The code in your question is good for connecting queries. As described in the WordPress Plugin API / Action Reference / pre_get_posts :

pre_get_posts starts before installing WP_Query.

Thus, it intercepts WP_Query () by default wherever you want (in your code, it modifies WP_Query in the GET request).

In template files, use the new WP_Query ($ args).

+1
source share

All Articles