SearchWP is an advanced search plugin that greatly improves WP core search.

FacetWP includes built-in integration with SearchWP.

Buy SearchWP

Why SearchWP?

By default, WP core search is very basic. It searches only titles and the content field for matches, and has no understanding of relevancy.

SearchWP returns relevant results. It’s also highly configurable, allowing you to search through custom fields, post data, taxonomies, eCommerce data, and even PDFs.

SearchWP also supports custom engines, essentially letting you create different searches to include subsets of data. This is super helpful when combined with a Search facet (so you can search specific fields).

The SearchWP engine settings interface.
The SearchWP engine settings interface.

Setup

How to select a SearchWP engine in the Search facet settings.
How to select a SearchWP engine in the Search facet settings.

FacetWP has built-in integration with SearchWP.

When SearchWP is installed, your Search facets will show your SearchWP engines under the “Search engine” setting. Simply choose the desired SearchWP search engine from the dropdown.

SearchWP limits

For large sites, keep in mind that SearchWP has a much lower maximum post limit than FacetWP itself, because all the advanced features and extra calculations SearchWP is doing behind the scenes require more server resources.

SearchWP works best on a site with anywhere from a few posts to a few thousand. If your website has tens of thousands of posts or even hundreds of thousands, SearchWP does recommend not using it (see their FAQ).

Remove the post limit

By default, FacetWP fetches a maximum of 200 results from SearchWP. To remove this limit, use the following code:

SearchWP 4.x

How to use custom PHP code?

PHP code can be added to your (child) theme's functions.php file. Alternatively, you can use the Custom Hooks add-on, or a code snippets plugin. More info

add_filter( 'searchwp\swp_query\args', function( $args ) { if ( isset( $args['facetwp'] ) ) { $args['posts_per_page'] = -1; } return $args; } );

SearchWP 3.x

How to use custom PHP code?

PHP code can be added to your (child) theme's functions.php file. Alternatively, you can use the Custom Hooks add-on, or a code snippets plugin. More info

add_filter( 'searchwp_swp_query_args', function( $args ) { if ( isset( $args['facetwp'] ) ) { $args['posts_per_page'] = -1; } return $args; } );

Prevent FacetWP interference with the search query on search result pages with no facets

If you are using FacetWP together with SearchWP, and your search results page (the page with /?s=searchterm in the URL) does not have facets, the search will not work properly: most often it will show no results, or other unexpected query interference may happen, like a different order of results than expected.

This is caused by FacetWP’s built-in integration having to intercept the search query before it can know if facets are being used on the page. To fix this issue, you have to disable FacetWP for the search results page only, by adding the following code to your (child) theme’s functions.php:

How to use custom PHP code?

PHP code can be added to your (child) theme's functions.php file. Alternatively, you can use the Custom Hooks add-on, or a code snippets plugin. More info

add_filter( 'facetwp_is_main_query', function( $is_main_query, $query ) { if ( $query->is_search() && $query->is_main_query() ) { $is_main_query = false; } return $is_main_query; }, 5, 2 );

Use SearchWP on the WooCommerce search results page

If you are using FacetWP together with SearchWP and WooCommerce, the WooCommerce search results page will not work well out of the box. WooCommerce uses a special post type archive template for its search results page, which has the “product” post type in the URL, like this:

/?s=searchterm&post_type=product

This search results template behaves differently from the normal WP results page (which does not have &post_type=product in the URL).

The WooCommerce Integration SearchWP extension needs to be installed for SearchWP (and FacetWP) to work well together on this WooCommerce search results page. (It requires a SearchWP Pro license).

Without this extension active, when FacetWP is installed, a WooCommerce search will return no posts for keywords that are indexed by SearchWP, like keywords in custom fields, partial matches etc. Confusingly, searching for keywords that return results in a normal WP search, like keywords from post titles, will work okay.

Note that if you are not using the built-in WooCommerce search results page, the extension is not needed. You can use WP’s normal search results page (without &post_type=product in the URL) with FacetWP and SearchWP without issues.

Fix SearchWP and Woocomerce integration on the default search page

If you are using FacetWP with WooCommerce, SearchWP and the SearchWP WooCommerce Integration add-on, you’ll encounter issues with products not showing up in the search results on the default product search results page (the page with /?s=searchterm&post_type=product in the URL).

This issue can be solved by adding the following snippet to your (child) theme’s functions.php:

How to use custom PHP code?

PHP code can be added to your (child) theme's functions.php file. Alternatively, you can use the Custom Hooks add-on, or a code snippets plugin. More info

add_filter( 'facetwp_is_main_query', function( $is_main_query, $query ) { if ( $is_main_query && $query->is_main_query() && $query->is_search() ) { if ( true == $query->get( 'wc_query' ) ) { $query->set( 'using_searchwp', '' ); } } return $is_main_query; }, 11, 2);

We are researching a more definitive fix, which will be included in a future update.

Use SearchWP with WPML or Polylang

If you are using SearchWP together with WPML or Polylang, make sure to:

  1. Install the Multilingual add-on
  2. Install the appropriate SearchWP integration extension:

The above SearchWP extensions will limit search results to the active language of the page. Without them, there will be a disconnect between the facets, their counts, and the post listing.

Search (in) attachments/media/PDFs

By default, FacetWP only indexes, displays and filters “published” items, meaning posts that have their post_status set to publish. This excludes attachments (like media and PDFs), which are posts that have their post_status automatically set to inherit.

Index attachments

By using the facetwp_indexer_query_args hook, it is possible to force FacetWP to index the attachment post type for all facets.

Add the code following to your (child) theme’s functions.php, and then click the re-index button:

How to use custom PHP code?

PHP code can be added to your (child) theme's functions.php file. Alternatively, you can use the Custom Hooks add-on, or a code snippets plugin. More info

add_filter( 'facetwp_indexer_query_args', function( $args ) { $args['post_status'] = [ 'publish', 'inherit' ]; return $args; });

Note: this is not needed if you are using only a Search facet (and no other facets) on your page, because FacetWP does not index anything for Search facets. A Search facet will retrieve attachments as results as long as they are in the listing query and in your SearchWP engine’s indexed sources.

Display attachments

To display attachments in your query, you’ll need to add the attachment post type to the post_type argument, and inherit to the post_status argument of your listing query. In a custom WP_Query this would like this:

How to use custom PHP code?

PHP code can be added to your (child) theme's functions.php file. Alternatively, you can use the Custom Hooks add-on, or a code snippets plugin. More info

$args = [ 'post_type' => [ 'post', 'attachment' ], // retrieve posts and attachments 'post_status' => [ 'publish', 'inherit' ], // add 'inherit' post status for attachments 'posts_per_page' => 10, 'orderby' => [ 'title' => 'ASC' ], 'facetwp' => true ]; $my_query = new WP_Query( $args );

In a Listing Builder listing, the same query would look as follows. Note that attachments are called ‘Media’ in the Listing Builder settings:

A Listing Builder query retrieving posts and attachments, with Post Status 'inherit' added for attachments. Attachments are called 'Media' in the Listing Builder settings.
A Listing Builder query retrieving posts and attachments, with Post Status ‘inherit’ added for attachments. Note that attachments are called ‘Media’ in the Listing Builder settings.

Display attachments only

If you want to retrieve only attachments/media/PDFs, using post_type => attachment and post_status => inherit is enough:

How to use custom PHP code?

PHP code can be added to your (child) theme's functions.php file. Alternatively, you can use the Custom Hooks add-on, or a code snippets plugin. More info

$args = [ 'post_type' => 'attachment', // retrieve attachments only 'post_status' => 'inherit', // add 'inherit' post status for attachments 'posts_per_page' => 10, 'orderby' => ['title' => 'ASC'], 'facetwp' => true ]; $my_query = new WP_Query( $args );

If you use any other facets than a Search facet, make sure to also let FacetWP index attachments.

Search content within attachments/PDFs

To search for content within attachments/PDFs with a Search facet that has its engine set to a SearchWP engine, you only need to retrieve attachments in your listing query.

FacetWP does not index anything for Search facets, so if you only have a Search facet on your page, this is enough to enable searching within attachments/PDFs. However, when you have other facets on the page besides a Search facet, you’ll need to also force FacetWP to index attachments.

The Transfer Weight To Media Parent setting

SearchWP has a “Transfer Weight” setting for engine sources. When this setting is enabled for the “Media” source, and is set to “To Media Parent”, all relevance weight of an attachment is transferred to the attachment’s parent post (the post to which the attachment was uploaded).

SeachWP's Transfer Weight - To Media Parent setting.
SeachWP’s Transfer Weight – To Media Parent setting.

With this setting enabled, if you use a Search facet (set to use this engine) to search for content within attachments/PDFs, the returned results will not be the attachments/PDFs themselves, but the parent post to which they have been attached.

So if you use this setting, attachments/PDFs need to have a parent post, which means they have to be uploaded from a post edit screen. Also, the listing query needs to include those parent posts’ post_type.

Counterintuitively, this setup will not work with only the parent post type in the query argument. The query needs to also include the attachment post type and the inherit post status, as shown in the query examples above.

The above means you can’t use this setup to search attachments/PDF’s and retrieve parent posts only, without the attachments/PDFs themselves showing up in your listing. If you don’t want the attachments/PDFs in your listing, but only the parent posts, there is another solution:

Search PDFs without showing them directly in the listing

If you don’t want PDFs to be displayed directly in your listing, but still want to search through
their contents with a Search facet, it is possible to let SearchWP append the PDFs’ search data to their parent posts.

With the following code (source) in place, you can have only the parent post type in your listing query. So when you search PDF content with a Search facet, only the PDFs’ parent posts will show up as results. You’ll never see the individual PDFs in the listing (before or after filtering), while still being able to search their content.

With this setup – obviously – don’t include the attachment post type in your listing query. Also, there is no need to let FacetWP index attachments.

The code below needs to be added to your (child) theme’s functions.php, or to your SearchWP Customizations plugin. Before rebuilding the SearchWP index, scroll down for further setup instructions.

How to use custom PHP code?

PHP code can be added to your (child) theme's functions.php file. Alternatively, you can use the Custom Hooks add-on, or a code snippets plugin. More info

// Retrieve child PDF content and add as 'extra' data to a SearchWP Entry. // Source: https://searchwp.com/documentation/knowledge-base/append-document-content-to-parent-post-content/ add_filter( 'searchwp\entry\data', function( $data, \SearchWP\Entry $entry ) { // Convert the SearchWP Entry into it's native object type. $entry = $entry->native(); // We only want to consider WP_Post objects. if ( ! $entry instanceof \WP_Post ) { return $data; } // Retrieve PDFs that have been uploaded to this Entry. $pdfs = get_posts( [ 'post_type' => 'attachment', 'post_mime_type' => 'application/pdf', 'post_status' => 'inherit', 'nopaging' => true, 'post_parent' => $entry->ID, ] ); if ( empty( $pdfs ) ) { return $data; } // Retrieve PDF content for PDFs and store as extra data. $data['meta'][ 'searchwp_child_pdf_content' ] = array_map( function( $pdf ) { return \SearchWP\Document::get_content( $pdf ); }, $pdfs ); return $data; }, 20, 2 ); // Add "Attached PDF Content" as available option to SearchWP Source Attributes. add_filter( 'searchwp\source\attribute\options', function( $keys, $args ) { if ( $args['attribute'] !== 'meta' ) { return $keys; } // This key is the same as the one used in the searchwp\entry\data hook above, they must be the same. $pdf_content_key = 'searchwp_child_pdf_content'; // Add "Attached PDF Content" Option if it does not exist already. if ( ! in_array( $pdf_content_key, array_map( function( $option ) { return $option->get_value(); }, $keys ) ) ) { $keys[] = new \SearchWP\Option( $pdf_content_key, 'Attached PDF Content' ); } return $keys; }, 20, 2 );

The two hooks in above code tap into SearchWP’s indexing process for each post. The first hook will look for any PDFs that have been uploaded to each post (by using the post_parent relationship), and then parse the content in each of those PDFs. The content of all found “child” PDFs for a post will then be stored in a new custom field with the name searchwp_child_pdf_content.

The second hook will add this new custom field to the “Custom Fields” dropdown in the “Manage Post Attributes” popup that appears when clicking the “Add/Remove Attributes” button in the Source sections of your SearchWP engine.

Setup instructions
Step 1: Add the 'searchwp_child_pdf_content' custom field as post attribute.
Step 1: Add the ‘searchwp_child_pdf_content’ custom field as post attribute.
Step 2: Set relevance weight for the 'Attached PDF Content' Custom Field
Step 2: Set relevance weight for the “Attached PDF Content” Custom Field.

First, add the above code. Then follow these steps to complete the setup:

  1. Scroll to, and open your parent post type’s Source section (not the “Media” Source section). Click “Add/Remove Attributes”. In the popup, click the “Custom Fields” dropdown, then type “searchwp_child_pdf_content” and select this field. Click “Done” to save the field.
  2. Now you’ll see an “Attached PDF Content” item under the Custom Fields heading of your post type source. If desired, you can use the slider to set a higher relevance weight to content found in the attached child PDFs.
  3. Rebuild your SearchWP index by clicking the “Rebuild Index” button in the top right.

Now you can search for PDF content, and have only the PDFs’ parent posts show up as results.

Highlight Search facet search terms in Listing Builder templates

If you are using a Listing Builder template, and you have a Search facet on the page, you can use the facetwp_render_output hook to let SearchWP’s highlighter parse the template content and highlight the used search terms in the listing’s post title and content.

Make sure that your Search facet uses one of the SearchWP engines in the Search engine setting, and add the following snippet to your (child) theme’s functions.php:

How to use custom PHP code?

PHP code can be added to your (child) theme's functions.php file. Alternatively, you can use the Custom Hooks add-on, or a code snippets plugin. More info

add_filter( 'facetwp_render_output', function( $output, $params ) { $keywords = ''; if ( isset( FWP()->facet->facets['search'] ) ) { $keywords = FWP()->facet->facets['search']['selected_values']; $keywords = is_array( $keywords ) ? implode( ' ', $keywords ) : $keywords; } // SearchWP 4 if ( ! empty( $keywords ) && class_exists( '\SearchWP\Highlighter' ) ) { $highlighter = new \SearchWP\Highlighter(); $output['template'] = $highlighter->apply( $output['template'], $keywords ); } // Use this instead for SearchWP 3 // if ( ! empty( $keywords ) && class_exists( 'SearchWPHighlighter' ) ) { // $highlighter = new SearchWPHighlighter(); // $output['template'] = $highlighter->apply_highlight( $output['template'], $keywords ); // } return $output; }, 10, 2 );

Note that this snippet only works when uing a Search facet on a Listing Builder template.

Style the hightlighted search terms

SearchWP’s highlighter will wrap highlighted search terms in a <mark> element, with the class searchwp-highlight:

<mark class="searchwp-highlight">search terms</mark>

Browsers will render this element bright yellow by default. If you want to give the highlights another color, add the following CSS:

How to use custom PHP code?

PHP code can be added to your (child) theme's functions.php file. Alternatively, you can use the Custom Hooks add-on, or a code snippets plugin. More info

add_action( 'facetwp_scripts', function() { ?> <style> .searchwp-highlight { background: #ffa07a; /* light orange-red */ } </style> <?php }, 100 );

Debug SearchWP

SearchWP has its own debugging feature, which can be helpful to gain insight into exactly what SearchWP is doing. The “Debugging enabled” setting can be enable in: Settings > SearchWP > Advanced > Actions & Settings.

When debugging is enabled, a log file is created (one per day) in ~/wp-content/uploads/searchwp-logs/. It shows information about what SearchWP is doing as it indexes and performs searches.

Additionally, an HTML comment block will be output in the source of search results pages, showing information about searches that ran for that page’s request.

See also

Last updated: August 21, 2024