1. pre_get_posts
Definition:
- A filter hook that lets you modify the main query before it runs.
- Runs early in the page load (before posts are fetched).
- Preferred method for changing queries.
Example:
function modify_main_query( $query ) {
if ( $query->is_main_query() && !is_admin() && $query->is_home() ) {
$query->set( 'posts_per_page', 5 );
}
}
add_action( 'pre_get_posts', 'modify_main_query' );Advantages:
- Works without replacing the main query.
- Maintains pagination and other WordPress logic.
- More efficient.
2. query_posts()
Definition:
- A template tag that modifies the main query by replacing it entirely.
- Runs after WordPress has already created the main query.
- Not recommended because it can break pagination and cause performance issues.
Example:
query_posts( array(
'posts_per_page' => 5,
'category_name' => 'news'
) );Disadvantages:
- Overrides the main
$wp_queryobject. - Can mess up pagination and conditional tags.
- Less flexible and older approach.
Key Differences Table
| Feature | pre_get_posts | query_posts() |
|---|---|---|
| Type | Action/filter hook | Template tag |
| When Runs | Before main query executes | After main query created |
| Performance | Efficient, recommended | Less efficient, not recommended |
| Pagination | Preserves pagination | Often breaks pagination |
| Best Use | Modify main query parameters | Quick, temporary query changes (rarely advised) |
💡 Quick Memory Tip:
pre_get_posts= Adjust the recipe before cooking 🍲query_posts()= Throw away the first dish and start over — wasteful and messy.
