If you've used WordPress for any length of time, you are no doubt familiar with the concept of posts and pages. To technocrats, these are known as post types. As delivered, WordPress provides five (5) different post types that are either readily accessible to users or used internally by WordPress. These post types are post, page, attachment, revision, and navigation menu. While these post types suit the average blogger, as a web development platform, WordPress is capable of far exceeding the needs of the average user through the use of hooks, filters, plugins, and custom post types (CPTs).
For example, using WordPress to sell products through an eCommerce solution, such as the very popular WooCommerce, is just one example of how WordPress can be extended through plugins and custom post types. CPTs are new post types you can create for whatever need or purpose you see fit. The WooCommerce individual product pages are examples of a custom post type designed to display products. The product custom post type is created when the WooCommerce plugin is installed.
The Stealthiness of CPTs
Because CPTs are custom components, they can be quite stealthy when it comes to searching through their content. In fact, they are completely off the radar unless you intentionally do something about it. WordPress's search query only "knows" about its own 5 post types, and at that it only searches through post and page content. If you want to include your CPTs in the search query, you have to modify the query parameters to include them.
The following code is used on this site to include our portfolio custom post type in the site's search results page.
Note: This change will also change the way searches execute across the entire WordPress spectrum. For example, when you are searching for an internal link in the post or page editor. To confine the search to the front end only, change line 3 above to read:
How the Snippet Works
The developers behind WordPress are smart people…very smart people! As WordPress has evolved, they gave us the ability to extend WordPress's functionality through hooks and filters. Hooks and filters allow us to 'hook into' the rest of WordPress. In other words, they allow us to work with built-in WordPress functions whenever we need to do something that modifies their behavior. In this case, we are modifying the default behavior of the search query. We do this by hooking into the built-in WordPress pre_get_posts filter. A filter, by the way, is just a type of hook.
The WordPress codex explains the pre_get_posts filter this way:
This hook is called after the query variable object is created, but before the actual query is run.
The pre_get_posts action gives developers access to the $query object by reference (any changes you make to $query are made directly to the original object - no return value is necessary).
The $query object is pretty complex in itself. As a core WordPress feature, it is a work horse. The $query->set() function allows us to set a named query variable to a specific value. In the case of this snippet, we are setting post_type to page or post or portfolio (our cpt). In simpler terms, this snippet is telling WordPress to find our desired string in any of its posts, pages, or portfolio custom post types and display the results in an archive page. Is that cool or what?
Hi Victor,
This was very helpful, thanks a lot.
I have a request/idea for a future blog post in regards to search and CPT’s, and that is “displaying search results”.
From your article above I can now see that it’s fairly straight forward to include custom post types in your WordPress search, but in my experience many of these also require “special treatment” when it comes to displaying them.
Take for example Woocommerce.
On this demo site for example, if I search for “dress” without adding any extra parameters, the search results display is frankly horrible, and not very helpful in terms of converting this search into a sale.
https://demo.woothemes.com/storefront/?s=dress
But.. if I add “&post_type=product” to my query, then it suddenly becomes a lot better
https://demo.woothemes.com/storefront/?s=dress&post_type=product
But for the above to work I would basically need to have a search input for “normal” searches and an input for “product searches”, which obviously isn’t ideal.
So if you could instead edit your search results page to handle different custom post types with different layouts, that would be a huge benefit to many WordPress users, especially store owners.
I don’t know how to do that myself today, and I honestly haven’t been able to find a lot of info about it online either, so I think this would be a great topic for you to cover – thanks!