質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.49%
WordPress

WordPressは、PHPで開発されているオープンソースのブログソフトウェアです。データベース管理システムにはMySQLを用いています。フリーのブログソフトウェアの中では最も人気が高く、PHPとHTMLを使って簡単にテンプレートをカスタマイズすることができます。

PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

ページネーション

Webアプリケーションにおいて、1ページに収まらないコンテンツを、各ページへのリンクを並べてアクセスしやすくする手法をページネーションと呼びます。

Q&A

解決済

2回答

1124閲覧

Wordpressのページ送り機能で前後へ10ページ間隔で移動可能にしたい

M.Y.

総合スコア29

WordPress

WordPressは、PHPで開発されているオープンソースのブログソフトウェアです。データベース管理システムにはMySQLを用いています。フリーのブログソフトウェアの中では最も人気が高く、PHPとHTMLを使って簡単にテンプレートをカスタマイズすることができます。

PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

ページネーション

Webアプリケーションにおいて、1ページに収まらないコンテンツを、各ページへのリンクを並べてアクセスしやすくする手法をページネーションと呼びます。

0グッド

1クリップ

投稿2018/12/18 14:02

編集2018/12/29 11:51

前提・実現したいこと

 Wordpressのページ送り表示で総ページ数が多い時に、普通の1ページづつの「前へ」「次へ」以外に、前後へ10ページづつ移動できるリンクも表示したい。

試したこと

 プラグイン「WP-PageNavi」を使って<?php wp_pagenavi(); ?>でページャーを表示させた場合。

PageNavi 設定
表示するページ数 10
省略表示するページ数 1
省略ページを以下の倍数で表示 5
これで25ページ目を表示させると、以下の通り。

先頭«...5...21 22 23 24 25 26 27 28 29 30...40...»最終

「40」は現25ページ目から15ページ先になります。これを10ページ先への「35」にしたい。また、遡る方では「5」は先頭1ページ目から次の5の倍数であって、「21」から遡って20, 15, 10と表示されるわけではない。これは10ページ前への「15」にしたい。

「省略ページを以下の倍数で表示」を「1」に設定すると、以下。
先頭«...1...21 22 23 24 25 26 27 28 29 30...36...»最終
「36」は11ページ先だし、「1」は「先頭」と重複するので論外。

 条件分岐としては、10ページ前へのリンクは現在表示中のページが20ページ目以降の場合に表示され、2~19ページ目では表示されないことが望ましい。

 表示中のページの10ページ先・後へのページ・ナビゲーションが難しい場合は次善として、以下の通り10の倍数をそれぞれ「先頭」「最終」の横に表示させるのでもいい。
↓24ページ目を表示中
先頭«...10...20 21 22 23 24 25 26 27 28 29...30...»最終
↓39ページ目を表示中
先頭«...30...35 36 37 38 39 40 41 42 43 44...50...»最終
(18-12-29追記:10の倍数を前後に表示させるだけなら、 プラグイン「Simplistic page navi」で可能でした。「ページネーション(ページャー)を作り直してプラグイン」にコードの紹介あり。但しWP-PageNaviと違って「表示するページ数」を10にすることができません、「現在のページに隣接したページ番号を表示させる個数」が左右対称なので。)

 プラグインでなくphpプログラムで実現しても結構ですが、the_posts_pagination関数やpaginate_links関数のパラメーター一覧を見た限りでは、手立てが見つかりませんでした。
WordPressでページャーを出力する関数 the_posts_pagination の使い方

####追記
いまウェブ検索のキーワードを「wordpress "10ページ毎" ページネーション」にしてみたら、次のページがヒットしました。
PHPで10ページ毎のページネーション

動作としては、

1 2 3 4 5 6 7 8 9 10  >

という形に表示され、「>」をクリックした時に次の10ページグループが表示されます。

<  11 12 13 14 15 16 17 18 19 20  >

php

1page = isset($_GET['id']) ? $_GET['id'] : 1; 2// データ数 3$cnt = 275; 4// 1ページの表示件数 5$preview_item_num = 10; 6 7// 最大ページ数 8$max_page = ceil($cnt/$preview_item_num); 9// 次グループの先頭ページ 10$prove_group = (ceil( $page/10 )) * 10 + 1 ; 11// 現在のページグループ 12$group = (ceil( $page/10 ) - 1); 13// 二桁の値 14$select = $group * 10; 15// 差分 16$sabun = $cnt - 100 * $group; 17// 前ページの先頭ページ 18$prove = $prove_group - 20; 19// 手抜きで差分が100以上だったら100にする 20if($sabun > $preview_item_num * 10) $sabun = $preview_item_num * 10; 21 22// 過剰ページにアクセスがあったら非表示 23if( $page > 0 || $max_page >= $page ) 24{ 25// 10ページ以上だったら、前ページ移動のリンクを表示 26if( $page > 10 ) echo sprintf('<a href="?id=%s">前へ</a>', $prove); 27 28for( $s=1+$select; $s<= ceil($sabun/$preview_item_num)+$select; $s++? ) 29{ 30// 現在ページ以外のページにリンクを貼る 31if( $page == $s ) echo ' '.$s; 32else echo sprintf(' <a href="?id=%1$s">%1$s</a>', $s); 33} 34// 次のページグループが存在したら表示 35 if( $max_page >= $prove_group? ) echo sprintf(' <a href="?id=%s">後ろへ</a>', $prove_group); 36}

ううん、思った形とは異なるけど、10ページごとの移動をする同等の機能としてならこの例みたいなグループ化もありか。但しこれの両端に、「先頭」「最終」へのリンクも附けたい。
このソースをWordpressのページネーションに組み込むにはどうするのがよいのか、改造方法を御教示下さると、助かります。

補足情報(FW/ツールのバージョンなど)

Wordpress バージョン 5.0.1–ja
テーマはtwentysixteen(の子テーマ)
サーバーはXrea
WP-PageNavi バージョン 2.93

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

特殊なページネーションを使いたいのであれば、プラグインを使うのではなく、専用のページネーションをPHPで書いてしまったほうが手っ取り早いです。

https://wemo.tech/978https://web-ashibi.net/archives/971などを参考にして基本的なページネーションを作成したうえで、10ページ先のリンクを表示するように書けば完了です。


追記

PHP

1// 一般的なページネーションを作成した上で、10ページ先のリンクを出力する処理を追加 2global $paged; // 現在のページ番号 3echo get_pagenum_link($paged + 10):

追記2

追記戴いたget_pagenum_link($paged + 10):では、例として全50ページある時に41ページ目以降を表示中だと存在しないページを指定して変なことになりますよね。10ページ前も同様です。

PHP

1//未検証 2global $wp_query; 3global $paged; // 現在のページ番号 4 5$max pages = $wp_query->max_num_pages; 6 7if$max_page >= $paged10echo get_pagenum_link($paged10)

追記3(2018/12/31変更)

動作未検証です。

PHP

1global $wp_query; 2 3$pages = $wp_query->max_num_pages; 4$paged = get_query_var("paged") ?: 1; 5 6teratail_paginatio($pages, $paged,10);

PHP/**

1* ページネーション出力関数 2* $pages : 全ページ数 3* $paged : 現在のページ 4* $range : 何ページ表示するか 5*/ 6function teratail_pagination($pages, $paged, $range) { 7 8 // 1頁のみ 9 if ( $pages === 1 ) return; 10 11 // 複数頁 12 if ( 1 !== $pages ) { 13 14 $range = $range - 1; 15 $range1 = floor($range/2); 16 $range2 = ceil($range/2); 17 18 if( !((($paged-$range1) <= 1) && (1 <= ($paged+$range2))) ) 19 echo '<a href="', get_pagenum_link(1) ,'">', "先頭" ,'</a> '; 20 21 if($paged-$range1-1 > 1 && $paged-10-1 != 1) 22 echo "… "; 23 24 if( !(($paged-$range1) < ($paged-10) && ($paged-10) < ($paged+$range2)) && ($paged-10) > 1 ) 25 echo '<a href="', get_pagenum_link($paged - 10) ,'">', $paged - 10 ,'</a>… '; 26 27 for($it = $range1; $it > 0; $it--) 28 if( $paged-$it > 0) 29 echo '<a href="', get_pagenum_link($paged - $it) ,'">', $paged - $it ,'</a> '; 30 31 echo $paged, " "; 32 33 for($it = 1; $it <= $range2; $it++) 34 if( $paged + $it <= $pages ) 35 echo '<a href="', get_pagenum_link($paged + $it) ,'">', $paged + $it ,'</a> '; 36 37 if( !(($paged-$range1) < ($paged+10) && ($paged+10) < ($paged+$range2)) && ($paged+10) < $pages ) 38 echo '…<a href="', get_pagenum_link($paged + 10) ,'">', $paged + 10 ,'</a> '; 39 40 if($paged+$range2+1 < $pages && $paged+10+1 != $pages) 41 echo "… "; 42 43 if( !(($paged-$range1) <= $pages && $pages <= ($paged+$range2)) ) 44 echo '<a href="', get_pagenum_link($pages) ,'">', "最後" ,'</a> '; 45 } 46}

投稿2018/12/27 12:42

編集2018/12/31 07:51
退会済みユーザー

退会済みユーザー

総合スコア0

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

M.Y.

2018/12/27 13:28 編集

>10ページ先のリンクを表示するように書けば完了です  その手立てが見つけられなかったので、質問した次第です。示されたリンク先を読んでも、解りません。10ページ前と10ページ後へのリンクを表示させるのは、何を使ってどうやればよいのですか?  追記戴いたget_pagenum_link($paged + 10):では、例として全50ページある時に41ページ目以降を表示中だと存在しないページを指定して変なことになりますよね。10ページ前も同様です。
退会済みユーザー

退会済みユーザー

2018/12/29 09:01

> 追記戴いたget_pagenum_link($paged + 10):では、例として全50ページある時に41ページ目以降を表示中だと存在しないページを指定して変なことになりますよね。10ページ前も同様です。 if文で条件振り分けしてください。
M.Y.

2018/12/29 09:09

これはおっしゃる通り「特殊なページネーション」なのですから、「if文で条件振り分け」といった大まかな一般論のみでは、特殊な問題の解答として不足です。  望ましい条件分岐については既に質問文中に書いた通りですが、これを実現するにはif文でどう仕組めばいいのか、どうにもややこしくて、いまだ思案中です。
退会済みユーザー

退会済みユーザー

2018/12/29 09:13

日本語で考えてみてください。 「現在のページ数に10を足したページ数が最大ページ数以上だったら」という条件ならば、後はそれをif文にするだけです。
M.Y.

2018/12/30 23:37 編集

「追記3」を拝見。 >$range : 左右に何ページ表示するか  これ$range=5ですから、現在表示中のページと合せて5+1+5=11ページ分が表示される筈。  WP-PageNaviみたいに「表示するページ数」を「10」(もしくは偶数)に設定可能にするには、左右対称に5ページづつではなく、現在表示中のページ番号の左に4・右に5と振り分けねばなりません。また、現在表示中のページが1~4の場合は一律に左に4ではなく左に0~3・右に9~6と変化させる必要があります。その辺、下記解説等見ながら試行錯誤中です。 http://wordpress.windows-style.info/make_template/pagination.html
退会済みユーザー

退会済みユーザー

2018/12/30 13:18

はい、「WP-PageNaviみたいに「表示するページ数」を「10」に設定」する仕様はコードに組み込んでいないので、そうはなりません。 もしかしたら、最初は$rangeを4に設定しておいて、コードの途中で5に変更するようにすれば、いけるかもしれません。想像ですが。
退会済みユーザー

退会済みユーザー

2018/12/30 13:25

> もしかしたら、最初は$rangeを4に設定しておいて、コードの途中で5に変更するようにすれば、いけるかもしれません。想像ですが。 いや、これだと駄目だな。うまくいかない。むしろ、$rangeを$range1と$range2にわけて書いた方がよいか。
guest

0

自己解決

回答にある2018/12/31変更の追記3を参考にしました、有り難うございます。しかし条件分岐のif文に自分には何のための記述か理解できない意味不明な箇所もあり、不具合もあったので、いろいろ試して、いまはやっと下記の形に落ち着きました。
以下の通りfunctions.phpに書き込み。decaは10の意。

PHP

1/** ページネーション出力関数 2* $pages : 総ページ数 3* $paged : 現在のページ 4* $showitems : 何ページ表示するか 5*/ 6function deca_pagination($pages, $paged, $showitems = 10) { 7 global $wp_query; 8 $pages = $wp_query->max_num_pages; 9 $paged = get_query_var("paged") ?: 1; 10 $showitems = 10; 11 if ( $pages == 1 ) return;// 1頁のみ 12 if ( $pages !== 1 ) {// 複数頁 13 $minus_1 = $showitems - 1;// 偶数対策 14 $range1 = floor($minus_1/2); 15 $range2 = ceil($minus_1/2); 16 // cf. wp-content/plugins/wp-pagenavi/core.php 17 $start_page = $paged - $range1; 18 if ( $start_page <= 0 ) $start_page = 1; 19 $end_page = $paged + $range2; 20 if ( ( $end_page - $start_page ) != $minus_1 ) $end_page = $start_page + $minus_1; 21 if ( $end_page > $pages ) { 22 $start_page = $pages - $minus_1; 23 $end_page = $pages; 24 } 25 if ( $start_page < 1 ) $start_page = 1; 26 27 echo '<nav class="pagenavi" role="navigation"><small>Page:</small><span class="navilinks">'; 28 if( $start_page >= 2 && $pages > $showitems ) 29 echo '<a href="', get_pagenum_link(1) ,'" class="firstpage">1&laquo;</a>&nbsp;';// 先頭 30 if( !($range1 > 10) && ($paged-10) > 1 ) 31 echo '<a href="', get_pagenum_link($paged - 10) ,'" class="deca">', $paged - 10 ,'</a><small>&hellip;</small>'; 32 if ($start_page > 2 && $showitems < $pages) 33 echo '<a href="' . get_pagenum_link($paged - 1) . '" class="prev" title="前へ">&lt;</a> ';// Previous 34 35 $range = range($start_page, $end_page); 36 foreach ( $range as $i ) { 37 if ($i == $paged) {echo '<strong aria-current="page" class="current">' . $i . '</strong>&nbsp;';} 38 else if($i == $pages && !($showitems >= $pages)){ 39 echo '<a href="', get_pagenum_link($i) ,'" class="page-numbers">&raquo;', $i ,'</a>';} 40 else { 41 echo '<a href="', get_pagenum_link($i) ,'" class="page-numbers">', $i ,'</a>&nbsp;'; 42 } 43 } 44 45 if ( $end_page+1 < $pages ) 46 echo ' <a href="' . get_pagenum_link($paged + 1) . '" class="next" title="次へ">&gt;</a>';// Next 47 if( !($range2 > 10) && ($paged+10) < $pages && ($paged != 1) ) 48 echo '<small>&hellip;</small><a href="', get_pagenum_link($paged + 10) ,'" class="deca">', $paged + 10 ,'</a>&nbsp;'; 49 if( !($end_page >= $pages) ) 50 echo '&nbsp;<a href="', get_pagenum_link($pages) ,'" class="lastpage">&raquo;', $pages ,'</a>';// 最終 51 echo '</span></nav>' . "\n"; 52 } 53}

で、出力するためには子テーマ内のindex.phpやarchive.phpやsearch.phpに次の通り貼り附けました。

PHP

1<?php if (function_exists("deca_pagination")) {deca_pagination($wp_query->max_num_pages);} ?>

 もっとうまいやり方があるやも知れず、見落とした穴があるかも知れませんが、初心者にはここらが限界なので、何かお気づきの方は御指摘下されば幸甚です。

2019-04-04追記
PHP7.1以降ではUncaught ArgumentCountErrorになる。これは「ユーザー定義の関数に渡す引数が足りない場合」とのことなので、下記の通り修正。
function deca_pagination($pages, $paged, $showitems = 10) {

function deca_pagination() {

<?php if (function_exists("deca_pagination")) {deca_pagination($wp_query->max_num_pages);} ?>

 ↓

<?php if (function_exists("deca_pagination")) {deca_pagination();} ?>

投稿2019/01/09 21:58

編集2019/04/04 05:04
M.Y.

総合スコア29

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.49%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問