Related Posts with SearchWP

We use SearchWP on almost all the websites we build. It provides search results based on relevancy rather than recency; indexes more attributes like categories, tags, and custom fields; and includes detailed reporting for on-site searches.

It’s also a great tool for related posts. Instead of showing recent posts in the same category or tag and hoping they are related to the current post, you can ask SearchWP for content that is actually related.

The Related Content extension adds a metabox for controlling the keywords used. By default it uses the current post’s title as the keyword, but you can modify it to include any keywords you like. It also displays live search results based on those keywords:

Displaying Related Posts

There are a few different ways to display the related posts:

  1. SearchWP can auto-append them to the bottom of your posts using their template.
  2. SearchWP can auto-append them to the bottom of your posts using your template, defined in your-theme/searchwp-related/related.php. Here’s more information on building your own template for their template loader.
  3. You define where they appear in your theme and use their template loader, either with their template or your custom template. Here’s a code example.
  4. You define where they appear in your theme and use your own custom query. This gives you the most flexibility over the query and display.

My Approach

I like to use #4 and then add a fallback in case SearchWP is ever disabled, or if the keyword search delivers less results than we want displayed.

I created a be_get_related_posts() function that queries for related using SearchWP Related. If we need more posts, we then query for recent posts in the same primary category using ea_first_term().

<?php
/**
* Get Related Posts
* @see https://www.billerickson.net/related-posts-with-searchwp/
*
*/
function ea_get_related_posts( $related_to_show = false ) {
$related_to_show = !empty( $related_to_show ) ? intval( $related_to_show ) : get_option( 'posts_per_page' );
$related = array();
// Use SearchWP
if( class_exists( 'SearchWP_Related' ) && count( $related ) < $related_to_show ) {
// Instantiate SearchWP Related
$searchwp_related = new SearchWP_Related();
// Use the keywords as defined in the SearchWP Related meta box
$keywords = get_post_meta( get_the_ID(), $searchwp_related->meta_key, true );
if( empty( $keywords ) )
$keywords = get_the_title();
$args = array(
's' => $keywords, // The stored keywords to use
'engine' => 'default', // the SearchWP engine to use
'posts_per_page' => $related_to_show - count( $related ),
'post__not_in' => array( get_the_ID() ),
'fields' => 'ids',
);
// Retrieve Related content for the current post
$swp_related = $searchwp_related->get( $args );
if( !empty( $swp_related ) ) {
$related = array_merge( $related, $swp_related );
}
}
// Fallback, use primary category
if( count( $related ) < $related_to_show ) {
$loop = new WP_Query( array(
'posts_per_page' => $related_to_show - count( $related ),
'category_name' => ea_first_term( 'category', 'slug' ),
'post__not_in' => array_merge( $related, array( get_the_ID() ) ),
'fields' => 'ids',
));
if( ! is_wp_error( $loop ) && !empty( $loop->posts ) )
$related = array_merge( $related, $loop->posts );
}
return $related;
}
view raw single.php hosted with ❤ by GitHub

Then I create a function to display the related posts. We use template parts for reusable blocks of code like post summaries. This allows us to use the same format for listings on archive pages, post listings on landing pages, and related posts on single posts.

<?php
/**
* Related Posts
* @see https://www.billerickson.net/related-posts-with-searchwp/
*
*/
function be_related_posts() {
$related = ea_get_related_posts( 3 );
if( empty( $related ) )
return;
$loop = new WP_Query( array(
'post__in' => $related,
'orderby' => 'post__in',
) );
if( $loop->have_posts() ):
echo '<section class="related-posts">';
echo '<h3>Related Posts</h3>';
while( $loop->have_posts() ): $loop->the_post();
get_template_part( 'partials/archive', 'related' );
endwhile;
echo '</section>';
endif;
wp_reset_postdata();
}
add_action( 'genesis_after_entry', 'be_related_posts' );
view raw single.php hosted with ❤ by GitHub

Bill Erickson

Bill Erickson is a freelance WordPress developer and a contributing developer to the Genesis framework. For the past 14 years he has worked with attorneys, publishers, corporations, and non-profits, building custom websites tailored to their needs and goals.

Ready to upgrade your website?

I build custom WordPress websites that look great and are easy to manage.

Let's Talk

Reader Interactions

Comments

  1. Thanks Bill. I didn’t yet know the plugin and will certainly try it out.

    Small error: the link on “template parts” above doesn’t work (it contains 2 URLs concatenated).

    Cheers,
    Hans

Leave A Reply