Usage
PHP
related_posts($post_id, $args)
Parameters
$post_id
(Required) (int) The post ID to find related posts of
Default: None
$args
(Optional) (array) An array of additional options
Default: None
Parameter Notes
Options for the $args array:
taxonomy
Default: post_tag
post_type
Default: array('post')
max
Default: 5
Examples
PHP
<h4>Related Posts</h4> <?php $related_posts = nebula()->related_posts(get_the_id()); ?> <?php if ( $related_posts->have_posts() ): ?> <ul> <?php while ( $related_posts->have_posts() ): ?> <?php $related_posts->the_post(); ?> <li><a href="<?php the_permalink();?>"><h2><?php the_title();?></h2></a></li> <?php endwhile; ?> <?php wp_reset_postdata(); ?> </ul> <?php endif; ?>
Additional Notes
Results are stored in a transient for 24 hours for optimization.
Source File
Located in /libs/Functions.php on line 1832.
No Hooks
This function does not have any filters or actions available. Request one?
PHP
public function related_posts($post_id=null, $args=array()){ $this->timer('Related Posts'); global $post, $wpdb; $post_id = intval($post_id); if ( !$post_id && $post->ID ){ $post_id = $post->ID; } if ( !$post_id ){ return false; //Post ID is required for this function } $defaults = array( 'taxonomy' => 'post_tag', 'post_type' => array('post'), 'max' => 5 ); $options = wp_parse_args($args, $defaults); $related_post_ids = nebula()->transient('nebula-related-' . $options['taxonomy'] . '-' . $post_id, function($data){ $term_args = array( 'fields' => 'ids', 'orderby' => 'count', //Sort by frequency 'order' => 'ASC' //Least popular to most popular ); $orig_terms_set = wp_get_object_terms($data['post_id'], $data['options']['taxonomy'], $term_args); $orig_terms_set = array_map('intval', $orig_terms_set); //Make sure each returned term id to be an integer. $terms_to_iterate = $orig_terms_set; //Store a copy that we'll be reducing by one item for each iteration. $post_args = array( 'fields' => 'ids', 'post_type' => $data['options']['post_type'], 'post__not_in' => array($data['post_id']), 'posts_per_page' => 50 //Start with more than enough posts ); $related_post_ids = array(); //Loop through the terms to find posts that contain multiple terms (term1 AND term2 AND term3) while ( count($terms_to_iterate) > 1 ){ $post_args['tax_query'] = array( array( 'taxonomy' => $data['options']['taxonomy'], 'field' => 'id', 'terms' => $terms_to_iterate, 'operator' => 'AND' ) ); $posts = get_posts($post_args); foreach( $posts as $id ){ $id = intval($id); if ( !in_array($id, $related_post_ids) ){ $related_post_ids[] = $id; } } array_pop($terms_to_iterate); //Remove the least related post ID } $post_args['posts_per_page'] = $data['options']['max']; //Reduce the number to our desired max $post_args['tax_query'] = array( array( 'taxonomy' => $data['options']['taxonomy'], 'field' => 'id', 'terms' => $orig_terms_set ) ); //Check for posts that contain any of the terms (to fill out the desired max) $posts = get_posts($post_args); foreach ( $posts as $count => $id ){ $id = intval($id); if ( !in_array($id, $related_post_ids) ){ $related_post_ids[] = $id; } if ( count($related_post_ids) > $data['options']['max'] ){ break; //We have enough related post IDs now, stop the loop. } } return $related_post_ids; }, array('options' => $options, 'post_id' => $post_id), DAY_IN_SECONDS); if ( !$related_post_ids ){ $this->timer('Related Posts', 'end'); return false; } //Query for the related post IDs $query_options = array( 'post__in' => $related_post_ids, 'orderby' => 'post__in', 'post_type' => $options['post_type'], 'posts_per_page' => min(array(count($related_post_ids), $options['max'])), ); $this->timer('Related Posts', 'end'); return new WP_Query($query_options); }
Override
This function can not be short-circuited with an override filter. Request one?