はじめに
WordPressではページネーションを簡単に実装できますが、
固定ページや投稿ページの影響等で上手くページネーションが反映されない(ページネーションは出来たのにナビゲーションが表示されない)ことがあります。
ここでは私が簡単に解決することができた方法を載せますので、同じ状況にある方はぜひ試していただければ幸いです。
WordPressのページネーション
WordPressではブログやネットニュースのように記事を投稿できる機能があり、投稿した記事のリンク等を表示することができます。
記事を一覧表示するようなページでは、記事の数があまりに多いと1ページに表示するには無理がある場合があります。その際に数ページに分けて表示を行うことをページネーションといいます。
例えば、よく使われるコードとしては
以下のようなものが挙げられます。
<?php
if(have_posts()): //have_posts()は記事が存在するかどうか
while (have_posts()):
the_post(); //記事を取得
?>
<!-- HTML等をつかって取得した記事を反映する -->
<?php
endwhile;
endif;
the_posts_pagination(パラメータ配列); //ページネーションを行ってくれる関数
wp_reset_postdata(); //この関数は必ず書いておきましょう
?>
問題点
これが最も簡単にページネーションを実装できるコードではないでしょうか。
しかし、実はこのコードでは固定ページではページネーションが実装できず、投稿ページに指定したページのみでしかページネーションを実装できないという問題点があります。
またWordPressでは通常、投稿ページに1ページしか指定できず、この方法ではページネーションを簡単に行うことが限られてしまいます。
代替案
ですが、WordPressではほかにもページネーションを行う方法が存在しています。
それは「WP_Query」という関数を使って記事を取得する方法です。
先ほどの方法と比べると少し複雑にはなりますが、それでも比較的簡単にページネーションを実装することができます。
例えば、以下のコードで
ページネーションを実装できます。
<?php
$paged = get_query_var('paged', 1); //現在ページを取得
$args = array(
"paged" => $paged, //ページングに必要になるので書いておきましょう
/*ほかにも並べ替えや昇順降順の指定などを
この配列でしておきます。 */
);
$my_posts = new WP_Query($args); //記事取得
if($my_posts->have_posts()): //have_posts()は記事が存在するかどうか
while ($my_posts->have_posts()):
$my_posts->the_post(); //記事を取得
?>
<!-- HTML等をつかって取得した記事を反映する -->
<?php
endwhile;
endif;
paginate_links(パラメータ配列); //ページネーションを行ってくれる関数
wp_reset_postdata(); //この関数は必ず書いておきましょう
?>
このように、必要な関数が変わっていたりと少し勝手が違ってきますが、これでページネーションを実装することはできます。
さらにこちらの実装方法なら固定ページ・投稿ページ関係なくページネーションを実装できます。
ページネーションは実装できたけど…
これでページネーション実装問題は解決しました。
しかし、この方法では…
なぜかスタイルが反映されない!!!
もっときれいなスタイルにしたい!!!
…といった問題が発生しました。(これについては原因が分かっておらず、自分はここで3~4時間ほど時間を取られてしまいました。)
恐らく、the_posts_pagination()を使った際に生成されるHTMLタグとpaginate_links()を使った際に生成されるHTMLタグの内容(親要素やクラス)に違いがあったためではないかと考えています。
最終的な解決法
最終的に自分がとった解決策としては、
1.まず、適当なページを投稿ページとして設定し、the_posts_pagination()を用いてページングを行う
2.ページングを行ったときに生成されたHTMLコードを確認する
3.paginate_links()を用いて生成したHTMLコードとの違いを確認する
4.違った個所を直接PHPから反映するようにコードを書く
この手順を踏みました。最終的に以下のコードになりました。
<?php
$paged = get_query_var('paged', 1);
$args = array(
"paged" => $paged,
"post_type" => "post",
"orderby" => "date",
"order" => "DESC"
);
$my_posts = new WP_Query($args);
if($my_posts->have_posts()):
while ($my_posts->have_posts()):
$my_posts->the_post();
?>
<!-- HTML等をつかって取得した記事を反映する -->
<?php
endwhile;
endif;
$page_links = paginate_links(
'total' => $my_posts->max_num_pages, //最大ページ数
'mid_size' => 1,
'prev_next' => false,
'next_type' => false,
'type' => 'array' //ここが重要。ページングのデータを配列にしておきます
);
if($my_posts->max_num_pages > 1): //2ページ以上の時だけページングします
echo '<nav class="navigation pagination" role="navigation"aria-label="投稿">
<div class="nav_links">
<ul class="page-numbers">';
foreach($page_links as $link):
echo '<li>';
echo $link;
echo '</li>';
endforeach;
echo '</ul></div></nav>'
endif;
wp_reset_postdata(); //この関数は必ず書いておきましょう
?>
このように行うことで、無事にスタイルの反映されたページネーションを反映することができました。(かなり強引ですね…)
自分もまだよくわかっていないのですが、もしWordPress側が作ってくれるページネーションのHTMLコードを変えることができないなら、上記と同じコードでページネーションを実装すればスタイルも自由にできるのかもしれませんね。
終わりに
今回はWordPressにおけるページネーションの実装方法と、実装できない際の解決法について書いてみました。WordPressもPHPもまともに触ったことのないトーシローなので、ひょっとしたら間違っている点もあるかもしれませんが、自分の備忘録ついでに書き残しておきます。
自分がQiitaに記事を投稿するのは今回が初めてでとても新鮮でした。これからも備忘録ついでに何か書き残すかも…