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とスマホでの表示も統一されやすくて良いかもしれない。



関連記事