
wordpressで人気記事などを表示する際に大活躍のプラグイン「WordPress Popular Posts」ですが、テンプレートに組み込む際に融通がきかないというか、なんというか。。。
まずは正攻法
公式に用意されているコードは
<?php
$args = array(
'post_html' => '<li>{thumb} <a href="{url}">{text_title}</a></li>'
);
wpp_get_mostpopular($args);
?>
こんな感じで、post_htmlのオプションをいじって出力するHTMLを操作するんですよね。
けど、wordpressのWP_Queryを使い慣れてる人からすると、かなり使いにくいというか。微妙に痒いところに手が届かないというか。。。
ちなみにpost_htmlで使える変数は
{thumb} (リンクありで投稿・固定ページのサムネイル画像を表示 (thumbnail_width と thumbnail_height が必要))
{thumb_img} (投稿・固定ページへのリンクなしでサムネイル画像を表示 (thumbnail_width と thumbnail_height が必要))
{thumb_url} (サムネイルの URL を返す (thumbnail_width と thumbnail_height が必要))
{title} (リンクされた投稿・固定ページのタイトルを表示)
{pid} (投稿・固定ページの ID を表示)
{summary} (投稿・固定ページの本文の抜粋を表示 (excerpt_length に0より大きい数が指定されている必要があります))
{stats} (デフォルト統計タグを表示)
{rating} (投稿・固定ページの現在のレートを表示 (WP-PostRatings がインストールされていて有効化されている必要があります))
{score} (投稿・固定ページのレートを数値で表示 (WP-PostRatings がインストールされていて有効化されている必要があります))
{url} (投稿・固定ページの URL を表示)
{text_title} (リンクなしで投稿・固定ページのタイトルを表示)
{title_attr} (similar to text_title, sanitized for use in title/alt attributes)
{author} (投稿者名を返す (stats_author=1 が必要))
{author_copy} (returns linked author name with copy, requires stats_author=1)
{category} (投稿のカテゴリーの返す (stats_category=1 が必要))
{category_copy} (returns linked category name with copy, requires stats_category=1)
{taxonomy} (リンクされたタクソノミー名を返す (stats_taxonomy=1 が必要))
{taxonomy_copy} (returns linked taxonomy names with copy, requires stats_taxonomy=1)
{views} (returns views count only, no text, requires stats_views=1)
{views_copy} (returns views count with copy, requires stats_views=1)
{comments} (コメントカウントのみ (テキストなし) を返す (stats_comments=1 が必要))
{comments_copy} (returns comments count with copy, requires stats_comments=1)
{date} (投稿/固定ページの投稿時間を返す (stats_date=1 が必要))
{date_copy} (returns post/page date with copy, requires stats_date=1)
{total_items} (見つかった人気の投稿数を表示します)
{item_position} (リスト内での投稿の位置を表示します)
と豊富なんですが、個人的にはちょっと使いにくい。。。
フィルターフック「wpp_post」を使えば、やりたいことができるとは思うんですが。。。
もっと使い慣れた形(WP_Query)で使えたらいいなぁ。みたいな感じで今回、いろいろ調べてみました。
結論から言うとプラグインの作者がサポートで答えていたので簡単に実装できました。
この記事にたどり着くまでに時間はかかりましたが。
いらんと思うけど解説
まず、functions.phpに下記コード(簡単に意訳したもの)を書き込みます。
/**
* Stores views of different time periods as meta keys.
*
* @author @migueleste / @radgh
* @link https://wordpress.org/support/topic/how-to-sort-a-custom-query-by-views-all-time-monthly-weekly-or-daily/
* @param int $postid The ID of the current post/page/custom post type.
*/
function custom_wpp_update_postviews($postid) {
// Accuracy:
// 10 = 10回に1回の訪問でビュー数が更新されます。(トラフィックの多いサイトに推奨されます。)
// 30 = 30%の割合でビュー数が更新されます。(そこそこのトラフィックのサイト向け)
// 100 = 毎回ビュー数の反映をするよ。リクエストごとにたくさんDBへの書き込み作業が発生するよ。
$accuracy = 50;
if ( function_exists('wpp_get_views') && (mt_rand(0,100) < $accuracy) ) {
// いらんとこ消すか、コメントアウトしてね!
update_post_meta(
$postid,
'views_total',
wpp_get_views($postid, 'all', false)
);
update_post_meta(
$postid,
'views_daily',
wpp_get_views($postid, 'daily', false)
);
update_post_meta(
$postid,
'views_weekly',
wpp_get_views($postid, 'weekly', false)
);
update_post_meta(
$postid,
'views_monthly',
wpp_get_views($postid, 'monthly', false)
);
}
}
add_action('wpp_post_update_views', 'custom_wpp_update_postviews');
このコードの解説を簡単にすると、wpp_post_update_views(ビュー数が更新された)したときにupdate_post_metaでビュー数をそれぞれ対応したカスタムフィールドに上書きしてね。って書いてあります。
例えば、週間ビュー数でソートしたい場合だと、
function custom_wpp_update_postviews($postid) {
$accuracy = 100;
if ( function_exists('wpp_get_views') && (mt_rand(0,100) < $accuracy) ) {
update_post_meta(
$postid,
'views_weekly',
wpp_get_views($postid, 'weekly', false)
);
}
}
add_action('wpp_post_update_views', 'custom_wpp_update_postviews');
となるわけですが、
ビュー数が更新されたとき、その投稿のその時のビュー数が「view_weekly」というカスタムフィールドに保存されます。
で、あとはいつも使っているWP_Queryで
$args = array(
'post_type' => 'post',
'meta_key' => 'views_weekly',
'orderby' => 'meta_value_num',
'order' => 'DESC',
'posts_per_page' => '3',
);
$top_posts = new WP_Query($args);
と、してやれば簡単にできますよ。
ってことですね。
個人的には
フィルターフック「wpp_post」を使って出力HTMLを変更したり、WPP_Queryを使ったり(今は非推奨)とやり方はいろいろあるし知っておいて損はないと思うけど、今回記事にした方法でやるのが一番簡単で良いかなぁと思います。
あまりトラフィックの多いサイトで$accuracyの値を100とかにしてサーバーに負荷かけないようにだけ注意していただければ。