WordPressで関連記事や人気記事を表示させるときに、あまりにも古い記事は表示させたくないなぁと思いまして、指定した日数までの記事を表示させられるようにごにょごにょしています。 その辺りをウィジェットにしてみました。が、細かいところの仕様だとかコレでいいのか?な部分があるので、まだまだブラッシュアップが必要だなぁと思うところ。 現状のソースを公開してみようと踏み切りました。

ウィジェットの説明

ウィジェットの設定画面はこんな感じです。
オプションも充実
管理画面から条件を変えられます
「現在より6ヶ月前から10件を表示」といった具合に簡単に期間が指定できます。 呼び出す順序も投稿日時順や更新日時順、JetPack Post ViewsとWP-Post viewsの閲覧数順にも対応しています。

ソース

ちょっと長いですがfunctions.phpへバーンと貼り付ければ、ウィジェット対応のテンプレートで利用できます。たぶん。
class TimeRangePosts extends WP_Widget {
	private static $default_range = 2;
	private static $default_unit = '週前';
	private static $default_num = 5;
	
	function TimeRangePosts() {
		parent::WP_Widget(false, $name = '期間内の投稿');
	}
	function widget($args, $instance) {
		if (!is_user_logged_in()) return;
		extract( $args );
		$title = apply_filters( 'widget_title', $instance['title'] );
		$range = apply_filters( 'widget_range', $instance['range'] );
		$unit = apply_filters( 'widget_unit', $instance['unit'] );
		$num = apply_filters( 'widget_num', $instance['num'] );
		$orderby = apply_filters( 'widget_orderby', $instance['orderby'] );
		$order = apply_filters( 'widget_order', $instance['order'] );
		$un = 'day';
		if(empty($range) || !preg_match('/^\d+$/',$range)) $range = self::$default_range;
		if(empty($unit)) $unit = self::$default_unit;
		if(empty($num) || !preg_match('/^\d+$/',$num)) $num = self::$default_num;
		if($unit=='年前') $un = 'year';
		elseif($unit=='ヶ月前') $un = 'month';
		elseif($unit=='週前') $un = 'week';
		
		echo '<div class="TimeRangePosts">';
		$args = array(
			'showposts'		=> $num,
			'post_type'		=> 'post',
			'suppress_filters' => false
		);
		if($orderby == '更新日時') {
			$args = array_merge($args, array(
				'orderby'		=> 'modified'
			));
		} elseif($orderby == 'ランダム') {
			$args = array_merge($args, array(
				'orderby'		=> 'rand'
			));
		} elseif(function_exists('JPV_display_top_posts') && $orderby == 'Jetpack Post Views') {
			// Jetpack Post Views(プラグイン有効時)
			$args = array_merge($args, array(
				'orderby'		=> 'meta_value_num',
				'meta_key'		=> 'jetpack-post-views'
			));
		} elseif(function_exists('get_most_viewed') && $orderby == 'WP-Post Views') {
			// WP-Post Views(プラグイン有効時)
			$args = array_merge($args, array(
				'orderby'		=> 'meta_value_num',
				'meta_key'		=> 'views'
			));
		} else {
			$args = array_merge($args, array(
				'orderby'		=> 'post_date'
			));
		}
		// 昇順/降順
		if(empty($order)) {
			$args = array_merge($args, array(
				'order'		=> 'DESC'
			));
		} else {
			$args = array_merge($args, array(
				'order'		=> 'ASC'
			));
		}
		$beforeNday = create_function('$where = ""', 'global $wpdb;$where .= $wpdb->prepare(" AND post_date > %s", date("Y-m-d", strtotime("-'.$range.' '.$un.'")));return $where;');
		add_filter( 'posts_where', $beforeNday);
		$posts = get_posts($args);
		echo(!empty($title))?'<h3>'.$title.'</h3>':'';
		echo '<ul>';
		foreach( $posts as $post ): setup_postdata( $post );
		echo '<li><a href="'.get_permalink($post->ID).'">'.$post->post_title.'</a></li>';
		endforeach;
		echo '</ul>';
		wp_reset_postdata();
		remove_filter('posts_where', $beforeNday);
		echo '</div>';
	}
	function update($new_instance, $old_instance) {
		$instance = $old_instance;
		$instance['title'] = strip_tags($new_instance['title']);
		$instance['range'] = trim($new_instance['range']);
		$instance['unit'] = trim($new_instance['unit']);
		$instance['num'] = trim($new_instance['num']);
		$instance['orderby'] = trim($new_instance['orderby']);
		$instance['order'] = trim($new_instance['order']);
		return $instance;
	}
	function form($instance) {
		$title = esc_attr($instance['title']);
		$range = esc_attr($instance['range']);
		$unit = esc_attr($instance['unit']);
		$num = esc_attr($instance['num']);
		$orderby = esc_attr($instance['orderby']);
		$order = esc_attr($instance['order']);
		if(empty($range) || !preg_match('/^\d+$/',$range)) $range = self::$default_range;
		if(empty($num)) $num = self::$default_num;
		if(empty($unit)) $unit = self::$default_unit;
?>
<p>
<label for="<?php echo $this->get_field_id('title'); ?>"><?php _e('見出し'); ?></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 $title; ?>" />
</p>
<p>
<label for="<?php echo $this->get_field_id('range'); ?>"><?php _e('期間の指定:'); ?></label><br />
<select id="<?php echo $this->get_field_id('range'); ?>" name="<?php echo $this->get_field_name('range'); ?>" style="width:3em;">
<?php
$arr = array(1,2,3,4,5,6);
foreach($arr as $r) {
	echo ($r==$range)?'<option selected="selected">'.$r.'</option>':'<option>'.$r.'</option>';
}
?></select>
<select id="<?php echo $this->get_field_id('unit'); ?>" name="<?php echo $this->get_field_name('unit'); ?>" style="width:6em;">
<?php
$arr = array('日前','週前','ヶ月前','年前');
foreach($arr as $r) {
	echo ($r==$unit)?'<option selected="selected">'.$r.'</option>':'<option>'.$r.'</option>';
}
?>
</select>までに絞る
</p>
<p>
<label for="<?php echo $this->get_field_id('num'); ?>"><?php _e('表示件数:'); ?></label><br />
<input class="widefat" id="<?php echo $this->get_field_id('num'); ?>" name="<?php echo $this->get_field_name('num'); ?>" type="text" value="<?php echo $num; ?>" style="width:3em;text-align:right;" />件
</p>
<p>
<label for="<?php echo $this->get_field_id('orderby'); ?>"><?php _e('並び替え:'); ?></label>
<select class="widefat" id="<?php echo $this->get_field_id('orderby'); ?>" name="<?php echo $this->get_field_name('orderby'); ?>">
<?php
$arr = array('投稿日時','更新日時','ランダム');
// Jetpack Post Views(プラグイン有効時)
if(function_exists('JPV_display_top_posts')){
	array_push($arr, 'Jetpack Post Views');
}
// WP-Post Views(プラグイン有効時)
if(function_exists('get_most_viewed')) {
	array_push($arr, 'WP-Post Views');
}
foreach($arr as $r) {
	echo ($r==$orderby)?'<option selected="selected">'.$r.'</option>':'<option>'.$r.'</option>';
}
?>
</select>
<input type="checkbox" name="<?php echo $this->get_field_name('order'); ?>" id="<?php echo $this->get_field_id('order'); ?>" value="1"<?php echo(empty($order))?'':' checked="checked"';?> />
<label for="<?php echo $this->get_field_id('order'); ?>"><?php _e('逆順(昇順)'); ?></label>
</p>
	<?php
	}
}
function TimeRangePosts_registWidget() {
	return register_widget("TimeRangePosts");
}
add_action('widgets_init', 'TimeRangePosts_registWidget');

これからやりたいこと

  • CSSでいい感じのデザインにして「ブラック系/ホワイト系」とかを選択できるようにする
  • ランダムな記事を出力
  • アイキャッチを表示させる
  • プラグイン化
ここはこっちの記述の方がいいよとか、こんな機能はどう?などフィードバックぜひお待ちしてます!