Skip to content

Instantly share code, notes, and snippets.

@gormus
Created October 6, 2019 21:26
Show Gist options
  • Save gormus/eba94c851d494969de73a2ac12491a93 to your computer and use it in GitHub Desktop.
Save gormus/eba94c851d494969de73a2ac12491a93 to your computer and use it in GitHub Desktop.
WordPress Widget for recent posts.
<?php
/*
Plugin Name: Cake - Recent Posts Widget
Version: 1.0.0
Plugin URI: https://gorm.us/wordpress/plugins/recent-posts
Description: A widget to display recent posts.
Author: Osman Gormus
Author URI: https://gorm.us
*/
add_action('widgets_init', 'cake_recent_posts_init');
/**
* Initiate the widget.
*/
function cake_recent_posts_init() {
register_widget('cake_recent_posts');
}
/**
* Default arguments.
*/
function cake_recent_posts_default_args() {
$defaults = [
'title' => esc_attr__('Recent Posts', 'cake-recent-posts'),
'title_url' => '',
'template' => '',
'limit' => 5,
'offset' => 0,
'order' => 'DESC',
'orderby' => 'date',
'taxonomy' => '',
'post_type' => ['post'],
'post_status' => 'publish',
'ignore_sticky' => 1,
'exclude_current' => 1,
'css_class' => '',
'before' => '',
'after' => '',
];
// Allow plugins/themes developer to filter the default arguments.
return apply_filters('cake_recent_posts_defaults', $defaults);
}
/**
* Get posts.
*/
function cake_recent_posts_get_posts($args = []) {
// Query arguments.
$query = [
'offset' => $args['offset'],
'posts_per_page' => $args['limit'],
'orderby' => $args['orderby'],
'order' => $args['order'],
'post_type' => $args['post_type'],
'post_status' => 'publish',
'ignore_sticky_posts' => $args['ignore_sticky'],
];
// Exclude current post.
if ($args['exclude_current']) {
$query['post__not_in'] = [get_the_ID()];
}
// Limit posts based on category.
if (!empty($args['cat'])) {
$query['category__in'] = $args['cat'];
}
// Limit posts based on post tag.
if (!empty($args['tag'])) {
$query['tag__in'] = $args['tag'];
}
/**
* Taxonomy query.
* Prop Miniloop plugin by Kailey Lampert.
*/
if (!empty($args['taxonomy'])) {
parse_str($args['taxonomy'], $taxes);
$operator = 'IN';
$tax_query = [];
foreach (array_keys($taxes) as $k => $slug) {
$ids = explode(',', $taxes[$slug]);
if (count($ids) == 1 && $ids['0'] < 0) {
// If there is only one id given, and it's negative
// Let's treat it as 'posts not in'
$ids['0'] = $ids['0'] * -1;
$operator = 'NOT IN';
}
$tax_query[] = [
'taxonomy' => $slug,
'field' => 'id',
'terms' => $ids,
'operator' => $operator
];
}
$query['tax_query'] = $tax_query;
}
// Allow plugins/themes developer to filter the default query.
$query = apply_filters('cake_recent_posts_default_query_arguments', $query);
// Perform the query.
$posts_query = new WP_Query($query);
if ($posts_query->have_posts()) {
$template = isset($args['template']) ? $args['template'] : 'template-parts/content/content';
while ($posts_query->have_posts()) {
$posts_query->the_post();
get_template_part($template);
}
}
wp_reset_postdata();
}
class cake_recent_posts extends WP_Widget {
public function __construct() {
$widget_details = [
'classname' => 'cake_recent_posts',
'description' => 'An advanced widget that gives you total control over the output of your site’s most recent Posts.'
];
parent::__construct('cake_recent_posts', 'Cake Recent Posts', $widget_details);
}
public function form($args) {
$args = wp_parse_args((array) $args, cake_recent_posts_default_args());
extract($args);
include('widget_form.php');
}
public function update($new_instance, $old_instance) {
return $new_instance;
}
public function widget($instance, $args) {
$args = wp_parse_args($args, cake_recent_posts_default_args());
extract($args);
cake_recent_posts_get_posts($args);
}
}
<p>
<label for="<?php echo $this->get_field_id('title'); ?>">
<?php _e('Title', 'cake-recent-posts'); ?>
</label>
<input class="widefat" id="<?php echo $this->get_field_id('title'); ?>" name="<?php echo $this->get_field_name('title'); ?>" type="text" value="<?php echo esc_attr($args['title']); ?>">
</p>
<div>
<label>
<?php _e('Post types', 'cake-recent-posts'); ?>
</label>
<ul>
<?php foreach (get_post_types(array('public' => true), 'objects') as $type) : ?>
<li>
<input type="checkbox" value="<?php echo esc_attr($type->name); ?>" id="<?php echo $this->get_field_id('post_type') . '-' . $type->name; ?>" name="<?php echo $this->get_field_name('post_type'); ?>[]" <?php checked(is_array($args['post_type']) && in_array($type->name, $args['post_type'])); ?>>
<label for="<?php echo $this->get_field_id('post_type') . '-' . $type->name; ?>">
<?php echo esc_html($type->labels->name); ?>
</label>
</li>
<?php endforeach; ?>
</ul>
</div>
<p>
<label for="<?php echo $this->get_field_id('order'); ?>">
<?php _e('Order', 'cake-recent-posts'); ?>
</label>
<select class="widefat" id="<?php echo $this->get_field_id('order'); ?>" name="<?php echo $this->get_field_name('order'); ?>">
<option value="DESC" <?php selected($args['order'], 'DESC'); ?>><?php _e('Descending', 'rpwe') ?></option>
<option value="ASC" <?php selected($args['order'], 'ASC'); ?>><?php _e('Ascending', 'rpwe') ?></option>
</select>
</p>
<p>
<label for="<?php echo $this->get_field_id('orderby'); ?>">
<?php _e('Orderby', 'cake-recent-posts'); ?>
</label>
<select class="widefat" id="<?php echo $this->get_field_id('orderby'); ?>" name="<?php echo $this->get_field_name('orderby'); ?>">
<option value="ID" <?php selected($args['orderby'], 'ID'); ?>><?php _e('ID', 'rpwe') ?></option>
<option value="author" <?php selected($args['orderby'], 'author'); ?>><?php _e('Author', 'rpwe') ?></option>
<option value="title" <?php selected($args['orderby'], 'title'); ?>><?php _e('Title', 'rpwe') ?></option>
<option value="date" <?php selected($args['orderby'], 'date'); ?>><?php _e('Date', 'rpwe') ?></option>
<option value="modified" <?php selected($args['orderby'], 'modified'); ?>><?php _e('Modified', 'rpwe') ?></option>
<option value="rand" <?php selected($args['orderby'], 'rand'); ?>><?php _e('Random', 'rpwe') ?></option>
<option value="comment_count" <?php selected($args['orderby'], 'comment_count'); ?>><?php _e('Comment Count', 'rpwe') ?></option>
<option value="menu_order" <?php selected($args['orderby'], 'menu_order'); ?>><?php _e('Menu Order', 'rpwe') ?></option>
</select>
</p>
<p>
<label for="<?php echo $this->get_field_id('limit'); ?>">
<?php _e('Number of posts to show', 'cake-recent-posts'); ?>
</label>
<input class="widefat" id="<?php echo $this->get_field_id('limit'); ?>" name="<?php echo $this->get_field_name('limit'); ?>" type="number" step="1" min="-1" value="<?php echo (int) ($args['limit']); ?>">
</p>
<p>
<label for="<?php echo $this->get_field_id('offset'); ?>">
<?php _e('Offset', 'cake-recent-posts'); ?>
</label>
<input class="widefat" id="<?php echo $this->get_field_id('offset'); ?>" name="<?php echo $this->get_field_name('offset'); ?>" type="number" step="1" min="0" value="<?php echo (int) ($args['offset']); ?>">
<small><?php _e('The number of posts to skip', 'cake-recent-posts'); ?></small>
</p>
<p>
<input class="checkbox" type="checkbox" <?php checked($args['exclude_current'], 1); ?> id="<?php echo $this->get_field_id('exclude_current'); ?>" name="<?php echo $this->get_field_name('exclude_current'); ?>">
<label for="<?php echo $this->get_field_id('exclude_current'); ?>">
<?php _e('Exclude current post', 'cake-recent-posts'); ?>
</label>
</p>
<p>
<input class="checkbox" type="checkbox" <?php checked($args['ignore_sticky'], 1); ?> id="<?php echo $this->get_field_id('ignore_sticky'); ?>" name="<?php echo $this->get_field_name('ignore_sticky'); ?>" />
<label for="<?php echo $this->get_field_id('ignore_sticky'); ?>">
<?php _e('Ignore sticky posts', 'cake-recent-posts'); ?>
</label>
</p>
<p>
<label for="<?php echo $this->get_field_id('template'); ?>">
<?php _e('Template', 'cake-recent-posts'); ?>
</label>
<input class="widefat" id="<?php echo $this->get_field_id('template'); ?>" name="<?php echo $this->get_field_name('template'); ?>" type="text" value="<?php echo $args['template']; ?>" placeholder="template-parts/content/content">
<small><?php _e('Customize the output of each post via a template.<br>See <code>get_template_part()</code>', 'cake-recent-posts'); ?></small>
</p>
<p>
<label for="<?php echo $this->get_field_id('taxonomy'); ?>">
<?php _e('Limit to Taxonomy', 'cake-recent-posts'); ?>
</label>
<input type="text" class="widefat" id="<?php echo $this->get_field_id('taxonomy'); ?>" name="<?php echo $this->get_field_name('taxonomy'); ?>" value="<?php echo esc_attr($args['taxonomy']); ?>">
<small><?php _e('Ex: category=1,2,4&amp;post_tag=6,12', 'cake-recent-posts'); ?><br />
<?php _e('Available: ', 'cake-recent-posts');
echo implode(', ', get_taxonomies(array('public' => true))); ?></small>
</p>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment