Useful WordPress Hooks – Part 1

In

For a WordPress developer, action hooks and filters are like their brothers and sisters. It helps a developer to hook into any particular code block/function and interact with it by modifying the data. Hooks are a way for one piece of code to interact/modify another piece of code at specific, pre-defined spots. They make up the foundation for how plugins and themes interact with WordPress Core, but they’re also used extensively by Core itself.

In this series, we will explore many different useful hooks and filters in WordPress and I will share tips and tricks on using them. I will also share my favourite hook at the end of the series. Let’s explore then.

1. pre_get_posts

In WordPress, pre_get_posts is an action that makes it easy to modify an existing WP_Query, before that query is actually run. pre_get_posts offers some solutions that are more performant than writing a custom WP_Query, and enables solutions to other problems that would be quite difficult otherwise.

Targeting the right query

We need to beaways when we are trying to interact/modify with any query using the pre_get_posts action. Such as,

Be aware of the queries you are changing when using the . Make use of conditional tags to target the right query. For example, its recommended to use the the is_admin() conditional to not change queries in the admin screens. With the $query->is_main_query() conditional from the query object you can target the main query of a page request. The main query is used by the primary post loop that displays the main content for a post, page or archive. Without these conditionals you could unintentionally be changing the query for custom loops in sidebars, footers, or elsewhere.

Let’s look at one example below

<?php
function target_main_category_query_with_conditional_tags( $query ) {
	if ( is_admin() && !$query->is_main_query() ) {
		return;
	}
		
	// Not a query for an admin page.
	// It's the main query for a front end page of your site.
	if ( is_category() ) {
		// It's the main query for a category archive.
		
		// Let's change the query for category archives.
		$query->set( 'posts_per_page', 15 );
	}
}
add_action( 'pre_get_posts', 'target_main_category_query_with_conditional_tags' );

Think about a situation where we want to exclude pages, testimonials, and any other custom post types from search results? We can simply exclude them using the code below

<?php
function site_search_filter($query) {
  if ( is_admin() && !$query->is_main_query() ) {
    return;
  }
  if ($query->is_search) {
    $query->set( 'post_type', 'post' );
  }
}
  add_action( 'pre_get_posts', 'site_search_filter' );

It’s easy to modify WP_Query’s with pre_get_posts

Sometimes you need to modify a custom WP_Query that you didn’t write. This most likely means a query from an external plugin, or from somewhere in WordPress core.

For example, the “Recent Posts” widget is a part of WordPress core. Let’s say that we’re using “Recent Posts” on our site, and that we’ve just created a page called “Electronics.” On our Electronics page, and that page alone, we want the “Recent Posts” widget to only show recent posts that are tagged with “electronics.”

We could add a better “Recent Posts” widget that allows this, and then make a custom widget area exclusively for the “Electronics” page, but that creates quite a bit of clutter. Instead, let’s just conditionally modify the custom WP_Query that “Recent Posts” uses. That process has three steps:

  1. Make sure we’re on the “Electronics” page,
  2. Make absolutely sure we’re talking to the custom query generated by “Recent Posts” (the hardest part), and
  3. Modify that query to meet our needs.

Here’s the code:

<?php
add_action( 'pre_get_posts', 'site_recent_posts' );
function site_recent_posts( $query ) {
	// Do nothing if not on Electronics page
	if ( !is_page( 'Electronics' ) ) {
    return;
  }

	// Make sure we're talking to the WP_Query
	if ( ! is_main_query() &&
		$query->query[ 'no_found_rows' ] === true &&
		$query->query[ 'post_type' ] === NULL
	) :
		// Fetch only posts tagged with "electronics"
		$taxquery = array(
			array(
				'taxonomy' => 'post_tag',
				'field' => 'slug',
				'terms' => array( 'electronics' ),
			)
		);
		$query->set( 'tax_query', $taxquery );

	endif;
}

Working with pre_get_posts is pretty easy and helps to interact with post query a lot. In the next part of WordPress action hooks, we discuss something more interesting. See you till then.

Thanks for reading!


Comments

Leave a Reply

Your email address will not be published. Required fields are marked *