WordPressのページネーションをセレクトボックスにカスタマイズする

WordPressに限らずではあるが、ページネーションは数が増えると美しくなくなってくる。そんな時に数字部分をセレクトボックスに変更する方法。プラグイン未使用。


まず、WordPress標準のページネーションを出力する paginate_links 関数は type オプションで出力形式を変更できるが、いずれもhtml状態で出力されてしまうため、そのままではセレクトボックスに変更しにくい。
今回は paginate_links 関数の type オプション array で出力されるhtmlタグから必要な情報を抜き出してセレクトボックス型に変更する。
以下を pagination.php
として使用しているテンプレートディレクトリに保存する。簡易的にstyleも入れているがサイトに応じて要調整。
<?php
// ページネーションをセレクトボックスにする
//paginate_linksでページネーション情報を取得
$paginate_links = paginate_links( array(
'show_all' => true,
'type' => 'array',
));
// ページネーション情報を格納する配列
$pagination = array(
'prev' => null,
'next' => null,
'num' => array(),
'max' => 0
);
// paginate_linksから正規表現で必要な部分を取り出す
if(isset($paginate_links)) {
$regexLink = "|<a.*?href=\"(.*?)\".*?>(.*?)</a>|mis";
$regexCurrent = "|<span.*?>(.*?)</span>|mis";
foreach( $paginate_links as $link ) {
// 前へリンク
if (preg_match('/prev/', $link)) {
preg_match_all($regexLink, $link, $matches);
$pagination['prev'] = [
'label' => $matches[2][0],
'href' => $matches[1][0],
];
// 次へリンク
} elseif (preg_match('/next/', $link)) {
preg_match_all($regexLink, $link, $matches);
$pagination['next'] = [
'label' => $matches[2][0],
'href' => $matches[1][0],
];
// ページ番号リンク
} elseif (preg_match('/page-numbers/', $link)) {
// 現在のページ番号
if (preg_match('/current/', $link)) {
preg_match_all($regexCurrent, $link, $matches);
$pagination['num'][] = [
'current' => 1,
'label' => $matches[1][0],
'href' => '',
];
$pagination['max'] = $matches[1][0];
// その他のページ番号
} else {
preg_match_all($regexLink, $link, $matches);
$pagination['num'][] = [
'label' => $matches[2][0],
'href' => $matches[1][0],
];
$pagination['max'] = $matches[2][0];
}
}
}
}
// ページネーション表示
echo '<div class="pagination" id="pagination">';
// 前へリンク表示
if(isset($pagination['prev'])) {
echo '<a href="'.$pagination['prev']['href'].'"><svg width="48" height="48" viewBox="0 0 48 48"><path d="M27,17l-7,7,7,7" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" /></svg></a>';
}else{
echo '<a href="" tabindex="-1"><svg width="48" height="48" viewBox="0 0 48 48"><path d="M27,17l-7,7,7,7" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" /></svg></a>';
}
// ページ番号select表示
if(!empty($pagination['num'])) {
echo '<select onchange="this.disabled = true; setTimeout(() => this.disabled = false, 3000);document.location.href = this.options[this.selectedIndex].value;">';
foreach( $pagination['num'] as $array ) {
if(isset($array['current'])) {
echo '<option value="" selected>'.$array['label'].' / '.$pagination['max'].'</option>';
}else{
echo '<option value="'.$array['href'].'">'.$array['label'].' / '.$pagination['max'].'</option>';
}
}
echo '</select>';
}else{
echo '<div><select disabled>';
echo '<option value="" selected>1 / 1</option>';
echo '</select></div>';
}
// 次へリンク表示
if(isset($pagination['next'])) {
echo '<a href="'.$pagination['next']['href'].'"><svg width="48" height="48" viewBox="0 0 48 48"><path d="M21,17l7,7-7,7" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" /></svg></a>';
}else{
echo '<a href="" tabindex="-1"><svg width="48" height="48" viewBox="0 0 48 48"><path d="M21,17l7,7-7,7" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" /></svg></a>';
}
echo '</div>';
?>
<!-- css -->
<style>
.pagination {
display: flex;
align-items: center;
justify-content: center;
font-size: 16px;
color: #333;
padding: 1em;
margin: 0;
a {
height: 3em;
width: 3em;
padding: 0;
margin: 0;
display: flex;
align-items: center;
justify-content: center;
color: currentColor;
&[href=""] {
pointer-events: none;
opacity: 0;
}
}
svg {
display: block;
width: 100%;
height: 100%;
padding: 0;
margin: 0;
}
select {
appearance: none;
display: block;
height: 3em;
width: 100%;
max-width: 10em;
padding: 0.8em;
margin: 0 0.5em;
line-height: 1;
color: currentColor;
text-align: center;
text-align-last: center;
font-size: 100%;
border: 1px solid rgba(0,0,0,0.05);
background-color: #fff;
&[onchange] {
padding-right: 2em;
background-image: url('data:image/svg+xml;charset=utf8,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%2248%22%20height%3D%2248%22%20viewBox%3D%220%200%2048%2048%22%3E%3Cpath%20d%3D%22M27%2C27l3%2C3%2C3-3m0-6-3-3-3%2C3%22%20fill%3D%22none%22%20stroke%3D%22%23333%22%20stroke-width%3D%222%22%20stroke-linecap%3D%22round%22%20%2F%3E%3C%2Fsvg%3E');
background-repeat: no-repeat;
background-position: right center;
}
&[disabled] {
opacity: 0.6;
}
}
}
</style>
テンプレートのページネーションを表示したい場所に以下を記述すればページネーションが表示される。
<?php get_template_part('pagination'); ?>

当サイトのページネーションも同じものを使用している。
https://yamada-original.com/#pagination
セレクトボックス型にするとPCとスマホでの表示も統一されやすくて良いかもしれない。