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 2038.
No Hooks
This function does not have any filters or actions available. Request one?
PHP
public function related_posts($post_id=null, $args=array()){
if ( $this->is_minimal_mode() ){return null;}
$this->timer('Related Posts', 'start', '[Nebula] Search');
global $post, $wpdb;
$post_id = intval($post_id);
if ( !$post_id && $post->ID ){
$post_id = $post->ID;
}
if ( !$post_id ){
return null; //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 null;
}
//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?