2014年にこのblogで「直近1ヶ月に投稿した記事の人気順位を表示するテンプレートを作りました」という記事を書いて、このblogでも使っていました。
今日、ふとそのページを見ると正常に動いていません。おかしいなぁ~と思ってテンプレート自体を変更してみました。そのエラーの原因と直した方法について書きます。
直近1ヶ月に投稿した記事の人気順位がおかしかった件
このblogでは、
about>直近1ヶ月の人気投稿 をクリックするとここ1ヶ月に投稿した記事が人気順に表示されるようになっています。しかし、表示が
こんな風に3つしかされないようになってしまっていました。blogは平日毎日書いているので1ヶ月で3つしか投稿していないはずはありません。おかしい…ずっと正常に動いていたのに… と原因を考えてみました。
WordPress.comとWebサイトが連携しているサイトでは各投稿のView数が保存されているのでこのテンプレートはそのView数を参照して使っています。
[ryus_blogcard url=”https://usortblog.com//recentonemonthpostedpopular/”]
こちらの記事でその方法について書いてあります。今確認したところ新しくプラグインを入れるとか、書いてありますが、それは必要ありませんでした(^_^;。昔は結構まだよくわかってなくて、、すみません。
そのときのテンプレートのコードは
・stats_get_csv という関数を使ってView数を取得する
・パラメーターとしてView数の参照日数=無制限、記事数の制限=無制限(すべての投稿のView数を取得)
・全件取ってきてから投稿日がこの1ヶ月のものだけ、をリスト表示
というロジックになっていました。
今時点でのこのコードで取得できたデータを全件見てみると503件しかありません。今現在のこのblogの投稿数は605件なので全件取れてきていません。。。ということは
・stats_get_csv という関数で件数を無制限にしても、取得できる件数は503件(ちょっと半端ですが)ではないか?
と推測しました。そもそも全件取ってきて日付で判定、というロジックは美しくないし当時みたいに数が少なければまぁ良かったですが(いいのか?)、このコードは気に入っていませんでした。
テンプレートのロジックを変えてみる
ということでテンプレートのロジックを変えてみることにしました。
stats_get_csv という関数には post_id というパラメーターもあるため、記事を指定してView数を取得することができます。
参考:Jetpack – stats_get_csv period parameter
ということを踏まえて、
・ここ1ヶ月に投稿した記事のIDを取得しておく
・View数の参照日数 無制限、記事数の制限 1、post_id指定でView数を取得して、IDごとの配列にView数を保存する
・保存した配列をView数の降順にsortする
というロジックにすればうまく表示できそうです。
テンプレートのロジックを変更してみた
考えたロジックでテンプレートを修正してみました。最初から作る場合はお使いの子テーマの page.php をコピーしてお好きな名前に変更します(例:page-recentOnemonthPostedPopular.php)。
ファイルを開いて、テンプレートだとわかるような記述を一番上に挿入します。
<?php /** Template Name: page-recentOnemonthPostedPopular */ ?>
Template Name は固定ページの属性 テンプレートのリストボックスに表示されるので、他のテンプレートと重ならないような名前にします。
このPHPにはコンテンツを表示する部分がありますのでその部分を置き換えます。 たとえばSimplicityのpage.php(のコピー)であれば、
<?php the_content(); //本文の呼び出し?>
こんな感じのところです。twentyfourteenでは、
<?php // Start the Loop. while ( have_posts() ) : the_post(); // Include the page content template. get_template_part( 'content', 'page' ); // If comments are open or we have at least one comment, load up the comment template. if ( comments_open() || get_comments_number() ) { comments_template(); } endwhile; ?>
こんな感じのところです。テーマによって違うのでそれぞれコンテンツをどこで表示しているのかを探します。
その部分を以下のコードで置き換えます。
<?php // 過去1ヶ月分の投稿のpost_id、日付、タイトルを取得 $today = getdate(); $oneMonthBeforeY = date("Y",strtotime("-1 month")); $oneMonthBeforeM = date("m",strtotime("-1 month")); $oneMonthBeforeD = date("d",strtotime("-1 month")); $args = array( 'date_query' => array( array( 'compare'=>'BETWEEN', 'inclusive'=>true, 'after' => array( 'year' => $oneMonthBeforeY, 'month' => $oneMonthBeforeM, 'day' => $oneMonthBeforeD, ), 'before' => array( 'year' => $today['year'], 'month' => $today['mon'], 'day' => $today['mday'], ), ), ), ); $the_query = new WP_Query( $args ); $monthPostIdArray = array(); // The Loop if ( $the_query->have_posts() ) { echo '<ul>'; while ( $the_query->have_posts() ) { $the_query->the_post(); if ($post->post_status == "publish") { $monthPostIdArray[$post->ID] = 0; } } echo '</ul>'; } else { // no posts found echo "<br>no posts found"; } // 1ヶ月分の投稿データのView数を取得して保存 $strArgs = 'days=-1&post_id=%s'; foreach ($monthPostIdArray as $key=>$val){ $top_post = stats_get_csv('postviews', sprintf($strArgs, $key)); if($top_post){ $monthPostIdArray[$key] = $top_post[0]['views']; } } // View数の降順でソート arsort($monthPostIdArray); // echo "<pre>";var_dump($monthPostIdArray);echo "</pre>"; ?> <h2>過去1ヶ月(<?php echo date("Y-m-d",strtotime("-1 month")). '~'.date("Y-m-d");?>)の投稿 読まれた順表示</h2> <ul> <?php $i = 0; foreach ( $monthPostIdArray as $key=>$val ) { $postValue = get_post($key); $i++; ?> <li style="list-style-type:none"><?php echo $i;?>. <a href="<?php echo get_permalink($key); ?>"><?php echo $postValue->post_title; ?></a> (<?php echo $val; ?> views <?php echo substr($postValue->post_date, 0, 10);?>) </li> <?php } ?> </ul>
保存します。
そして、そのファイルをアップロードして、
ダッシュボード 固定ページ>新規追加 をクリックし、
タイトルを入力して、ページ属性>テンプレート のリストボックスから先ほどアップしたファイルの Template Name に記述した名前を選択します。
これで、公開して表示してみると
このように直近1ヶ月の投稿が、View数の多い順にすべて表示されました(^^)/
[amazon_searchlink search=”WordPress デザイン”]
コメント