【WordPress】ページネーションを自作する方法

2018年9月1日
WordPress

WordPressでページネーションを設置する際に、プラグインを使いたくなかったため自作した。

ページネーション
ページネーション

手順

ページネーションを表示するクラスを定義する

下記のクラスをPHPファイルに定義する。

出力するタグやそれに付与する属性を任意で指定するため、paginate_linksthe_posts_paginationなどの関数を使用せずに実装してある。

class Pagination {
	private function __construct() {}

    public static function show() {
        $max_number = self::get_max_number();
        if ( $max_number < 2 ) return;

        echo <<< 'EOT'
<div class="pagination">
    <ul class="items">
EOT;

        self::show_items( $max_number );
        echo '</ul></div>';
    }

    private static function get_max_number() {
        global $wp_query;
        
        return $wp_query->max_num_pages;
    }

    private static function show_items( $max_number ) {
        $current_number         = self::get_current_number();
		$showing_range          = 2;
        $showing_min_number     = max( $current_number - $showing_range, 1 );
        $showing_max_number     = min( $current_number + $showing_range, $max_number );
        $is_show_previous       = $current_number > $showing_min_number;
        $is_show_next           = $current_number < $showing_max_number;
        $is_show_before_dots    = $showing_min_number > 1;
        $is_show_after_dots     = $showing_max_number < $max_number;

        if ( $is_show_previous      ) self::show_previous_item( $current_number );
        if ( $is_show_before_dots   ) self::show_dots_item();

        for ( $i = $showing_min_number; $i <= $showing_max_number; $i++ ) {
            self::show_number_item( $i, $current_number );
        }

        if ( $is_show_after_dots    ) self::show_dots_item();
        if ( $is_show_next          ) self::show_next_item( $current_number );
    }

    private static function get_current_number() {
        /**
         * get_query_var( 'paged' ) は1ページ目の場合に
         * 0を返すため、その場合は1を返すように対応
         */
        return max( get_query_var( 'paged' ), 1 );
    }

    private static function show_previous_item( $current_number ) {
        $content    = '前へ';
        $attributes = 'class="item previous"';
        $uri        = get_pagenum_link( $current_number - 1 );

        self::show_item( $content, $attributes, $uri );
    }

    private static function show_next_item( $current_number ) {
        $content    = '次へ';
        $attributes = 'class="item next"';
        $uri        = get_pagenum_link( $current_number + 1 );

        self::show_item( $content, $attributes, $uri );
    }

    private static function show_dots_item() {
        $content    = '...';
        $attributes = 'class="item dots"';
        
        self::show_item( $content, $attributes );
    }

    private static function show_number_item( $number, $current_number ) {
        $is_current = $number === $current_number;
        $content    = $number;
        
        if ( $is_current ) {
            $attributes = <<< 'EOT'
class="item number current" aria-current="page"
EOT;
            $uri = null;
        }
        else {
            $attributes = 'class="item number"';
            $uri        = get_pagenum_link( $number );
        }

        self::show_item( $content, $attributes, $uri );
    }

    private static function show_item( $content, $adding_attributes = '', $uri = null ) {
        echo '<li>';

        $on_show = function() use( $content, $adding_attributes ) {
            printf( '<div %s>%s</div>', $adding_attributes, $content );
        };

        if ( $uri === null ){
            $on_show();
        }
        else {
            printf( '<a href="%s">', $uri );
            $on_show();
            echo '</a>';
        }

        echo '</li>';
    }
}

表示させたい箇所で関数を呼ぶ

テンプレートファイルの表示させたい箇所で下記の関数を呼ぶ。

Pagination::show();

これでその箇所に次のようなHTMLが出力される。

出力例

<div class="pagination">
    <ul class="items">
		<li>
			<div class="item number current" aria-current="page">1</div>
		</li>
		<li>
			<a href="http://sample.com/page/2">
				<div class="item number">2</div>
			</a>
		</li>
		<li>
			<a href="http://sample.com/page/3">
				<div class="item number">3</div>
			</a>
		</li>
		<li>
			<div class="item dots">...</div>
		</li>
		<li>
			<a href="http://sample.com/page/2">
				<div class="item next">次へ</div>
			</a>
		</li>
	</ul>
</div>

CSSで見た目を整える

後は出力されたHTMLの各要素に付いているクラスを用いて、CSSで見た目を整える。