【WordPress】ワードプレスにプラグイン無しで番号付きのページネーションを付けてみた

ワードプレスにプラグイン無しでページネーションを付けてみました。
ブログの一覧ページの一番下に表示している、番号が付いたナビゲーションが今回実装したページネーションです。

調べると色々なやり方があるので、どれが正解というものはありませんが、
僕が今回参考にしたのはこちらのサイト

WordPressでページャー(ページネーション)をプラグインなしで実装

それでは実践です。

function.phpにコードをコピペ

以下のコードを丸っとfunction.phpにコピペします。

/**
* ページネーション出力関数
* $paged : 現在のページ
* $pages : 全ページ数
* $range : 左右に何ページ表示するか
* $show_only : 1ページしかない時に表示するかどうか
*/
function pagination( $pages, $paged, $range = 2, $show_only = false ) {

$pages = ( int ) $pages; //float型で渡ってくるので明示的に int型 へ
$paged = $paged ?: 1; //get_query_var('paged')をそのまま投げても大丈夫なように

//表示テキスト
$text_first = "« 最初へ";
$text_before = "‹ 前へ";
$text_next = "次へ ›";
$text_last = "最後へ »";

if ( $show_only && $pages === 1 ) {
// 1ページのみで表示設定が true の時
echo '<div class="pagination"><span class="current pager">1</span></div>';
return;
}

if ( $pages === 1 ) return; // 1ページのみで表示設定もない場合

if ( 1 !== $pages ) {
//2ページ以上の時
echo '<div class="pagination"><span class="page_num">Page ', $paged ,' of ', $pages ,'</span>';
if ( $paged > $range + 1 ) {
// 「最初へ」 の表示
echo '<a href="', get_pagenum_link(1) ,'" class="first">', $text_first ,'</a>';
}
if ( $paged > 1 ) {
// 「前へ」 の表示
echo '<a href="', get_pagenum_link( $paged - 1 ) ,'" class="prev">', $text_before ,'</a>';
}
for ( $i = 1; $i <= $pages; $i++ ) {

if ( $i <= $paged + $range && $i >= $paged - $range ) {
// $paged +- $range 以内であればページ番号を出力
if ( $paged === $i ) {
echo '<span class="current pager">', $i ,'</span>';
} else {
echo '<a href="', get_pagenum_link( $i ) ,'" class="pager">', $i ,'</a>';
}
}

}
if ( $paged < $pages ) {
// 「次へ」 の表示
echo '<a href="', get_pagenum_link( $paged + 1 ) ,'" class="next">', $text_next ,'</a>';
}
if ( $paged + $range < $pages ) {
// 「最後へ」 の表示
echo '<a href="', get_pagenum_link( $pages ) ,'" class="last">', $text_last ,'</a>';
}
echo '</div>';
}
}

index.phpに表示コードをコピペ

次に以下の表示用コードをindex.phpにコピペします。
僕のブログでは、一覧ページがindex.phpなので、
archive.php等、ご自身のサイトに合わせてコピペしてください。

if ( function_exists( 'pagination' ) ) :
pagination( $wp_query->max_num_pages, get_query_var( 'paged' ) );
endif;

コピペする場所は、記事投稿のコードの終わりと、記事が無い時に表示される文言の間です。

具体的な表示用コードの全文はこちら。

<?php if ( have_posts() ) : /** ループ開始 */
while ( have_posts() ) : the_post(); ?>
<?php $terms = wp_get_object_terms($post->ID, 'blog_cat'); ?>
<div class="post flex">
<a href="<?php the_permalink(); ?>" class="thumbnail-box"><?php the_post_thumbnail(); ?></a>
<div class="summary">
<h3><a href="<?php the_permalink(); ?>"><?php the_title(); ?></a></h3>
<time datetime="<?php echo get_the_date( 'Y-m-j' ) ?>"><?php the_time( get_option( 'date_format' ) ); ?></time>
<ul class="category-tag">
<?php foreach ( $terms as $term ) : ?>
<li class="<?php echo "$term->slug"; ?>"><?php echo esc_html( $term->name ); ?></li>
<?php endforeach; ?>
</ul>
<p class="btn"><a href="<?php the_permalink(); ?>" class="thumbnail-box">READ MORE</a></p>
</div>
</div>
<?php endwhile;

if ( function_exists( 'pagination' ) ) :
pagination( $wp_query->max_num_pages, get_query_var( 'paged' ) );
endif;

else : ?>
<div class="post">
<h3>Not Found</h3>
<p>Sorry, but you are looking for something that isn't here.</p>
</div>
<?php endif; /** ループ終了 */ ?>

17〜23行目はもしかしたら下記のように書くのが正解かもしれません。

<?php endwhile; ?>
<?php
if ( function_exists( 'pagination' ) ) :
pagination( $wp_query->max_num_pages, get_query_var( 'paged' ) );
?>
<?php endif; ?>
<?php else : ?>

両方動きとしては問題ありませんが、この辺は自己責任でお願いいたします;-)

CSSをコピペ

最後にCSSをコピペします。

.pagination {
display: flex;
align-items: center;
justify-content: center;
margin: 40px 0;
position: relative;
font-size: 13px;
}

.pagination span,
.pagination a {
display: block;
width: auto;
margin: 4px;
padding: 8px;
border: 1px solid #555;
text-decoration: none;
text-align: center;
line-height: 16px;
}

/* ページ番号 */
.pagination .pager {
width: 32px;
}

/* ホバー時 & 現在のページ */
.pagination a:hover,
.pagination .current {
color: #fff;
border-color: #555;
background-color: #555;
}

/* 前へ */
.pagination a.prev {
margin-right: 16px;
}
/* 次へ */
.pagination a.next {
margin-left: 16px;
}
/* 最初へ */
.pagination a.first {}
/* 最後へ */
.pagination a.last {}

/* Page x / y */
.pagination span.page_num {
display: none;
}

参考サイトでは背景色が#000の真っ黒でしたが、
僕は少しグレー寄りの黒が好きなので#555にしています。

Underscores(_s、アンダースコアズ)での使い方

スターターテーマであるアンダースコアズで実装する場合は、少し編集が必要です。
下記はアーカイブを表示するarchive.phpの初期のコードを抜粋したものです。

<main id="primary" class="site-main">

<?php if ( have_posts() ) : ?>

<header class="page-header">
<?php
the_archive_title( '<h1 class="page-title">', '</h1>' );
the_archive_description( '<div class="archive-description">', '</div>' );
?>
</header><!-- .page-header -->

<?php
/* Start the Loop */
while ( have_posts() ) :
the_post();

/*
* Include the Post-Type-specific template for the content.
* If you want to override this in a child theme, then include a file
* called content-___.php (where ___ is the Post Type name) and that will be used instead.
*/
get_template_part( 'template-parts/content', get_post_type() );

endwhile;

the_posts_navigation();

else :

get_template_part( 'template-parts/content', 'none' );

endif;
?>

</main><!-- #main -->

26行目のthe_posts_navigation();でページネーションを表示しているので、ここを変更します。
このコードの前後でPHPタグを使いたいので、下記のように書き換えます。

<main id="primary" class="site-main">

<?php if ( have_posts() ) : ?>

<header class="page-header">
<?php
the_archive_title( '<h1 class="page-title">', '</h1>' );
the_archive_description( '<div class="archive-description">', '</div>' );
?>
</header><!-- .page-header -->

<?php
/* Start the Loop */
while ( have_posts() ) :
the_post();

/*
* Include the Post-Type-specific template for the content.
* If you want to override this in a child theme, then include a file
* called content-___.php (where ___ is the Post Type name) and that will be used instead.
*/?>
<?php get_template_part( 'template-parts/content', get_post_type() );

endwhile; ?>

<?php the_posts_navigation(); ?>

<?php else :

get_template_part( 'template-parts/content', 'none' );

endif;
?>

</main><!-- #main -->

そしてここから、26行目の
<?php the_posts_navigation(); ?>
先ほどの

<?php
if ( function_exists( 'pagination' ) ) :
pagination( $wp_query->max_num_pages, get_query_var( 'paged' ) );?>
<?php endif;
?>

に置き換えます。

完成形

最終的なコードは以下になります。

<main id="primary" class="site-main">

<?php if ( have_posts() ) : ?>

<header class="page-header">
<?php
the_archive_title( '<h1 class="page-title">', '</h1>' );
the_archive_description( '<div class="archive-description">', '</div>' );
?>
</header><!-- .page-header -->

<?php
/* Start the Loop */
while ( have_posts() ) :
the_post();

/*
* Include the Post-Type-specific template for the content.
* If you want to override this in a child theme, then include a file
* called content-___.php (where ___ is the Post Type name) and that will be used instead.
*/?>
<?php get_template_part( 'template-parts/content', get_post_type() );

endwhile; ?>

<?php
if ( function_exists( 'pagination' ) ) :
pagination( $wp_query->max_num_pages, get_query_var( 'paged' ) );?>
<?php endif;
?>

<?php else :

get_template_part( 'template-parts/content', 'none' );

endif;
?>

</main><!-- #main -->

これでアンダースコアズにも番号付きのページャーが実装出来ます。