Skip to content

Instantly share code, notes, and snippets.

@ashucg
Created May 5, 2017 18:11
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ashucg/10bb443c3f66c87f3557d95e3625238e to your computer and use it in GitHub Desktop.
Save ashucg/10bb443c3f66c87f3557d95e3625238e to your computer and use it in GitHub Desktop.
WP class to create custom widget for displaying similar posts
<?php
class similar_posts_widget extends WP_Widget
{
function __construct()
{
parent::__construct('similar_posts_widget', __('Similar Posts', 'custom-slug'), [
'description' => __('Display similar post', 'custom-slug'),
]);
}
/**
* @param $instance
*/
public function form($instance)
{
/**
* Set default widget title and number of posts to display.
*/
$title = __('Similar Posts', 'custom-slug');
$number_of_posts = __('3', 'custom-slug');
if (isset($instance['title']))
{
$title = $instance['title'];
}
if (isset($instance['number_of_posts']))
{
$number_of_posts = $instance['number_of_posts'];
}
/**
* Output widget settings, allowing user to set custom Widget Title and Number of Posts.
*/
ob_start();
?>
<p>
<label for="<?=$this->get_field_id('title');?>"><?php _e('Title:');?></label>
<input id="<?=$this->get_field_id('title');?>" name="<?=$this->get_field_name('title');?>" type="text" value="<?=esc_attr($title);?>" />
<label for="<?=$this->get_field_id('number_of_posts');?>"><?php _e('Number Of Posts:');?></label>
<input id="<?=$this->get_field_id('number_of_posts');?>" name="<?=$this->get_field_name('number_of_posts');?>" type="number" value="<?=esc_attr($number_of_posts);?>" />
</p>
<?php
echo preg_replace('/\s{2,}/im', '', ob_get_clean()); // Remove extra spaces from the final HTML output.
}
/**
* @param $new_instance
* @param $old_instance
* @return mixed
*/
public function update($new_instance, $old_instance)
{
/**
* Remove any HTML tags from the user input and return the instance to be saved.
*/
$instance = [];
$instance['title'] = ( ! empty($new_instance['title'])) ? strip_tags($new_instance['title']) : '';
$instance['number_of_posts'] = ( ! empty($new_instance['number_of_posts'])) ? strip_tags($new_instance['number_of_posts']) : '';
return $instance;
}
/**
* @param $args
* @param $instance
*/
public function widget($args, $instance)
{
global $post;
$title = apply_filters('widget_title', $instance['title']);
/**
* Fetch the similar posts and output the results.
* You can change div to ul, either way you have write your own CSS.
*/
ob_start();
echo $args['before_widget'];
if ( ! empty($title))
{
echo $args['before_title'] . $title . $args['after_title'];
}
$tags = wp_get_post_tags($post->ID);
if ($tags)
{
$tag_ids = [];
foreach ($tags as $individual_tag)
{
$tag_ids[] = $individual_tag->term_id;
}
$wp_query = new WP_Query([
'tag__in' => $tag_ids,
'post__not_in' => [$post->ID],
'posts_per_page' => $instance['number_of_posts'],
'ignore_sticky_posts' => 1,
]);
?>
<div class="similar-posts">
<?php
while ($wp_query->have_posts())
{
$wp_query->the_post();
?>
<div class="similar-post">
<a href="<?=the_permalink();?>" rel="external"><?=get_the_title();?></a>
</div>
<?
}
?>
</div>
<?php
}
wp_reset_query();
echo $args['after_widget'];
echo preg_replace('/\s{2,}/im', '', ob_get_clean()); // Remove extra spaces from the final HTML output.
}
}
function wpb_load_widget()
{
register_widget('similar_posts_widget');
}
add_action('widgets_init', 'wpb_load_widget');
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment