プラグインなしで人気記事一覧ウィジェット化-カテゴリー別人気記事ランキングウィジェット

2018年2月17日

プラグインなしで人気記事一覧ウィジェット化

プラグインなしで人気記事一覧ウィジェット化4回目、前回はサイドバーに全投稿からの人気記事ランキングウィジェットを作成したが、今回は個別投稿ページの記事の下に、その投稿が属するカテゴリーの人気記事ランキングを表示するウィジェットを作成する。

どちらかといえば、サイドバーの人気記事ランキングウィジェットよりも、いまから作成する個別投稿ページに表示するカテゴリー別人気ランキングウィジェットの方が作りたかった。全投稿からの人気記事ランキングより関連性が高い記事を表示できるからだ。

記事下ウィジェットにカテゴリー別人気記事一覧

記事下ウィジェットにカテゴリー別人気記事一覧
記事下ウィジェットにカテゴリー別人気記事一覧

個別投稿記事に属するカテゴリーの人気記事を記事の下ウィジェットエリアに表示させるウィジェット作成する。基本的には前回のサイドバーに表示している全記事からの人気記事ランキングウィジェットと同じ構成でコードをfunctions.phpに追加する。

個別ページにも記事下ウィジェットエリアを表示させている関係上、ページには「おすすめの人気記事」というタイトルでサイドバーとカブルのだが全記事からの人気記事一覧を表示させる。個別投稿記事専用のウィジェットエリアを作成すればいいのだが面倒なのでやめた。

カテゴリー別人気記事一覧ウィジェット化functions.phpにコード追加

何かとコードを追加するfunctions.php。肥大化するので整理整頓した方がすっきりするし、テーマを変更した場合も移行しやすいのでテンプレートパート化した方がよい。

使ってるテーマの関係上(Luxeritas ルクセリタスの子テーマ)、直接single.phpやpage.phpをいじれないのでウィジェット化しているが、Webページに出力するウィジェットの内容の部分をテンプレートに直接追加すればウィジェット化する必要がなくなる。

WP_Widgetクラスを継承しサブクラスを作成

<?php
/* カテゴリー別人気記事ウィジェット */
class Cat_Ninki_Kiji extends WP_Widget {
function __construct() {
parent::__construct(
'cat_ninki_kiji',
'カテゴリー別人気記事ランキング',
array( 'description' => 'カテゴリー別でPV数の多い順で人気記事をランキング ランキング記事件数は10まで' )
);
}

Webページに出力するウィジェットの内容 widget()

追記 2018/03/20
複数カテゴリーに対応した『カテゴリー別人気記事ランキングウィジェット 複数カテゴリー対応版』に差し替えてます。
public function widget($args, $instance) {
extract($args);
echo $before_widget;
$category = get_the_category();
$cat_id   = $category[0]->cat_ID;
$cat_name = $category[0]->cat_name;
if (is_single()){
echo '<h2>' . $cat_name. ' <span class="fon14">カテゴリーの人気記事</span></h2>';	
}
else {
echo '<h2>おすすめの人気記事</h2>';
}
$number = $instance['number'] ;
?>
<div class="ninki-kiji">
<ul>
<?php 
get_the_ID();
$args = array(
'cat' => $cat_id,
'meta_key'=> 'post_views_count',
'orderby' => 'meta_value_num',
'order' => 'DESC',
'post_type' => array('post','page'),
'post__not_in' => array(41),
'posts_per_page' => $number
);
$my_query = new WP_Query( $args );?>
<?php while ( $my_query->have_posts() ) : $my_query->the_post(); $rankcount++; ?>
<li>
<a href="<?php the_permalink(); ?>">
<span class="cat-rank-count ranking-count<?php echo $rankcount; ?>">
<?php echo $rankcount; ?>
</span>
<?php if( has_post_thumbnail() ): ?>
<?php the_post_thumbnail('thumb100'); ?>
<?php endif; ?>
<div class="cat-ninki-kiji-text">
<h3><?php the_title(); ?></h3>
<p><?php
$str = get_the_excerpt();
$count = 60;
$more = '...';
echo wp_html_excerpt( $str, $count, $more );
?></p>
</div>
</a>
</li>
<?php endwhile; ?>
<?php wp_reset_postdata(); ?>
</ul>
</div>
<?php echo $after_widget;
}

4~6行目で属するカテゴリー情報を取得、20行目でWP_Queryサブループに渡すカテゴリーID条件、24行目ランキングに投稿だけ入れるなら'post_type’ => 'post’,でOK、25行目ランキングから除外したい投稿がある場合IDを指定('post__not_in’ => array(ID),)、40~44行目60字の概要を表示。

ウィジェット化しない場合

<?php
$category = get_the_category();
$cat_id   = $category[0]->cat_ID;
$cat_name = $category[0]->cat_name;
if (is_single()){
echo '<h2>' . $cat_name. ' <span class="fon14">カテゴリーの人気記事</span></h2>';	
}
else {
echo '<h2>おすすめの人気記事</h2>';
}
?>
<div class="ninki-kiji">
<ul>
<?php 
get_the_ID();
$args = array(
'cat' => $cat_id,
'meta_key'=> 'post_views_count',
'orderby' => 'meta_value_num',
'order' => 'DESC',
'post_type' => array('post','page'),
'post__not_in' => array(41),
'posts_per_page' => 表示する記事数
);
$my_query = new WP_Query( $args );?>
<?php while ( $my_query->have_posts() ) : $my_query->the_post(); $rankcount++; ?>
<li>
<a href="<?php the_permalink(); ?>">
<span class="cat-rank-count ranking-count<?php echo $rankcount; ?>">
<?php echo $rankcount; ?>
</span>
<?php if( has_post_thumbnail() ): ?>
<?php the_post_thumbnail('thumb100'); ?>
<?php endif; ?>
<div class="cat-ninki-kiji-text">
<h3><?php the_title(); ?></h3>
<p><?php
$str = get_the_excerpt();
$count = 60;
$more = '...';
echo wp_html_excerpt( $str, $count, $more );
?></p>
</div>
</a>
</li>
<?php endwhile; ?>
<?php wp_reset_postdata(); ?>
</ul>
</div>

ウィジェット化しないでテンプレート(single.php)に直で貼り付ける場合上のコードを貼り付ければいけるはず。まあテンプレートパーツにした方がいいだろうけど。

例えば、テーマフォルダにwiget-cat-ninki.phpとして上のコードを保存した場合は下のコードをsingle.phpの表示したいところに貼り付ければOK。

<?php get_template_part( wiget, cat-ninki ); ?>

cssをstyle.cssに追加

.ninki-kiji ul {
padding: 0;
list-style: none;
}
.ninki-kiji li {
position: relative;
margin-top: 10px;
padding: 0 5px 10px;
border-bottom: dotted 1px #ddd;
}
.ninki-kiji a {
display: inline-block;
text-decoration: none;
color: #AD3B32;
font-weight: bold;
}
.ninki-kiji a:hover {
background-color: #fafad2;
}
.ninki-kiji a:after {
display: block;
clear: both;
content: '';
}
.cat-rank-count {
position: absolute;
top: 0;
left: 5px;
padding: 1px 10px;
color: #fff;
background: rgba(66, 66, 66, .85);
}
.ranking-count1 {
background: rgba(189, 161, 82, .9);
}
.ranking-count2 {
background: rgba(152, 153, 173, .9);
}
.ranking-count3 {
background: rgba(156, 85, 34, .9);
}
.ninki-kiji img {
float: left;
width: 100px;
height: 100px;
}
.cat-ninki-kiji-text {
font-size: .9em;
margin-left: 110px;
font-weight:normal;
color:#333;
}

管理画面のウィジェット設定フォームを出力 form()

/* 管理画面のウィジェット設定フォームを出力 */
public function form($instance) {
?>
<p>
<label for="<?php echo $this->get_field_id('number'); ?>"><?php _e('記事表示件数:'); ?></label>
<input type="text" id="<?php echo $this->get_field_id('number'); ?>"
name="<?php echo $this->get_field_name('number'); ?>"
value="<?php echo esc_attr( $instance['number'] ); ?>" size="2">
</p>
<?php
}

ランキング何位まで表示するか、記事表示数のみ指定する。タイトルは「カテゴリー名 カテゴリーの人気記事」と表示される。(投稿ページ)

データ検証して無害化して安全な値で保存 update()

/* データ検証して無害化して安全な値で保存 */
public function update($new_instance, $old_instance) {
$instance = $old_instance;
$instance['number'] = ctype_digit($new_instance['number']) ? $new_instance['number'] : 5;
/* 記事表示件数11以上の場合10件表示 */
if( $instance['number'] == 0 || 10 < $instance['number']){$instance['number'] = 10 ; };
return $instance;
}
}/* class Cat_Ninki_Kiji 終わり */

ランキングは10位までに限定する。一応、サニタイズはしている。

ウィジェットの登録処理 PHP 5.3以上 widgets_init

/* ウィジェットの登録処理 */
add_action( 'widgets_init', function() {
     register_widget( 'Cat_Ninki_Kiji' );
});

カスタムフィールドの値を書き換え更新すれば

カテゴリー別人気記事一覧ウィジェット化
カテゴリー別人気記事一覧ウィジェット化

ウィジェット管理画面に「カテゴリー別人気記事ランキング」ウィジェットが現れ、Luxeritas ルクセリタスの場合「記事下ウィジェットさらに下」ウィジェットエリアにカテゴリー別人気記事ランキングウィジェットを追加すればこの記事の下のようにSNSシェアボタンの上に、「WPカスタマイズ カテゴリーの人気記事」といった具合に投稿が属するカテゴリーの人気記事ランキングが表示される。

カスタムフィールド「post_views_count」
カスタムフィールド「post_views_count」

投稿編集画面のカスタムフィールドの「post_views_count」に投稿のページビューの値が保存されているということは、post_views_countの値を書き換えて更新すればランキング操作できるということになる。

本当の意味でアクセスの多い記事ランキングを表示したいのであればPVの値を操作するべきではないだろうが、どうしても押したい記事がある場合にはpost_views_countの値を書き換えてランクインさせるという使い方もできる。おすすめの記事的な使い方もできるということだ。

以上4回に渡って備忘録した「プラグインなしで人気記事一覧ウィジェット化」。人気記事プラグインを使えば手っ取り早いだろうけど、自分で自由にカスタマイズできるのがいい点なのかもしれない。