
WordPressで人気記事を表示するにはプラグイン(WordPress Popular Postsというのが有名)を使用すると簡単に実現出来ます。
しかしプラグインを使用すると
- 記事が増えると重い。(デフォルトの設定でアクセス事にデータベースとやり取りして保存しているのが原因)
- WordPressバージョンのアップデートの際の心配もなくなるし裏でどのようにして動作しているのか把握したいので個人的に自作可能なら自作したい。
上記の理由からプラグインを使用するのはやめてWordPressのカスタムフィールド機能を使うと割と簡単に自作出来そうだったので自作した際のメモ。
流れとしてはfunction.phpに人気記事を表示するための関数を追加して出力したいsingleページテンプレートにコード追加。最後にcssで見た目の確認・調節。
function.phpにオリジナル関数を追加
まずはfunction.php内にオリジナルの関数get_custom_popular_ranking()を追加。
function get_custom_popular_ranking() {
if (!is_single()) return;
if (empty($post_id)) {
global $post;
$post_id = $post->ID;
}
session_start();
if (!isset($_SESSION['custom_popular_id_'.$post_id])) {
$_SESSION['custom_popular_id_'.$post_id] = 1;
$custom_key = 'custom_popular_ranking';
$cnt = get_post_meta($post_id, $custom_key, true);
if ($cnt == '') {
$cnt = 1;
add_post_meta($post_id, $custom_key, $cnt);
} else {
$cnt++;
update_post_meta($post_id, $custom_key, $cnt);
}
}
session_write_close();
}
add_action('wp_head', 'get_custom_popular_ranking');
解説
-
36行目:wp_headをフックにページが呼び出されるとget_custom_popular_ranking関数(オリジナル)を呼び出す。
-
3行目:シングルページでなければ関係ないので処理停止。
-
10行目:同ユーザーの場合はアクセス事(リロードなど)に毎回カウントアップされるのではなくブラウザを閉じるまではカウントアップさせたくなかったのでセッション($_SESSION)を利用。
-
12行目:セッションがない時の処理。
セッション名に記事IDを付加して記事毎のセッション名を作成。trueに。 -
16行目:‘custom_popular_ranking’(任意)という名前のカスタムフィールドを使いたいので変数に。
-
17行目:$cnt = get_post_meta($post_id, $custom_key, true);
‘custom_popular_ranking’という名前のカスタムフィールドがあるかチェック。 -
19行目:カスタムフィールド(‘custom_popular_ranking’)がまだ存在しない場合の処理。
ない場合はadd_post_meta()で値は1でカスタムフィールドを作成。 -
24行目:カスタムフィールド(‘custom_popular_ranking’)が存在する場合の処理。
update_post_meta()で値を1プラスしてアップデート。
- ※ページをアクセス事(リロードなど)にカウントアップさせたい場合はセッション関連を削除してください。
singleページテンプレートにコード追加
人気ランキング記事を挿入したい場所に以下を挿入。
‘custom_popular_ranking'(任意で作成)
という名前のカスタムフィールドをfunction.phpで自動で作成しているのでその値が高い順に記事を表示させる。
- ※htmlは適宜自分のサイトに合わせて変更が必要。
<nav class="cms-nav cms-nav-ranking">
<ul>
<?php
$custom_key = 'custom_popular_ranking';
$args = array(
'cat' => $cat_common_id,
'posts_per_page'=>15,
'meta_key'=>$custom_key,
'orderby'=>'meta_value_num',
'order'=>'DESC'
);
$my_query = new WP_Query($args);
$ranking_counter = 0;
?>
<?php if( $my_query -> have_posts() ) :?>
<?php while($my_query -> have_posts()) : $my_query -> the_post();?>
<?php
$category = get_the_category();
$category_slug = $category[0]->slug;
$category_name = $category[0]->cat_name;
$thumbnail_id = get_post_thumbnail_id();
$eye_img = wp_get_attachment_image_src($thumbnail_id,'medium');
$popular_ranking_cnt = get_post_meta($post->ID, $custom_key, true);
$ranking_counter++;
?>
<li class="ranking-<?php echo $ranking_counter; ?>">
<a href="<?php the_permalink();?>">
<div class="cms-nav-img">
<img src="<?php echo $eye_img[0]; ?>" width="<?php echo $eye_img[1]; ?>" height="<?php echo $eye_img[2]; ?>" alt="<?php the_title(); ?>">
</div>
<div class="cms-nav-txt">
<div class="cms-nav-tit"><?php the_title(); ?></div>
<div class="cms-nav-info clearfix">
<div class="cms-nav-cat-items clearfix">
<div class="cat-<?php echo $category_slug;?>"><?php echo $category_name;?></div>
</div>
<div class="cms-nav-date"><?php the_time('Y/m/d'); ?></div>
</div>
<div class="cms-nav-ranking-num"><?php echo $popular_ranking_cnt;?><span>View</span></div>
</div>
</a>
</li>
<?php endwhile;?>
<?php endif;?>
</ul>
</nav>
解説
-
8行目:‘cat’に必要なカテゴリIDを挿入。
-
9行目:‘posts_per_page’に表示したい件数を挿入。
-
10行目:‘meta_key’に’custom_popular_ranking’を渡し‘orderby’で’meta_value_num’を指定して降順(DESC)でソート。
要するに〇〇カテゴリの〇〇件分のデータを〇〇の名前のカスタムフィールドの数値が高い順に取得するという事です。 -
31行目:$popular_ranking_cnt = get_post_meta($post->ID, $custom_key, true);
get_post_meta()に記事IDとカスタムフィールドのキーを渡しカウント取得。 -
37行目:<li class="ranking-<?php echo $ranking_counter; ?>">
ループ処理でリストに順位となるcssを付加。
以下出力されるHTMLソース。(1件分)
<nav class="cms-nav cms-nav-ranking">
<ul>
<li class="ranking-1">
<a href="https://keprate.com/web/css/form/">
<div class="cms-nav-img">
<img src="https://keprate.com/wp-content/uploads/2018/02/css_form-300x200.png" width="300" height="200" alt="フォーム要素 input・プルダウン等をCSSでデザイン変更する">
</div>
<div class="cms-nav-txt">
<div class="cms-nav-tit">フォーム要素 input・プルダウン等をCSSでデザイン変更する</div>
<div class="cms-nav-info clearfix">
<div class="cms-nav-cat-items clearfix">
<div class="cat-css">CSS</div>
</div>
<div class="cms-nav-date">2018/02/13</div>
</div>
<div class="cms-nav-ranking-num">21<span>View</span></div>
</div>
</a>
</li>
</ul>
</nav>
cssで見た目を調節
あとは見た目の調節。
リストにクラスを付加しているので各々好みのランキング画像をいじいじしてください。
個人的にはcssのみ(:nth-child() 疑似クラス)でも順位は取得できるのでループ処理内の$ranking_counter;は不必要かと。
以下cssソース(疑似クラス版参考程度に)
.cms-nav.cms-nav-ranking li {
position: relative;
}
.cms-nav.cms-nav-ranking li::after {
pointer-events: none;
position: absolute;
display: block;
content: '';
letter-spacing: 0.1em;
font-size: 12px;
font-weight: 700;
top: 7px;
left: 12px;
width: 20px;
height: 20px;
padding-top: 3px;
background: #bbb;
text-align: center;
color: #fff;
z-index: 9;
}
.cms-nav.cms-nav-ranking li:nth-child(3)::after,
.cms-nav.cms-nav-ranking li:nth-child(2)::after,
.cms-nav.cms-nav-ranking li:nth-child(1)::after {
width: 24px;
height: 24px;
padding-top: 6px;
font-size: 13px;
}
.cms-nav.cms-nav-ranking li:nth-child(1)::after {
content: '1';
background: #bca045;
}
.cms-nav.cms-nav-ranking li:nth-child(2)::after {
content: '2';
background: #7d7d7d;
}
.cms-nav.cms-nav-ranking li:nth-child(3)::after {
content: '3';
background: #9b7155;
}
.cms-nav.cms-nav-ranking li:nth-child(4)::after {
content: '4';
}
.cms-nav.cms-nav-ranking li:nth-child(5)::after {
content: '5';
}
.cms-nav.cms-nav-ranking li:nth-child(6)::after {
content: '6';
}
.cms-nav.cms-nav-ranking li:nth-child(7)::after {
content: '7';
}
自作の人気ランキングの数値をいじる方法
本当はいじったりしたら不正にあたるのでダメなのでしょうがどこかで数値を変更できないかなぁと調べてみたらデータベースなどを見に行かなくても簡単に出来たのでおまけ的に記載。
WordPressの投稿画面にてカスタムフィールドにチェックが入っていない場合は表示オプションをクリックしてカスタムフィールドにチェックしてください。

デフォルトではページ下部に移動するとカスタムフィールドが出てきます。
function.phpで作成したcustom_popular_rankingが見事に表示されております。右の値を変更すればランキングの順位が変動します。

- ※ソースの流用、改変は自由ですが自己責任とさせていただきます。