記事一覧

一覧ページネーション を表示する

 posted by suzu
テンプレート作成のススメ

実は、今回から次のテンプレート作成 (の解説) に取り掛かろうと
思っていたのですが、解説ネタを書いていくにつれ、
前の記事 「HTMLタイトルを切り替える」 同様、
先に作成 (解説) しておいた方がよいものがあることに気付き、
急遽変更してこちらを先に作成することにしました。

アーカイブ一覧 (カスタムタクソノミー別、カテゴリ別、タグ別、作成者別、
日付別(年別、月別、日別)、カスタム投稿タイプ別) 等の一覧ページの場合、
記事が少ないうちはいいですが、多くなってくると、ページ遷移ができる
ページネーションが必須となってきます。
「前へ」 「次へ」 だけのリンクでチマチマとページ遷移していくのも
面倒なことも多いので、どうせなら、ページ番号によるページネーション
にした方が便利でしょう。

ということで、今回は、function.php に、ページ番号による
ページネーション部分を出力 (表示) する関数を作成したいと思います。

実は、参考 (というかほぼそのまんま) にさせてもらったサイトがあります。
WordPressにプラグイン無しでページネーションを設置する方法」 です。
こちらの記事の 「Pagination without plugin:拡張版」 が元ネタです。
こちらのサイトでも、実は、
How to Add WordPress Pagination Without a Plugin [Enhanced]
が元ネタのようです (笑) が、きちんと元ネタページを明記され、
リンクを貼ってあるので、好感が持てますね。
 

参考ページで掲載されているソースを整形はしていますが、
実際の処理内容は、ほぼそのままです。

/**
 * 一覧ページネーション出力
 * @param  int    $pages     総ページ数
 * @param  int    $range     前へ / 次へ のリンクを表示するレンジ
 */
function pagination($pages = 0, $range = 4) {
	$showitems = ($range * 2) + 1;

	global $paged;
	if (empty($paged)) $paged = 1;

	if ($pages == 0) {
		global $wp_query;
		$pages = $wp_query->max_num_pages;
		if (!$pages) $pages = 1;
	}

	if ($pages != 1) {
		echo '<!-- 一覧ページネーション -->' . "\n";
		echo '<div class="pagination"><span>Page ' . $paged . ' of ' . $pages . '</span>';
		if ($paged > 2 && $paged > $range + 1 && $showitems < $pages) echo '<a href="' . get_pagenum_link(1) . '">« First</a>';
		if ($paged > 1 && $showitems < $pages) echo '<a href="' . get_pagenum_link($paged - 1) . '">‹ Previous</a>';
		for ($i=1; $i <= $pages; $i++) {
			if ($pages != 1 && (!($i >= $paged + $range + 1 || $i <= $paged - $range - 1) || $pages <= $showitems)) {
				echo ($paged == $i) ? '<span class="current">' . $i . '</span>' : '<a href="' . get_pagenum_link($i) . '" class="inactive">' . $i . '</a>';
			}
		}
		if ($paged < $pages && $showitems < $pages) echo '<a href="' . get_pagenum_link($paged + 1) . '">Next ›</a>';
		if ($paged < $pages - 1 &&  $paged + $range - 1 < $pages && $showitems < $pages) echo '<a href="' . get_pagenum_link($pages) . '">Last »</a>';
		echo '</div><div class="clear" />' . "\n";
	}
}

まず、パラメータの説明も兼ねて、この関数の挙動について説明します。
パラメータ : $pages は、総ページ数を指定します。省略可能です。
パラメータ : $range は、現在表示中のページの前後何ページずつを
直接ページリンクで表示するかの値 (省略可能) を指定します。
「‹ Previous (前へ)」 や 「Next › (次へ)」 等の
直接ページリンク以外のリンクを表示するための閾値にもなります。
全ての直接ページリンクが表示できない場合は
「‹ Previous (前へ)」 や 「Next › (次へ)」 のリンクが表示され、
それよりもまだ前後のページが存在する場合は
「« First (先頭へ)」 や 「Last » (最終へ)」 のリンクが表示されます。

7行目の $showitems は、1ページあたりに最大でどれぐらいの
直接ページリンクを表示するかを算出しています。
現在表示中のページで1つ分、表示ページよりも前のページを $range 分、
表示ページよりも後のページを $range 分、
直接ページリンクを表示しますので、このような計算式になるわけです。

9・10行目の加工についてです。
前の記事 「HTMLタイトルを切り替える」 でも触れていますが、
アーカイブページ等の一覧ページの場合、グローバル変数 : $paged には、
現在表示中のページ番号が入ります。
もし、現在表示中のページ番号の値がなかった場合、1ページ目である
とみなして後続の処理を進めるための加工ですね。

12行目から16行目までのブロックです。
これは単に、総ページ数がパラメータで指定されなかった場合、
グローバルである $wp_query クラスの max_num_pages から
ページの合計数を取得しています。

ここからが実際のページネーションの出力部分になります。
そもそも1ページしかページがない場合は出力する必要はありませんので、
18行目の if 構文で除外しています。
20行目では 「表示中ページ番号 / 総ページ数」 を出力しています。

21行目では、

1. 現在表示ページが2ページ目よりも後である (3ページ目以降である)
2. 現在表示ページが [$range + 1] よりも後である
  cf.) $range = 4 の場合、5ページ目より後 (6ページ目以降)
3. 総ページ数が1ページに表示できる直接ページリンクの数を超えている
  cf.) $range = 4 の場合、9ページより大きい (10ページ以上)

の3つの条件を満たした場合に、「先頭へ」のリンクを出力しています。
22行目では、

1. 現在表示ページが1ページ目よりも後である (2ページ目以降である)
2. 総ページ数が1ページに表示できる直接ページリンクの数を超えている
  cf.) $range = 4 の場合、9ページより大きい (10ページ以上)

の2つの条件を満たした場合に、「次へ」 のリンクを出力しています。

23行目から27行目が 直接ページリンクを出力している for ブロック
になりますが、今々改めて見ると、効率の悪い回し方をしてますね・・・
for の繰り返し処理は、1 から 総ページ数分回していて、

1. 総ページ数が 1 ではない
2. a) 処理対象ページが [現在表示ページ + $range + 1] 以降でも
   [現在表示ページ - $range - 1] 以前でもない
  b) または、総ページ数が1ページに表示できる直接ページリンクの数以下である

上記 1、2 の条件を満たす場合のみ、
25行目にて、直接ページリンクを出力しています。
そもそも、1. の条件は、18行目の if の条件で処理から外しているので、
ここでの条件に加味してやる必要はないですよね・・・ orz
また、全ページ分ループしてその中の if で除外するよりも、
直接ページリンクの開始ページと終了ページを求めておいて、
必要な分だけループする方が効率よいと思うんですけど・・・
まぁ、私も使わせて貰っている分際なので不平は言えない立場ですけど。
そのうち直そう・・・
ちなみに、現在表示ページである場合は、
リンクではなくページ番号のみを出力しています。
echo をコンテキスト内で動作させるとエラーになりますので、
書き方に注意しましょう。
詳しくは 「echo と print の違い」 参照のこと。

28行目では、

1. 現在表示ページが 総ページ数 よりも前である (最終ページではない)
2. 総ページ数が1ページに表示できる直接ページリンクの数を超えている
  cf.) $range = 4 の場合、9ページより大きい (10ページ以上)

の2つの条件を満たした場合に、「次へ」 のリンクを出力しています。
29行目では、

1. 現在表示ページが [総ページ数 - 1] よりも前である (最終ページより2つ以上前)
2. [現在表示ページ + $range - 1] が総ページ数よりも前である
  cf.) 現在表示ページ = 2 / $range = 4 の場合、
     総ページ数は5ページより多い (6ページ以上)
3. 総ページ数が1ページに表示できる直接ページリンクの数を超えている
  cf.) $range = 4 の場合、9ページより大きい (10ページ以上)

の3つの条件を満たした場合に、「最終へ」 のリンクを出力しています。
 

では、ページネーション用のスタイルを style.css に追記します。

.clear {
	clear: both;
	margin: 0px;
	padding: 0px;
}
#main .pagination {				/* 一覧ページネーション */
	clear: both;
	margin: 0px 0px 20px 0px;
	padding: 20px 0px;
	position: relative;
	font-size: 10px;
	line-height: 12px;
}
#main .pagination span, #main .pagination a {
	display: block;
	float: left;
	margin: 2px 2px 2px 0;
	padding: 5px 7px 4px 7px;
	width: auto;
	background: #999999;
	color: #ffffff;
	text-decoration: none;
}
#main .pagination a:hover {
	background: #cccccc;
	color: #ffffff;
}
#main .pagination .current {
	padding: 5px 7px 4px 7px;
	background: #cccccc;
	color: #ffffff;
}

追記する場所はどこでも問題ありませんが、
clear 用のクラスはこれから汎用的に使う可能性が高いので
ベースのスタイルを記述している箇所の近くに、
一覧ページネーション自体のスタイルは
メインコンテンツの一覧表示のスタイル設定の直後にでも
追記しておくのが分かりやすくていいでしょう。
 

これで、ページ番号によるページネーションを表示する
関数とスタイルの準備ができました。
呼び出す側のテンプレートでは、ページネーションを表示させたい場所に

<?php
if (have_posts() && function_exists("pagination")) {
	// 一覧ページネーション
	pagination($wp_query->max_num_pages);
}
?>

のように追記します。
($wp_query->max_num_pages パラメータは指定しなくても構いません)
2行目の have_posts では記事があるかどうかを、
function_exists (PHP関数) では関数自体が存在するかどうかを判定し、
今回作成した関数を呼び出して、一覧ページネーションを表示します。
 

はぁ、これで今度こそ次回から違うテンプレートの作成 (解説) に
取り掛かれるハズ・・・

関連記事

eyecatch_template

作成するテンプレートを整理する

今回から、実際にテーマに必要なテンプレートの作成の準備に入ります。 先の記事 「...

記事を読む

eyecatch_template

index.php を作成する – [1]

先の記事 「作成するテンプレートを整理する」 で 作成すべきテンプレートを拾い出...

記事を読む

eyecatch_template

カラムレイアウトを考える

テンプレートを書き始める前に、基本的なレイアウト構成を考えてみます。 HTMLで...

記事を読む

「一覧ページネーション を表示する」へ1件のコメント

カレンダー

2018年12月
« 7月    
 1
2345678
9101112131415
16171819202122
23242526272829
3031  
PAGE TOP ↑