WordPressの任意のテーブルから情報を出す時のページネーション

WP-PageNaviを利用することで、「前へ、次へ」リンクではなく、ページ数を指定して飛べる、下の図のようなページナビを出すことができます。

ページネーションの例。これはAmazonの検索結果ページの一番下に出るもの。

ですが、投稿ではない別のテーブルの場合にはこれが使えないので、下記のようにしてみました。
また、作成にあたってはゆりこさんの、WP-PageNavi を使わずにナビゲーション表示をとても参考にさせてもらいました。ありがとうございます。

今回はマルチサイトを運用中に、全サイトからの最新投稿をストックしている別テーブルwp_site_postsから、最新の記事を持ってくるページの場合です。

global $wpdb, $wp_rewrite;

$posttype = 'post';
$totalPosts = $wpdb->get_var($wpdb->prepare("SELECT COUNT(*) FROM " . $wpdb->base_prefix . "site_posts WHERE post_type = %s", $posttype));
$paged = (get_query_var( 'paged' )) ? get_query_var( 'paged' ) : 1 ;
$ppp = get_query_var( 'posts_per_page' );
$paginate_base = get_pagenum_link(1);
$paginate_format = (substr($paginate_base, -1 ,1) == '/' ? '' : '/') .
user_trailingslashit('page/%#%/', 'paged');;
$paginate_base .= '%_%';
$totalPages = ceil( $totalPosts/$ppp );

echo paginate_links( array(
	'base' => $paginate_base,
	'format' => $paginate_format,
	'total' => $totalPages,
	'mid_size' => 3,
	'current' => ($paged ? $paged : 1),
));

$start = ( $paged - 1 ) * $ppp;
$query = $wpdb->prepare("SELECT * FROM " . $wpdb->base_prefix . "site_posts WHERE post_type = %s ORDER BY post_published_stamp DESC LIMIT %d, %d", $posttype, $start, $ppp);
$tmp_posts = $wpdb->get_results( $query, ARRAY_A );
foreach ($tmp_posts as $tmp_post) { ?>
	<li><a href="<?php echo $tmp_post['post_permalink']; ?>"><?php echo $tmp_post['post_title']; ?></a></li>
<?php }

ポイントは、最後のpaginate_linksという関数に5つの値を渡すところです。これらの値を何とかして自分で作ればよいわけです。

  • baseは、/page/2, /page/3といった現在何ページ目にいるのかを示すスラッグを取り除いたベースに和る部分のことです。ゆりこさんのポストからそのまま持ってくるとちゃんと動きます。
  • formatは、ページをどのように示すかで/page/数字に設定しています。ゆりこさんのポストでは、デフォルトのパーマリンクや?を使ったURLの場合についてもケアされています。僕はそういう形を使わないのでパス。(記事の最後に注あり。)
  • totalは、全部で何ページになるか=最後のページはいくつか、です。3行目で全ての記事の件数を取得して、5件目で1ページ毎にいくつの記事を表示するかを取得しているので、(全記事数/1ページ毎の記事数)を切り上げた数という風にしています。
  • mid_sizeは、現在のページの両サイドにいくつ分のページを表示するかの指定です。ページが多くなってきた時に使われます。
  • currentは現在地。

実際の表示は、22行目のところで現在のページに対して最適な件数だけを取得して表示させています。

今回はSQLが関わっているところなのでちょっと時間がかかりました。また、こうした方が速いよ、負荷少ないよ、ということがありましたら教えて下さいm(__)m。

追記:FBで教えてもらいました。 @jim0912さん、いつもありがとうございます!

注:
formatの箇所に関して、ゆりこさんのコードでは、下記のようになっています。

if (strpos($paginate_base, '?') || ! $wp_rewrite->using_permalinks()) {
	$paginate_format = '';
	$paginate_base = add_query_arg('paged', '%#%');
} else {
	$paginate_format = (substr($paginate_base, -1 ,1) == '/' ? '' : '/') .
	user_trailingslashit('page/%#%/', 'paged');;
	$paginate_base .= '%_%';
}

僕はページネーションをしつつ?を使ってパラメータも渡したいので今回はやっていないのですが、デフォルトのパーマリンクのままで、こういったことをやりたい場合には、上記の8,9,10行目をゆりこさんのものに置き換えて使ってください。

↓ プラグインを作る方々への本、書きました。 ↓

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です