読者です 読者をやめる 読者になる 読者になる

残像ブログ

残像だった

WordPressでプラグインを使わずにページネーションする


プラグインを使わなくても上図のようなページ送り機能を実装できるとの事なのでやりました。
とっても参考:E03CA オートフォーカス壊れたっぽい へのコメント

前提として

  • 今回使用するWordPressのバージョンは3.1.2
  • ページネーションはカテゴリごとの記事一覧、タグごとの記事一覧、検索結果での記事一覧に設置する
  • コードはfunctions.phpに記載し、必要な場所で呼び出す。
  • 私の環境では動きましたが、本記事に記載したコードだとパーマリンク設定などの違いにより環境によっては上手くいかないかもしれません。

実装にはテンプレートタグの「paginate_links」を使う

そもそもWordPressでページネーションするには、カテゴリの記事一覧なら

http://example.com/cat/[カテゴリスラッグ]/page/[ページ番号]

タグの記事一覧なら

http://example.com/tag/[タグスラッグ]/page/[ページ番号]

検索結果なら

http://example.com/page/[ページ番号]?s=[検索文字列]

のようなURLにアクセスすればいいっぽい。
※設定によって若干異なるっぽい

そこでテンプレートタグのpaginate_linksにお願いする。
paginate_linksのリファレンス:Function Reference/paginate links « WordPress Codex
このテンプレートタグがほぼ自動的にページネーションを出力してくれるが、いくつかの引数に対して加工が必要で、主に手をかけるのがbase、formatの2つの引数

formatはページネーションURLでのページ番号の書式的なものを指定するのに使い、値内に含まれた「%#%」の部分がページ番号に置換される。
baseはその名の通りページネーションで生成するリンクURLのベースとなる部分で、値内に必ず「%_%」を含む。「%_%」の部分はformatの値に置換される。

生成するURLを指定して実装する

検索結果のページURLには「?s=検索ワード」が含まれており、カテゴリやタグの記事一覧とはURL構成が若干違う。
なので、baseやformatもページの種類によって変更する必要があるみたい。

上記を踏まえて、ページネーションを実装するコードをとりあえず示す。

functions.phpに記述

<?php
function my_paginate(){
	global $wp_query, $paged;

	$p_base = get_pagenum_link(1);
	$p_format = 'page/%#%';

	//?の有無確認、有る場合は場所を特定
	if($word = strpos($p_base, '?')){
	//?がある場合(検索結果)
		$p_base = get_option(home).(substr(get_option(home), -1 ,1) === '/' ? '' : '/')
			.'%_%'.substr($p_base, $word);
	} else{
	//?が無い場合(カテゴリ、タグ等)
		$p_base .= (substr($p_base, -1 ,1) === '/' ? '' : '/') .'%_%';
	}

 	echo paginate_links(array(
		'base' => $p_base,
		'format' => $p_format,
		'total' => $wp_query->max_num_pages,
		'current' => ($paged ? $paged : 1),
	)); 
}
?>

ページネーションしたい場所(index.phpなど)に記述

<?php my_paginate(); ?>
共通の説明

$wp_queryや$pagedはglobal宣言しとかないと動かないので注意(これでしばらく困ったのでメモ)

最初にget_pagenum_link(1)で今現在のURL的な物を取得して、baseに使う$p_base変数に入れる。
今回はformatの形式は検索結果・カテゴリともに同じにしたので共通部分で代入済みにする。

if文の判定で使用しているstrpos()は、文字列(ここでは$p_base)内に指定した文字(ここでは'?')が最初に見つかった位置を数値で返す。見つからない場合はFalseを返す。

検索結果ページの説明

検索結果ページのURLは下記のようにしたい。

http://example.com/page/[ページ番号]?s=[検索文字列]

【page/[ページ番号]】の部分はもうp_formatに入っているので、その前部分のホームURLをget_option(home)で取得する。
次にsubstr()でホームURLの末尾文字を取り出し、末尾が「/」でない場合は「/」を追加する(でないとformatとうまく繋がらないため)。
最後に?から後の部分をget_pagenum_link(1)で取得したURLからsubstrで取り出して合体させる。
これでbaseが出来あがる。

なおコード内で使用している「substr(略) === '/' ? '' : '/'」みたいなのは条件演算子と言うらしい。

[式] ? [真の時の処理] : [偽の時の処理]
カテゴリ・タグページの説明

カテゴリやタグの記事一覧のURLは下記のようにしたい。

http://example.com/[tagとかcatとか]/[スラッグ]/page/[ページ番号]

こっちの場合は単純で、get_pagenum_link(1)で取得したURLに「/」がついてなければ追加しする。
あとはformatに置換する「%_%」を追加してやればbaseが出来上がる。

paginate_linksの引数について

引数は配列で指定する重要なのはbaseとformatに加えて、

  • total:ページの総数(最大ページ数)記事の投稿数が30で1ページごとの表示数が3なら10ページ。ここではmax_num_pagesで自動的に取得。
  • current:現在のページ番号。$pagedに値がある場合はその値、無い場合は1ページ目としている。

その他の引数については以下の通りとなる

引数名 デフォルト値 説明
show_all False trueにするとページ番号を省略せずに全て表示する。
end_size 1 ページ番号が省略された時、リスト先頭と末尾に表示するページ番号の数。end_sizeが2、mid_sizeが1の時、12...456...89となる。
mid_size 2 現在のページ番号を起点に、左右に省略しないで表示するページ番号の数。mid_sizeが1で現在のページが4なら1...345...9、現在のページが1なら12...9となる。
prev_next True 前ページ、次ページへのリンクを表示するか否か
prev_text <<前ページへ 前ページへのリンク文字列を指定できる。
next_text 次ページへ>> 次ページへののリンク文字列を指定できる。
type plan ページリストの出力形式を指定できる。'plan':各ページにリンクしたテキストをそのまま表示、'array':コードは出力せずリストを配列に格納、'list':<ul>を出力

最後の二つ(add_args、add_fragment)はページネーションURLに指定した文字列を追加するっぽいけどよくわからん。

'type'=planで生成されるhtml


↑この状態のページネーションの場合は次のようなhtmlが生成される。

<a class="prev page-numbers" href="http://localhost/gallery/d_gray/page/3">&#171; 前ページへ</a>
<a class="page-numbers" href="http://localhost/gallery/d_gray/">1</a>
<span class="page-numbers dots">...</span>
<a class="page-numbers" href="http://localhost/gallery/d_gray/page/3">3</a>
<span class="page-numbers current">4</span>
<a class="page-numbers" href="http://localhost/gallery/d_gray/page/5">5</a>
<span class="page-numbers dots">...</span>
<a class="page-numbers" href="http://localhost/gallery/d_gray/page/7">7</a>

<a class="next page-numbers" href="http://localhost/gallery/d_gray/page/5">次ページへ &#187;</a>

まとめると表の通りになるので、これに合わせてCSSを適用すればよい。もしもっと個別に色々したい場合はtypeの指定を変えればできそう。

要素 クラス名
全ての要素 page-numbers
« 前ページへ prev
次ページへ » next
... dots
現在のページ番号 current