Related Items From the Same Category for Any Post Type
Shows up to three other items that share a category or tag below single custom post type entries, such as related recipes, services or case studies.
Opens WPIDE on
Code
// Post types that get related items, how many, and the heading.
$wpide_related_types = array( 'recipe', 'case_study', 'service' );
$wpide_related_count = 3;
$wpide_related_heading = 'You may also like';
add_filter( 'the_content', function ( $content ) use ( $wpide_related_types, $wpide_related_count, $wpide_related_heading ) {
if ( ! is_singular( $wpide_related_types ) || ! in_the_loop() || ! is_main_query() ) {
return $content;
}
$post = get_post();
$key = 'wpide_related_' . $post->ID . '_' . get_option( 'wpide_related_ver_' . $post->post_type, '1' );
$ids = get_transient( $key );
if ( false === $ids ) {
$tax_query = array( 'relation' => 'OR' );
foreach ( get_object_taxonomies( $post->post_type, 'objects' ) as $taxonomy ) {
if ( ! $taxonomy->public ) {
continue;
}
$terms = wp_get_object_terms( $post->ID, $taxonomy->name, array( 'fields' => 'ids' ) );
if ( $terms && ! is_wp_error( $terms ) ) {
$tax_query[] = array( 'taxonomy' => $taxonomy->name, 'terms' => $terms );
}
}
$ids = count( $tax_query ) > 1 ? get_posts( array(
'post_type' => $post->post_type,
'posts_per_page' => $wpide_related_count,
'post__not_in' => array( $post->ID ),
'tax_query' => $tax_query,
'fields' => 'ids',
'no_found_rows' => true,
) ) : array();
set_transient( $key, $ids, DAY_IN_SECONDS );
}
if ( ! $ids ) {
return $content;
}
$list = '';
foreach ( $ids as $id ) {
$list .= '<li><a href="' . esc_url( get_permalink( $id ) ) . '">' . esc_html( get_the_title( $id ) ) . '</a></li>';
}
return $content . '<nav class="related-items" aria-label="' . esc_attr( $wpide_related_heading ) . '"><h2>' . esc_html( $wpide_related_heading ) . '</h2><ul>' . $list . '</ul></nav>';
} );
add_action( 'clean_post_cache', function ( $post_id, $post ) use ( $wpide_related_types ) {
if ( $post && in_array( $post->post_type, $wpide_related_types, true ) ) {
update_option( 'wpide_related_ver_' . $post->post_type, (string) microtime( true ), false );
}
}, 10, 2 );
Notes
Set the post types and heading. Each list is cached for a day and refreshed when content of that type changes.
How to add this snippet
- Install WPIDE on your WordPress site (it is free) and open Code Snippets.
- Use snippet above adds it from the library in one click. Or copy the code into a new snippet with the same code type.
- It is added inactive: review the code and settings, then switch it on.