Scribble at 2020-05-08 22:55:36 Last modified: 2020-05-20 09:36:21

当サイトで公開しているページではなく会社の仕事でだが、新型コロナウイルス感染症にかかわる行政施策や補助金について、情報発信するサイトを WordPress で構築した。そろそろ記事が増えてきたので pagination を追加することにしたのだが、あいにくループで回して記事を表示しているわけではないため、pagination はプラグインを使わずに自力で HTML 要素を出力することにした(プレゼンテーションは要素が表示されたら CSS で何とでもなる)。何度か自力で実装したことはある。どうもこう、WP_Query() を好き勝手に回してデータを取り出してから HTML 要素を配置する方が好きにやれるという気分がしていて、ループを使うといちいちコンテクストを気にしなくてはいけないので、あまり使いたくないのである。ただ、ループを使わずに pagination を実装するとプラグインは使えなくなるから、prev, next, current といったステータスごとに要素を表示したり表示する内容を変える条件くらいは、正確にまとめておくと混乱が少なくなる。

まず最初に、表示する記事の総数を(別にいちいち WP_Query() を使う必要はないので)$p = wp_count_posts(); $count = $p->publish; で数えてセットする。次に、1ページごとに表示する記事の数を define( 'PER', 20 ) などと定義しよう。そして、現在のページを $_GET[ 'page' ] でやりとりする(面倒なので、$page = intval( substr( $_GET[ 'page' ], 0, 4 ) ) などとバリデートしておく)。フロント・ページを表示したときは $_GET[ 'page' ] などないが、それはどうでもよい(なければフロント・ページとして扱えばいいだけだ)。こうすると、(1) $_GET[ 'page' ] がセットされていないか、(2) 空であるか、(3) あるいは $entries < PER であれば、そもそも pagination は全く表示しなくていいということは最初に指定できる(空の HTML 要素は表示しないという方針)。

そして、「NEWER」とか「<」などのような pagination 表記に相当する HTML 要素は、2 > $page であれば非表示にして、それ以外は "/?page=<?php echo $page - 1; ?>" をアンカーにした「NEWER」として表示すればよい。逆に「OLDER」とか「>」などのような pagination 表記に相当する HTML 要素は、$page * PER => $entries であれば非表示にして、それ以外は "/?page=<?php echo $page + 1; ?>" をアンカーにした「OLDER」として表示すればよいだろう。なお、かなり前に議論したことだが、大多数のブログ等で記事を降順(DESC)で並べているときは、新しい、つまり数値化した日付として値が大きく、実際に記事を投稿したときの ID も大きい値になっている記事が先頭に来ているわけなので、大きい値の ID の記事へ移動することを「PREV」と表現するのは、どう考えてもおかしい。過去の記事に遡る「遡及」という行為を基準にすれば古い記事を見ていくのは「NEXT」と言っていいかもしれないが、それはやはりフロント・ページから遡るという特定のページ遷移しか想定していない(途中のページに検索エンジンからたどり着けば、やはりフロント・ページ側に向かって遷移することは主観的には「NEXT」だろう)ので、PREV, NEXT という表現は不適切だと思う。ここで、「それならどうして $page の並びは記事の ID と逆の向きなのか」という指摘はありうるが、それはもともと DESC として先頭から出力するという無理をしているのだから、これはこれで仕方がないとは言える。もちろん、フロント・ページを《最終の $page 値を設定したページ》として扱うことは可能だが。

それから 、「1」「2」「3」などとページ番号にアンカーなり「現在地」のクラス名をつけるような条件も決めておけば、かなり応用が利く。こういう要素は $page の走る範囲が ceil( $entries / PER ) と同じであることから、PER ごとのループを回して番兵 + 1 === $page であるときに HTML 要素のクラスに「現在地」を示すクラス名を追加すればいいだろう。さらには、このページがどんどん増えていった場合のことも考えて省略表示の基準もあればいいが、まぁ何百もページが作成される見込みはないので、ひとまずこれくらいのルールがあればいい。(もちろん1ページしかないときは、そもそも pagination 全体が表示されないので、このページ番号のリストは表示ステータスについて心配しなくてもいい。具体的には、「( $page + 1 ) * PER <= 記事総数」なら数字の並びを表示する for とか foreach を break する。)

それはそうと、今回は SAKURA のクラウドで初めて "KUSANAGI" という WordPress 専用の OS(実質はカスタムの CentOS 7 だ)を使っている。使い勝手は良好なので、機会があればこれを使うのが良さそうだ。

  1. もっと新しいノート <<
  2. >> もっと古いノート

冒頭に戻る


※ 以下の SNS 共有ボタンは JavaScript を使っておらず、ボタンを押すまでは SNS サイトと全く通信しません。

Twitter Facebook