当サイトでも利用しているWordPressテーマSANGOには、標準で「記事の閲覧数」と「人気記事のウィジェット」がありますが、これ以外のテーマにはあったりなかったりします。
国内産で人気のテーマには、大体標準で搭載されてることが多いです。
そんな時、プラグインを使えば簡単にそれらが実装できてしまいますが、プラグインの入れ過ぎで動作がもっさりとしてしまったり。プラグインの干渉で動作がしない。など、不具合が出ないよう、できることならプラグイン無しで実装したいところです。
この記事では、そんな「記事の閲覧数」と「人気記事のウィジェット」を、プラグイン無しのコピペだけで実装するスニペットの解説です。
実装のサンプル
早速の実装のサンプルです。管理画面と、ウィジェットにそれぞれ項目が追加されます。
管理画面
投稿ページに閲覧数を機能として追加します。
閲覧数は、当サイトで使用しているWordPressテーマSANGOや、人気のCocoonのテーマでは、最初から搭載されています。
この閲覧数の機能が無いテーマにプラグインなしで実装できます。
閲覧数をWordPress内に作ると
- 人気記事のランキングができる
- 管理画面上で人気の記事が分かる
のようなことができるので、記事一覧の表示パターンやサイト内のコンテンツを拡張したい人にはオススメです。
人気記事のウィジェット
人気記事のランキングを、ウィジェットで利用できるようになります。
オプションでランキングの表示数と、記事の投稿日も好きなようにカスタマイズできるので、TOP3やTOP10など条件を設定して出力できます。
表示するランキングに上限はないので、記事数さえあればTOP50とかも出せます。
コピペする時の注意点
この記事で紹介するコードは全てPHP
です。
コピペの際、functions.php
をいじる為、失敗すると画面が真っ白になりログイン等できなくなってしまいます。なので、くれぐれも注意してコピペください。
実装の手順と方法
閲覧数と、ウィジェット追加の実装手順について解説します。
以下の3つのSTEPでOKです。
まずは、使用しているテーマのfunctions.php
に以下のコードをコピペします。
コピペすることで、管理画面の投稿一覧ページに閲覧数の項目が追加されます。
コードを表示する
//アクセス数を取得
function get_post_views($postID){
$count_key = 'post_views_count';
$count = get_post_meta($postID, $count_key, true);
if($count==''){
delete_post_meta($postID, $count_key);
add_post_meta($postID, $count_key, '0');
return '0 View';
}
return $count.' Views';
}
//アクセス数を保存
function set_post_views($postID) {
$count_key = 'post_views_count';
$count = get_post_meta($postID, $count_key, true);
if($count==''){
$count = 0;
delete_post_meta($postID, $count_key);
add_post_meta($postID, $count_key, '0');
}else{
$count++;
update_post_meta($postID, $count_key, $count);
}
}
//クローラーのアクセス判別
function is_bot() {
$ua = $_SERVER['HTTP_USER_AGENT'];
$bot = array(
"googlebot",
"msnbot",
"yahoo"
);
foreach( $bot as $bot ) {
if (stripos( $ua, $bot ) !== false){
return true;
}
}
return false;
}
//管理画面の投稿画面にPV数を表示
function count_status($post){
if( $post->post_type == "post" ){
$number = $post->post_views_count;
if( empty($number) ){
$number = "0";
}
echo'<div class="postbox" style="margin:20px 0 0 0; padding:12px; ">';
echo'<span>この記事の閲覧数:</span>';
echo'<strong> '. esc_html( $number ) .' View </strong>';
echo'</div>';
}
}
add_action('edit_form_after_editor', 'count_status');
//管理画面の投稿一覧にPV数とサムネイル画像を表示
function manage_posts_columns($columns) {
$columns['post_views_count'] = '閲覧数';
$columns['thumbnail'] = 'サムネイル';
return $columns;
}
function add_column($column_name, $post_id) {
//View数呼び出し
if ( $column_name == 'post_views_count' ) {
$stitle = get_post_meta($post_id, 'post_views_count', true);
}
//サムネイル呼び出し
if ( $column_name == 'thumbnail') {
$thumb = get_the_post_thumbnail($post_id, array(100,100), 'thumbnail');
}
//表示する
if ( isset($stitle) && $stitle ) {
echo esc_attr($stitle);
}
else if ( isset($thumb) && $thumb ) {
echo $thumb;
}
}
add_filter( 'manage_posts_columns', 'manage_posts_columns' );
add_action( 'manage_posts_custom_column', 'add_column', 10, 2 );
//閲覧数で並び替え
function column_orderby_custom( $vars ) {
if ( isset( $vars['orderby'] ) && 'post_views_count' == $vars['orderby'] ) {
$vars = array_merge( $vars, array(
'meta_key' => 'post_views_count',
'orderby' => 'meta_value_num'
));
}
return $vars;
}
add_filter( 'request', 'column_orderby_custom' );
function posts_register_sortable( $sortable_column ) {
$sortable_column['post_views_count'] = 'post_views_count';
return $sortable_column;
}
add_filter( 'manage_edit-post_sortable_columns', 'posts_register_sortable' );
次にsingle.php
に以下のコードをコピペします。コードは、<main>〜</main>
のクロージング(閉じ)タグ前あたりに記述するようにしましょう。
これをコピペすることで、投稿ページのデフォルトのテンプレートで閲覧数のカウントが可能になります。
閲覧数は、WordPressにログインしているユーザーとGoogleのクローラーBOTを除外してカウントします。
コードを表示する
<?php if(!is_user_logged_in() && !is_bot()): ?>
<!-- PVカウンター -->
<?php set_post_views(get_the_ID()); ?>
<!-- /PVカウンター -->
<?php endif; ?>
最後に、人気記事のウィジェット追加の為、以下のコードをfunctions.php
にコピペします。
コードを表示する
//人気記事ランキングウィジェット
class Popular_Posts extends WP_Widget {
function __construct() {
$widget_option = array('description' => 'PV数の多い順に記事を表示');
parent::__construct( false, $name = '人気記事ランキング', $widget_option );
}
function form($instance) {
$time = !empty($instance['time']) ? 'checked' : '';
?>
<p>
<p>
<label for="<?php echo $this->get_field_id('title'); ?>">タイトル:</label>
<input type="text" class="widefat" id="<?php echo $this->get_field_id('title'); ?>" name="<?php echo $this->get_field_name('title'); ?>" value="<?php echo esc_attr( @$instance['title'] ); ?>">
</p>
<p>
<label for="<?php echo $this->get_field_id('number'); ?>">表示する投稿数:</label>
<input class="tiny-text" type="number" id="<?php echo $this->get_field_id('number'); ?>" name="<?php echo $this->get_field_name('number'); ?>" value="<?php echo esc_attr( @$instance['number'] ); ?>" step="1" min="1" max="10" size="3">
</p>
<p>
<input class="checkbox" type="checkbox" <?php echo $time; ?> id="<?php echo $this->get_field_id('time'); ?>" name="<?php echo $this->get_field_name('time'); ?>" />
<label for="<?php echo $this->get_field_id('time'); ?>">投稿日を表示しますか ?</label>
</p>
</p>
<?php
}
function update($new_instance, $old_instance) {
$instance = $old_instance;
$instance['title'] = strip_tags($new_instance['title']);
$instance['number'] = is_numeric($new_instance['number']) ? $new_instance['number'] : 5;
$instance['time'] = strip_tags($new_instance['time']);
return $instance;
}
function widget($args, $instance) {
extract($args);
echo $before_widget;
$title = NULL;
if(!empty($instance['title'])) {
$title = apply_filters('widget_title', $instance['title'] );
}
if ($title) {
echo $before_title . $title . $after_title;
} else {
echo '<h2 class="heading heading-widget">RANKING</h2>';
}
$number = !empty($instance['number']) ? $instance['number'] : 5;
get_the_ID();
$args = array(
'meta_key'=> 'post_views_count',
'orderby' => 'meta_value_num',
'order' => 'DESC',
'ignore_sticky_posts' => '1',
'posts_per_page' => $number
);
$my_query = new WP_Query( $args );?>
<ol class="rankListWidget">
<?php while ( $my_query->have_posts() ) : $my_query->the_post(); ?>
<li class="rankListWidget__item<?php if ( get_option('fit_post_eyecatch') == 'value2' ) : ?> rankListWidget__item-noeye<?php endif; ?>">
<?php if ( get_option('fit_post_eyecatch') != 'value2' ) : ?>
<div class="eyecatch eyecatch-widget u-txtShdw">
<a href="<?php the_permalink(); ?>">
<?php if(has_post_thumbnail()) {the_post_thumbnail('icatch');} else {echo '<img src="'.get_template_directory_uri().'/img/img_no.gif" alt="NO IMAGE"/>';}?>
</a>
</div>
<?php endif; ?>
<h3 class="rankListWidget__title"><a href="<?php the_permalink(); ?>"><?php the_title(); ?></a></h3>
<div class="dateList dateList-widget<?php if ( get_option('fit_post_eyecatch') == 'value2' ) : ?> dateList-noeye<?php endif; ?>">
<?php if(!empty($instance['time'])) : ?><span class="dateList__item icon-calendar"><?php the_time('Y.m.d'); ?></span><?php endif; ?>
<span class="dateList__item icon-folder"><?php the_category(' ');?></span>
</div>
</li>
<?php endwhile; wp_reset_postdata(); ?>
</ol>
<?php
echo $after_widget;
}
}
add_action( 'widgets_init', create_function( '', 'return register_widget( "Popular_Posts" );' ) );
コードの量は多いですが、これで完了です。
コピペ用コード一式
ここまで解説してきた2箇所にコピペするコードと全く一緒の記述ですが、PHPのコピペ用コード一式です。
記事に閲覧数を追加するスニペット一式
記事に閲覧数を追加するfunctions.php
と、投稿(記事)ページのsingle.php
にコピペするコード一式です。
コードを表示する
//アクセス数を取得
function get_post_views($postID){
$count_key = 'post_views_count';
$count = get_post_meta($postID, $count_key, true);
if($count==''){
delete_post_meta($postID, $count_key);
add_post_meta($postID, $count_key, '0');
return '0 View';
}
return $count.' Views';
}
//アクセス数を保存
function set_post_views($postID) {
$count_key = 'post_views_count';
$count = get_post_meta($postID, $count_key, true);
if($count==''){
$count = 0;
delete_post_meta($postID, $count_key);
add_post_meta($postID, $count_key, '0');
}else{
$count++;
update_post_meta($postID, $count_key, $count);
}
}
//クローラーのアクセス判別
function is_bot() {
$ua = $_SERVER['HTTP_USER_AGENT'];
$bot = array(
"googlebot",
"msnbot",
"yahoo"
);
foreach( $bot as $bot ) {
if (stripos( $ua, $bot ) !== false){
return true;
}
}
return false;
}
//管理画面の投稿画面にPV数を表示
function count_status($post){
if( $post->post_type == "post" ){
$number = $post->post_views_count;
if( empty($number) ){
$number = "0";
}
echo'<div class="postbox" style="margin:20px 0 0 0; padding:12px; ">';
echo'<span>この記事の閲覧数:</span>';
echo'<strong> '. esc_html( $number ) .' View </strong>';
echo'</div>';
}
}
add_action('edit_form_after_editor', 'count_status');
//管理画面の投稿一覧にPV数とサムネイル画像を表示
function manage_posts_columns($columns) {
$columns['post_views_count'] = '閲覧数';
$columns['thumbnail'] = 'サムネイル';
return $columns;
}
function add_column($column_name, $post_id) {
//View数呼び出し
if ( $column_name == 'post_views_count' ) {
$stitle = get_post_meta($post_id, 'post_views_count', true);
}
//サムネイル呼び出し
if ( $column_name == 'thumbnail') {
$thumb = get_the_post_thumbnail($post_id, array(100,100), 'thumbnail');
}
//表示する
if ( isset($stitle) && $stitle ) {
echo esc_attr($stitle);
}
else if ( isset($thumb) && $thumb ) {
echo $thumb;
}
}
add_filter( 'manage_posts_columns', 'manage_posts_columns' );
add_action( 'manage_posts_custom_column', 'add_column', 10, 2 );
//閲覧数で並び替え
function column_orderby_custom( $vars ) {
if ( isset( $vars['orderby'] ) && 'post_views_count' == $vars['orderby'] ) {
$vars = array_merge( $vars, array(
'meta_key' => 'post_views_count',
'orderby' => 'meta_value_num'
));
}
return $vars;
}
add_filter( 'request', 'column_orderby_custom' );
function posts_register_sortable( $sortable_column ) {
$sortable_column['post_views_count'] = 'post_views_count';
return $sortable_column;
}
add_filter( 'manage_edit-post_sortable_columns', 'posts_register_sortable' );
<?php if(!is_user_logged_in() && !is_bot()): ?>
<!-- PVカウンター -->
<?php set_post_views(get_the_ID()); ?>
<!-- /PVカウンター -->
<?php endif; ?>
使用しているテーマで、管理画面にアイキャッチ画像の表示がある場合は、こっちのコードを利用ください。
上記のコードは、サムネイルとして記事のアイキャッチ画像も、管理画面に表示するスニペットです。
その為、管理画面に「閲覧数」だけ表示したい場合、以下のコードをコピペください。
コードを表示する
//アクセス数を取得
function get_post_views($postID){
$count_key = 'post_views_count';
$count = get_post_meta($postID, $count_key, true);
if($count==''){
delete_post_meta($postID, $count_key);
add_post_meta($postID, $count_key, '0');
return '0 View';
}
return $count.' Views';
}
//アクセス数を保存
function set_post_views($postID) {
$count_key = 'post_views_count';
$count = get_post_meta($postID, $count_key, true);
if($count==''){
$count = 0;
delete_post_meta($postID, $count_key);
add_post_meta($postID, $count_key, '0');
}else{
$count++;
update_post_meta($postID, $count_key, $count);
}
}
//クローラーのアクセス判別
function is_bot() {
$ua = $_SERVER['HTTP_USER_AGENT'];
$bot = array(
"googlebot",
"msnbot",
"yahoo"
);
foreach( $bot as $bot ) {
if (stripos( $ua, $bot ) !== false){
return true;
}
}
return false;
}
//管理画面の投稿画面にPV数を表示
function count_status($post){
if( $post->post_type == "post" ){
$number = $post->post_views_count;
if( empty($number) ){
$number = "0";
}
echo'<div class="postbox" style="margin:20px 0 0 0; padding:12px; ">';
echo'<span>この記事の閲覧数:</span>';
echo'<strong> '. esc_html( $number ) .' View </strong>';
echo'</div>';
}
}
add_action('edit_form_after_editor', 'count_status');
//管理画面の投稿一覧にPV数を表示
function manage_posts_columns($columns) {
$columns['post_views_count'] = '閲覧数';
return $columns;
}
function add_column($column_name, $post_id) {
//View数呼び出し
if ( $column_name == 'post_views_count' ) {
$stitle = get_post_meta($post_id, 'post_views_count', true);
}
//表示する
if ( isset($stitle) && $stitle ) {
echo esc_attr($stitle);
}
else if ( isset($thumb) && $thumb ) {
echo $thumb;
}
}
add_filter( 'manage_posts_columns', 'manage_posts_columns' );
add_action( 'manage_posts_custom_column', 'add_column', 10, 2 );
//閲覧数でソートできるようにする
function column_orderby_custom( $vars ) {
if ( isset( $vars['orderby'] ) && 'post_views_count' == $vars['orderby'] ) {
$vars = array_merge( $vars, array(
'meta_key' => 'post_views_count',
'orderby' => 'meta_value_num'
));
}
return $vars;
}
add_filter( 'request', 'column_orderby_custom' );
function posts_register_sortable( $sortable_column ) {
$sortable_column['post_views_count'] = 'post_views_count';
return $sortable_column;
}
add_filter( 'manage_edit-post_sortable_columns', 'posts_register_sortable' );
<?php if(!is_user_logged_in() && !is_bot()): ?>
<!-- PVカウンター -->
<?php set_post_views(get_the_ID()); ?>
<!-- /PVカウンター -->
<?php endif; ?>
人気記事ランキングのウィジェットを追加するスニペット
人気記事ランキングのウィジェットのコピペ用コードです。まるっとfunctions.php
に貼り付けしましょう。
コードを表示する
//人気記事ランキングウィジェット
class Popular_Posts extends WP_Widget {
function __construct() {
$widget_option = array('description' => 'PV数の多い順に記事を表示');
parent::__construct( false, $name = '人気記事ランキング', $widget_option );
}
function form($instance) {
$time = !empty($instance['time']) ? 'checked' : '';
?>
<p>
<p>
<label for="<?php echo $this->get_field_id('title'); ?>">タイトル:</label>
<input type="text" class="widefat" id="<?php echo $this->get_field_id('title'); ?>" name="<?php echo $this->get_field_name('title'); ?>" value="<?php echo esc_attr( @$instance['title'] ); ?>">
</p>
<p>
<label for="<?php echo $this->get_field_id('number'); ?>">表示する投稿数:</label>
<input class="tiny-text" type="number" id="<?php echo $this->get_field_id('number'); ?>" name="<?php echo $this->get_field_name('number'); ?>" value="<?php echo esc_attr( @$instance['number'] ); ?>" step="1" min="1" max="10" size="3">
</p>
<p>
<input class="checkbox" type="checkbox" <?php echo $time; ?> id="<?php echo $this->get_field_id('time'); ?>" name="<?php echo $this->get_field_name('time'); ?>" />
<label for="<?php echo $this->get_field_id('time'); ?>">投稿日を表示しますか ?</label>
</p>
</p>
<?php
}
function update($new_instance, $old_instance) {
$instance = $old_instance;
$instance['title'] = strip_tags($new_instance['title']);
$instance['number'] = is_numeric($new_instance['number']) ? $new_instance['number'] : 5;
$instance['time'] = strip_tags($new_instance['time']);
return $instance;
}
function widget($args, $instance) {
extract($args);
echo $before_widget;
$title = NULL;
if(!empty($instance['title'])) {
$title = apply_filters('widget_title', $instance['title'] );
}
if ($title) {
echo $before_title . $title . $after_title;
} else {
echo '<h2 class="heading heading-widget">RANKING</h2>';
}
$number = !empty($instance['number']) ? $instance['number'] : 5;
get_the_ID();
$args = array(
'meta_key'=> 'post_views_count',
'orderby' => 'meta_value_num',
'order' => 'DESC',
'ignore_sticky_posts' => '1',
'posts_per_page' => $number
);
$my_query = new WP_Query( $args );?>
<ol class="rankListWidget">
<?php while ( $my_query->have_posts() ) : $my_query->the_post(); ?>
<li class="rankListWidget__item<?php if ( get_option('fit_post_eyecatch') == 'value2' ) : ?> rankListWidget__item-noeye<?php endif; ?>">
<?php if ( get_option('fit_post_eyecatch') != 'value2' ) : ?>
<div class="eyecatch eyecatch-widget u-txtShdw">
<a href="<?php the_permalink(); ?>">
<?php if(has_post_thumbnail()) {the_post_thumbnail('icatch');} else {echo '<img src="'.get_template_directory_uri().'/img/img_no.gif" alt="NO IMAGE"/>';}?>
</a>
</div>
<?php endif; ?>
<h3 class="rankListWidget__title"><a href="<?php the_permalink(); ?>"><?php the_title(); ?></a></h3>
<div class="dateList dateList-widget<?php if ( get_option('fit_post_eyecatch') == 'value2' ) : ?> dateList-noeye<?php endif; ?>">
<?php if(!empty($instance['time'])) : ?><span class="dateList__item icon-calendar"><?php the_time('Y.m.d'); ?></span><?php endif; ?>
<span class="dateList__item icon-folder"><?php the_category(' ');?></span>
</div>
</li>
<?php endwhile; wp_reset_postdata(); ?>
</ol>
<?php
echo $after_widget;
}
}
add_action( 'widgets_init', create_function( '', 'return register_widget( "Popular_Posts" );' ) );
ウィジェットの見た目やデザインは、CSSで整えて使ってください。