前回はページビューを記録する機能をワードプレスに実装しましたので、今回はその記録されたページビューのデータを使用して記事一覧ページの表示順をページビュー順に変更してみます。併せて、最終更新日順やメニューオーダー順でも並べ替えられるようにし、これらを画面の再読込なしで切り替えられるようAjaxで実装します。
2019年3月5日
まずは完成形の確認です。当サイトの記事一覧ページに実際に実装されていますが、右上の青いアイコンをクリックすると表示が切り替わります。左からメニューオーダー順、最終更新日順、ページビュー順になっています。Ajaxを使用していますので画面の再読込なしで切り替わります。メニューオーダー順というのは管理画面での並び順で当サイトではプラグインIntuitive Custom Post Orderを使用して並び替えています。
このページを最初に読み込んだ時には表示順はランダムになっています。リロードするたびに並び順が変わるかと思います。ランダム表示については『投稿一覧をランダムに表示する』で解説しています。
最終的には並び順をAjaxを使用して切り替えられるようにしますので、その処理がしやすいように並び順を変えるスクリプトはfunctions.phpにユーザー定義関数として実装していきます。まずはページビュー順に並べるsort_orderby_pv()という関数から作ります。いろいろなやり方があるかと思いますが今回もSQL文を使用して作成します。
■functions.php
function sort_orderby_pv() {
global $wpdb;
$posts = $wpdb->get_results("
SELECT ID, page_view, post_title, post_type, post_name, post_modified FROM $wpdb->posts WHERE ID in
(SELECT DISTINCT ID FROM $wpdb->posts WHERE post_type = 'wordpress_customize') ORDER BY page_view desc");
include_once 'posts-show.php';
}
ページビューの値はpostsテーブルのpage_viewカラムに入っています(前回『ページビューを記録して管理画面に表示する』で作成したカラム)。サブクエリを使用して重複を取り除いた後にpage_viewの値で降順に並べ替えています(ORDER BY page_view desc)。記事一覧を生成するのに必要なデータはID、page_view、post_title、post_type、post_name、post_modifiedだけですので、これらのデータをプロパティに持つ投稿オブジェクトとして引っ張り出しています。
posts-show.phpは実際に記事一覧を出力するhtml記述を生成するもので、SQL文で取り出された$postsには全ての投稿オブジェクトが入っていますので、foreachで一つずつ投稿オブジェクトを取り出しながら必要なhtmlを出力しています(ループ処理)。これでページビュー順に並んだ記事一覧の記述が生成されます。
<?php foreach ($posts as $post) : ?>
<div class="article">
<p class="modified"><i class="fa fa-pencil fa-fw"></i><?php echo esc_html(get_post_modified_time('Y年n月j日', false, $post->ID, false)); ?></p>
・
・
・
<?php endforeach; ?>
メニューオーダー順、最終更新日順もほぼ同じ記述です。メニューオーダー順はmenu_orderというカラムの値で昇順に並べます。最終更新日順はpost_modifiedというカラムの値で降順に並べます。これで3つのユーザー定義関数ができました。
sort_orderby_default()・・・メニューオーダー順
sort_orderby_modified()・・・最終更新日順
sort_orderby_pv()・・・ページビュー順
アイコン部分の記述は以下のようになります。Ajaxで処理の分岐がしやすいようにdata属性を設定してあります。
<div id="sort">
<span data-mode="default" class="sort-btn fa-stack fa-lg" title="メニューオーダー順">
<i class="fa fa-circle fa-stack-2x"></i>
<i class="fa fa-bars fa-stack-1x fa-inverse"></i>
</span>
<span data-mode="modified" class="sort-btn fa-stack fa-lg" title="最終更新日順">
<i class="fa fa-circle fa-stack-2x"></i>
<i class="fa fa-pencil fa-stack-1x fa-inverse"></i>
</span>
<span data-mode="pv" class="sort-btn fa-stack fa-lg" title="ページビュー順">
<i class="fa fa-circle fa-stack-2x"></i>
<i class="fa fa-eye fa-stack-1x fa-inverse"></i>
</span>
</div>
例えばメニューオーダー順がクリックされた場合は下記jQueryでmodeという変数にdefaultという値が入ります(2行目)。最終更新日順ではmodeにmodifiedという値が入り、ページビュー順ではmodeにpvという値が入り_ajax.phpにmodeというパラメータの値として送信されます(8行目)。_ajax.phpは今回は/_ajaxでアクセスできる固定ページになっています。
Ajaxリクエストの結果として返ってきた値(記事一覧のhtml記述)を記事一覧全体を囲むdiv要素(#posts)の中身として書き換えています(12行目)。
$('#sort').on('click', '.sort-btn', function() {
const mode = $(this).data('mode');
$.ajax({
url: '/_ajax',
type: 'POST',
dataType: 'html',
data: {
'mode': mode
}
})
.done(function(response) {
$('#posts').html(response);
})
.fail(function(response) {
console.log('error');
})
})
Ajaxリクエストを受け取る_ajax.phpの記述ですが、渡ってきたmodeの値によってswitch文を使用して処理を振り分けています。これでfunctions.phpで定義した3つのユーザー定義関数のいずれかが走ってhtml記述が生成され画面が描画されます。
■_ajax.php
<?php if ($_SERVER['REQUEST_METHOD'] === 'POST') {
if (!isset($_POST['mode'])) {
exit;
}
switch ($_POST['mode']) {
case 'default':
sort_orderby_default();
break;
case 'modified':
sort_orderby_modified();
break;
case 'pv':
sort_orderby_pv();
break;
}
}
Ajaxリクエストはwp-adminディレクトリーのなかのadmin-ajax.phpにリクエストする方法もあります。ただし、コーデックスにも書かれているようにwp-adminディレクトリーにベーシック認証をかけていると今回のようなフロントで使用するAjaxリクエストはadmin-ajax.phpには通りませんのでご注意下さい。
・WordPress の安全性を高める – WordPress Codex 日本語版
また、Ajaxを使用して差し替えるコンテンツは元のhtml上には記述がないですから検索エンジンにはコンテンツとして認識されません。したがって、記事ページの遷移などでAjaxを使用するとせっかく作った記事がインデックスされないことになりますので使いどころに注意が必要です。
以上で「Ajaxで記事一覧を切り替える(ページビュー順、更新日順、メニューオーダー順)」の解説を終わります。