Hook of the Month: Customize Related Posts

Jetpack’s Related Posts module is a simple and easy way to add contextual posts your visitors might be interested in when they reach the end of a post on your website. To use this feature, go to your site’s Jetpack settings and enable the module. All the magic happens behind the scenes, on the WordPress.com cloud: Jetpack’s natural language search engine scans all of your posts, analyzes all their content based on several factors, and returns a list of related posts for each one of your posts.

Now that Jetpack has worked its magic1, let’s discover how to customize those related posts or how to customize their display on your site.

Related Cats

Replace one of the Related Posts by a custom result

Sometimes it might be useful to insert a specific post among the Related Posts returned for one post or more on your website.

You could use this to promote one of your posts by using it as the first related post appearing at the bottom of another popular post.

To use the jetpack_relatedposts_filter_hits filter, we’ll need 2 things:

  • The post ID of the post we want to insert into Related Posts.
  • If you want to insert that related post only for a specific post, you’ll need the ID of the post where you want to change the default list of Related Posts.
/**
 * Replace one of the Related Posts by a custom result
 *
 * @param array $hits Array of Post IDs returned by Jetpack.
 * @param string $post_id Post ID of the post for which we are retrieving Related Posts.
 *
 * @return array $hits Array of Post IDs used to build our list of Related Posts.
 */
function jeherve_inject_custom_related_post( $hits, $post_id ) {
    // '2194' is the post we are currently getting related posts for
    if ( 2194 == $post_id ) {
        // Add post ID '1036' to the front of our default list of related posts.
        array_unshift( $hits, array( 'id' => 1036 ) );
        // Remove the last element of the list, so we keep the same amount of related posts in total.
        array_pop( $hits );
    }
    return $hits;
}
add_filter( 'jetpack_relatedposts_filter_hits', 'jeherve_inject_custom_related_post', 20, 2 );

Add Related Posts to your RSS feed

Jetpack displays Related Posts at the bottom of single posts by default. You can also use the raw Jetpack Related Posts class to build our own list of Related Posts. This class can be very useful, as you’re then in full control of the output, and you’ll be able to display it anywhere. In the example below, we’ll add that list to the bottom of the post content in RSS feeds.

/**
 * Add Jetpack Related Posts to RSS feed.
 *
 * @param string $content Post content.
 *
 * @return string $content Post content.
 */
function jeherve_related_posts_feed( $content ) {
    // Return early if we're not in the RSS feed.
    if ( ! is_feed() ) {
        return $content;
    }

    // If Jetpack and Related Posts are active, let's get started.
    if ( class_exists( 'Jetpack_RelatedPosts' ) && method_exists( 'Jetpack_RelatedPosts', 'init_raw' ) ) {
        // Use the raw class to get 3 related posts.
        $related = Jetpack_RelatedPosts::init_raw()
            ->set_query_name( 'jetpackme-shortcode' ) // Optional, name can be anything
            ->get_for_post_id(
                get_the_ID(),
                array( 'size' => 3 )
            );

        if ( $related ) {
            $related_list = '';

            foreach ( $related as $result ) {
                // Get the related post IDs
                $related_post_id = get_post( $result[ 'id' ] );

                /**
                 * From there you can do just about anything, using the post IDs.
                 *
                 * In this example, we'll build an unordered list.
                 */
                $related_list .= sprintf(
                    '
	<li><a title="%1$s" href="%2$s">%3$s</a></li>
',
                    esc_attr( get_the_title( $related_post_id ) ),
                    get_permalink( $related_post_id ),
                    get_the_title( $related_post_id )
                );
            }

            /**
             * Let's wrap all those related posts in ul tags, and add that list to the end of our post content.
             *
             * We will also add a headline, but only if it was set to be displayed in your Jetpack Related Posts settings.
             */
            $related_options = Jetpack_Options::get_option( 'relatedposts' );
            if ( $related_options['show_headline'] ) {
                $headline = sprintf(
                    '
<h3 class="jp-relatedposts-headline"><em>%s</em></h3>
',
                    esc_html__( 'Related', 'jetpack' )
                );
            } else {
                $headline = '';
            }

            return sprintf(
                '%1$s%2$s
<ul class="jp-relatedposts">%3$s</ul>
',
                $content,
                apply_filters( 'jetpack_relatedposts_filter_headline', $headline ),
                $related_list
            );
        }

        return $content;
    }

    // Last fallback, just in case Jetpack and Related Posts aren't there anymore.
    return $content;
}
add_filter( 'the_content', 'jeherve_related_posts_feed' );

Display the post author’s name below each Related Post

By default, Jetpack displays some extra information about each Related Post below the post title: the category it belongs to and the tags it uses. This information is good to display to your readers as it helps them decide whether they might be interested in the related post or not.

Display the post author after the existing Related Posts context.

What you may not know is that you could add some extra context there. If multiple authors publish on your site, it could be useful to display the name of the author below each post, so readers can pick posts from their favorite author.

To do that, we’ll use the jetpack_relatedposts_filter_post_context filter, like so:

/**
 * Display the post author after the existing Related Posts context.
 *
 * @param string $context Context displayed below each related post.
 * @param string $post_id Post ID of the post for which we are retrieving Related Posts.
 *
 * @return string $context Context, including information about the post author.
 */
function jeherve_related_authors( $context, $post_id ) {
    // Get the author ID.
    $post_author = get_post_field( 'post_author', $post_id );

    // Get the author's display name.
    $author_display_name = get_the_author_meta( 'display_name', $post_author );

    // Add the author name after the existing context.
    if ( isset( $author_display_name ) && ! empty( $author_display_name ) ) {
        return sprintf(
            __( '%1$s<span class="jp-relatedposts-post-author">By %2$s</span>', 'my-plugin-slug' ),
            $context,
            esc_html( $author_display_name )
        );
    }

    // Final fallback.
    return $context;
}
add_filter( 'jetpack_relatedposts_filter_post_context', 'jeherve_related_authors', 10, 2 );

You could also use that filter not to display any information below the related posts, like so:

add_filter( 'jetpack_relatedposts_filter_post_context', '__return_empty_string' );

That’s it for this month! If you’re interested in Jetpack Related Posts, I’d recommend checking our support documentation to discover some more filters you could use. You can also browse our code reference to discover all the other Jetpack hooks.


1. Do you want to learn more about the tools used to calculate Related Posts for your site? Read about Elasticsearch and how it runs on the WordPress.com cloud here. ↩

This entry was posted in Code snippets, Tips & Tricks and tagged , , , , . Bookmark the permalink.

Comments

  1. hearvox says:

    Is there a check to see if the hook-inserted ID is already in the $hits array, to prevent that related post from listing twice?

    Like

    • Jeremy says:

      You can use array_unique to remove any duplicates from your array of $hits. This way you’ll be sure that Related Posts are only displayed once.

      Like

      • hearvox says:

        Will do. Was just wondering if there was an `array_unique` check in Jetpack processing after this hook. Sounds like there isn’t so will do it on my end. Thanks, Jeremy.

        Like

  2. Donncha says:

    Thanks, I enabled it on both of my main blogs 🙂

    Like

Say Hello to 200 Themes

Jetpack Professional now bundles 200+ Premium WordPress themes,
alongside business class security tools, and marketing automation.

Use code "PRO" at checkout for 50% introductory discount.

%d bloggers like this: