広告

【WordPress】paginate_linksカスタマイズ:最終ページへのリンクや「…」をページネーションで非表示にする

アイキャッチ WordPress

通常、WordPressのページネーションリンクでは、1ページ、2ページ、3ページ目などの隣接したリンクと合わせて、一番最初や一番最後のページへのリンクが表示されます。

WordPressブログの構成によっては、過去の記事への注目を意図的に下げたい場合や、投稿数のボリュームを計られたくないなどの理由により、この最終ページへのリンクなどの表示をオフにしたい場合などがあるかと思います。

ページネーションリンクの例。丸つけた部分を非表示にしたい

ここでは、WordPressブログでのページネーションリンクにおいて、最終ページへのリンクを非表示にする方法について解説します。

ページネーションリンクの表示関数 paginate_links()

まず、WordPressでのページネーションリンクの表示方法ですが、paginate_links()という関数を使って行います。

paginate_links()は出力用のパラメータを特に指定しなければデフォルトでHTMLを返しますので、echoなどでそのまま完成したページネーションリンクをHTML表示することが可能です。

echo paginate_links(array(
            'base' => '%_%',
            'format' => '?page=%#%',
            'mid_size' => 2,
            'current' => max(1, get_query_var('paged')),
            'total' => $loop->max_num_pages,
            'prev_text' => '<',
            'next_text' => '>',
        ));

このpaginate_links()関数のリファレンスを見てみると、いくつか表示のカスタマイズに関するパラメータがあることがわかります。

end_size
(整数) (オプション) ページ番号のリストの両端(最初と最後)にいくつの数字を表示するか。
初期値: 1
mid_size
(整数) (オプション) 現在のページの両側にいくつの数字を表示するか。ただし現在のページは含みません。
初期値: 2

引用元:関数リファレンス/paginate links – WordPress Codex 日本語版

‘end_size’ に0を指定しても非表示にならない

end_sizeの説明が「リストの両端にいくつの数字を表示するか」となっているので、こちらの値を0にしてあげれば期待する表示になりそうなのですが、実際に ‘end_size’ => 0を指定しても非表示になりません。

echo paginate_links(array(
            'base' => '%_%',
            'format' => '?page=%#%',
            'mid_size' => 3,
            'end_size' => 0, //0にしても機能しない
            'current' => max(1, get_query_var('paged')),
            'total' => $loop->max_num_pages,
            'prev_text' => '<',
            'next_text' => '>',
        ));

これは、end_sizeの値が1未満($end_size < 1)の場合に1に戻す内部処理があるためで、1以上の整数値以外の値が反映されないことが原因のようです。

ということで、paginate_links()関数のパラメータのみでは期待する表示にはできません。

paginate_links()関数で取得したHTMLを加工する

ページネーションのリスト両端のリンクは、paginate_links()関数のパラメータ「’end_size’ => 0」で表示を消すことができないため、別の方法で対応します。

まず、paginate_links()関数の ‘type’ パラメータを使い、echoなどで直接表示を出力せずにいったん情報を別の場所に取得します。

‘type’ => ‘array’ とすることでページネーションの内容を配列に格納できるので、ここではこの方法で進めます。

$paginate_args = array(
    'base' => '%_%',
    'format' => '?page=%#%',
    'mid_size'  => 3,
    'current' => max(1, get_query_var('paged')),
    'total' => $loop->max_num_pages,
    'prev_text' => '<',
    'next_text' => '>',
    'type' => 'array', //配列で取得
);
$paginate_links = paginate_links($paginate_args);

そして、現在表示中のページ番号の値を基準に、配列の置換処理を行います。

配列にはタグの内容がそのまま入っているので、残しておきたいタグに対してマッチする文字列を正規表現で指定し、array_filter()を使ってマッチしない要素を破棄する処理になります。

$current = $paginate_args['current'];
$allowed = [ //URL書式のパターン入力
    '/ current/u', //現在のページ
    '/prev /u', //前へ
    '/next /u', //次へ
    sprintf( '/\/page\/%d(\/|")/u', $current-2 ),
    sprintf( '/\/page\/%d(\/|")/u', $current-1 ),
    sprintf( '/\/page\/%d(\/|")/u', $current+1 ),
    sprintf( '/\/page\/%d(\/|")/u', $current+2 ),
];

if(!empty($paginate_links)) {
    $paginate_links = array_filter( // $allowedにマッチしない要素を破棄する
        $paginate_links,
        function($value) use ($allowed) {
            foreach((array)$allowed as $tag) {
                if(preg_match($tag, $value))
                    return true;
            }
            return false;
        }
    );
}

「 current」、「prev 」、「next 」については、それぞれのタグのclassに指定されている文字列にマッチするようにしています。

sprintf()では、表示を残す配列要素にマッチする文字列を指定しています。ここでは、現在表示中のページの前後2ページを残すために、現在表示中のページ番号を$currentに格納し、その前後2ページ(-2、-1、+1、+2)のURLをテストする文字列として指定しています。

テストする文字列はリンク先のURLである「/page/%d」の書式にマッチするようにしていますが、WordPressのページネーションリンクの書式はこれ以外に「?page=%d」や、独自の書式を設定することもあるかと思いますので、これらも対応できるようにするには、対象のURL書式の正規表現を$allowed配列に加えていけばOKです。

sprintf( '/[\/\?\&\;]custom-paged=%d(\&|")/u', $c-1 ), //こんな感じで残したい表記を配列に加える

その後、$paginate_linksの配列に残されたHTMLをforeach()で表示してあげれば完了です。

if(!empty($paginate_links)) {
    foreach($paginate_links as $paginate_link) {
       echo $paginate_link;
    }
}

出力されるタグの指定によっては親要素の(<ul>とか)の表示処理を入れてあげるのを忘れずに。

WordPressではアーカイブページにアクセスするためにいくつかのURLの書式が用意されているため、実際にはもう少しURLの書式のパターンを考慮しておかなければ正しく表示されないケースがあるかもしれません。

ちなみに、URLの書式がマッチしなかった場合は「前へ」、「次へ」と「現在のページ」の3つのボタンのみが表示される状態になると思いますので、このようになった場合はURLの書式と正規表現が正しくマッチするかどうかを疑ってみてください。

正規表現の書き方次第でもう少しスマートに動かせると思いますが、細かい部分はご自身の環境に合わせてカスタマイズしてみてください。

コメント

タイトルとURLをコピーしました