Page No.1

まえがき – どうでもいいこと

この投稿の公開日付は、2014年11月となっているので、始めにこのプログラムを作ったのはその頃になります。もう、ずいぶんと月日が流れました。こうして改めて当時投稿した内容を見返していると、そうだったか、などと思い出すことも多々あって、備忘録として投稿を残していたことは、自分なりに改めて良かったと思ったりしています。あと、こうしてプログラムのことを記事に書いていると、実はその時に、こうした方がいいんじゃないか!ということに気がつくことがよくあるのです。

WordPress を使い始めた当初は、教本に載っていた通り WP-PageNavi を使っていたとのこと。
これといった問題があったわけではないし、こうであればいいのにという希望もまったくと言ってよいほどなかったのだけれど、たいして難しいものでないし、自作すれば汎用的でない分、シンプルになって少しは軽くなるのではないか、というわずかな期待をもって自作することにしたようです。

今となって自分としてはすっかり忘れてしまっていますが、「画像一覧ページ」で参考にした教本、「PHPによるWordPressカスタマイズブック 藤本 壱 著 出版社 ソシム」に出ていたページネーションを基本にしたとのことです。あらためてその本を見てみると、参考にしたというか、ほぼそのままという感じですね。

for でページ数だけループさせ、それで得られる番号により、get_pagenum_link() を使ってページへのリンクを取得して表示させるというやり方。シンプルだけどまっとうな手法。

その本では、get_pagenum_link() を使ってリンクを得ているのを、パーマリンク設定が基本のままだったということもあって、簡略化して使わないようにすることで、少しでも軽くなればと、涙ぐましい努力をしたようです。

そして、自作なりのオリジナリティーな部分として、目当てのページ番号を入力して直にそのページへジャンプできるようにと form ( input 要素 )を付加しています。このときすでにページ数が多量になることを想定していたようです。ページ数が多いサイトであるなら、このダイレクトジャンプの機能は有用なのではないかと思います。

このプログラムもなんだかんだと改良を重ね、2023年1月現在、バージョンは5となっています。なんとか少しでも軽く速くということを考えて改良したきたわけですが、このバージョン5においては、リストの生成に for ループを使うのをやめ、新たに思いついた手法へと変更しています。実はこれ、お風呂に入っていて頭を洗っているときに閃いたんだけど。これにより、かなり高速化できたのではと、自負しています。

function make_page_num_list()

なんとか高速化できないものかと、あーでもないこーでもないと考えて思いついた手法。それは、ページナンバーリストを生成するのに、正攻法の for ループを使うのをやめ、配列操作でナンバーリストを生成していく手法です。

こちらも理屈はとてもシンプルなものです。
1から総ベージ数までのすべてのページ番号を値にもつ配列を、range( 1, $allpages ) で生成します。この全ページ番号を値としてもっている配列を、現在のページ番号で array_slice() を使って前後二つに分割します。隣接するページ番号は、その前後の配列の最後と最初で簡単に取得できます。

if の条件式はほとんど必要としない。おおかたの処理を配列を操作する関数でできる。10 の倍数ページも100 の倍数ページも同じことをするだけ。それぞれの配列を10の倍数の配列、100の倍数の配列として作っておけばいいだけのこと。どうしても細かいことで if 文が必要にはなるけれど、ループでやるよりも条件判断を通る数を圧倒的に減らすことが出来るはずです。

ということで、まずはその関数。与えられた現在のページ番号、総ページ数から、表示するページ番号のリストを配列で返します。当然のことながら、functions.php 内に書いてあります。

<?php
    // $current -> 現在のページ番号
    // $allpagecount -> サイト(そのページ)の総ページ数
    // $setting -> 現在のページに隣接するページ番号の表示数指定、10の倍数ページ、100の倍数ページ
    function make_page_num_list ( $current, $allpagecount, $setting = array( 3, 3, 3 ) ) {

        if ( $current > $allpagecount ) {
            return array();
        }

        if ( 3 !== count ( $setting ) ) {
            $setting = array( 3, 3, 3 );// 0->一桁、1->10の倍数、2->100の倍数 表示するページの個数の各設定
        }

        $pglist = array(// それぞれ表示するページ番号を入れておくための配列
            'triplef' => array(),// 隣接する100の倍数のページ番号で$currentより小さい
            'doublef' => array(),// 隣接する10の倍数のページ番号で$currentより小さい
            'onef' => array(),// 隣接する一桁のページ番号で$currentより小さい番号
            'current' => array( $current ),// 現在のページ番号
            'oneb' => array(),// 隣接する一桁のページ番号で$currentより大きい
            'doubleb' => array(),// 隣接する10の倍数のページ番号で$currentより大きい
            'tripleb' => array(),// 隣接する100の倍数のページ番号で$currentより大きい
        );
        // 前後のページ番号を取得するのに基本となるそれぞれ前後の数値
        $basenum = array( 'f' => $current, 'b' => $current );

        // 全てのページ番号による配列を生成
        $allpages = range( 1, $allpagecount );
        // 1ページから現在のページまで含む分の配列を抜き出す
        $front = array_slice( $allpages, 0, $current );
        // 現在のページより後ろの分の配列を抜き出す。(現在のページは含まない)
        $back = array_slice( $allpages, $current );

        // 現在のページの前後、隣接したページ番号の生成
        // 前部分の配列の後ろから現在のページを除いて、指定された個数だけ配列を取り出す
        $pglist['onef'] = array_slice( $front, ( $setting[0] + 1 ) * -1, -1 );
        // 10の倍数のページ番号を取得するための目印となる番号を設定
        if ( $pglist['onef'] ) {
            $basenum['f'] = $pglist['onef'][0];
        }
        // 後部分の配列の先頭から指定された個数だけ配列を取り出す。
        $pglist['oneb'] = array_slice( $back, 0, $setting[0] );
        if ( $pglist['oneb'] ) {
            $basenum['b'] = end( $pglist['oneb'] );
        }

        // 隣接した番号に続く、10の倍数のページの生成
        // 総ページ数が10ページより多い時だけ
        if ( $allpagecount > 10 ) {
            // 0から総ページ数以内で、10の倍数の配列を生成、eq. 0,10,20,30,・・・
            $doublenum = range( 0, $allpagecount, 10 );

            $dblover = floor ( ( $basenum['b'] + 2 ) / 10 ) + 1;
            $tmpdbb = array_slice( $doublenum, $dblover );
            $pglist['doubleb'] = array_slice( $tmpdbb, 0, $setting[1] );
            if ( $pglist['doubleb'] ) {
                $basenum['b'] = end( $pglist['doubleb'] );
            }

            if ( $basenum['f'] > 12 ) {
                if ( $setting[1] > 0 ) {
                    $dblunder = floor( ( $basenum['f'] - 2 ) / 10 );
                    $tmpdbf = array_slice ( $doublenum, 1, $dblunder );
                    $pglist['doublef'] = array_slice( $tmpdbf, ( $setting[1] * -1 ) );
                    if ( $pglist['doublef'] ) {
                        $basenum['f'] = $pglist['doublef'][0];
                    }
                }
            }

            if ( $allpagecount > 100 ) {
                $triplenum = range( 0, $allpagecount, 100 );

                $tplover = ceil ( $basenum['b'] / 100 );
                $tmptpb = array_slice( $triplenum, $tplover );
                $pglist['tripleb'] = array_slice( $tmptpb, 0, $setting[2] );

                if ( $basenum['f'] > 100 and $setting[2] > 0 ) {
                    $tplunder = floor( ( $basenum['f'] - 1 ) / 100 );
                    $tmptpf = array_slice ( $triplenum, 1, $tplunder );
                    $pglist['triplef'] = array_slice( $tmptpf, ( $setting[2] * -1 ) );
                }
            }
        }

        return $pglist;
    }
?>
PHP
CopyExpand

function echopagelist()

そして、メインとなる本体の関数。これは自サイト用で、パーマリンク設定がデフォルトの基本のままのサイトでしか使えないものです。あしからずご承知おきください。で、汎用性をもたせたものは2ページ目に載せてます。

これももちろん、functions.php 内に書いてあります。
で、同じページ内で上部と下部など、この関数が二度呼ばれたときは、一度目に生成した html データを変数に保存しておいて、二度目の時はそのキャッシュを使用するようにして同じものが二度生成されないようにしてあります。

そのキャッシュとしての変数が static $liststr。これ、関数内でも static ということが使えることを実は知らなかった。あまり global を使いたくないな、と思ってなにか他に手は無いものかと探していたら見つかった。static をつけて静的な変数にすると、その関数が終わってもその変数に入れた値は維持されているというもの。なんだそんな便利なものがちゃんとあったんだな~って。

<?php
    // $dir -> 要素のid指定 0->bottompagelink、1->toppagelink
    // $label -> ページリストのトップページとラストページのラベルの文字列指定、0->Top,End、1->First,Last
    // $setting -> 表示するページ番号の個数指定
    function echopagelist( $dir = 0, $label = 0, $setting = 0 ) {
        global $wp_query, $accpt_lang;

        // 同ページ内で二度関数が呼ばれた場合、二度目は一度目のときに生成したものを再利用するため、それを入れておくための変数
        // static の変数は関数が終了しても入れた値は保持されている
        static $liststr = '';

        if ( get_query_var('paged') ) {
            $page_no = ( int ) get_query_var('paged');
        } else {
            $page_no = 1;
        }
        $page_counts = ( int ) $wp_query -> max_num_pages;
        // 自サイトの場合、パーマリンク設定は基本のままなので、ページ番号リンクは?paged=numberをつけるだけなのでホームのurlを取得しておく
        $basicurltop = home_url( '/' );//オプションを除いた自url

        // ダイレクトジャンプのformを送信するための既存のurl クエリを設定するための処理
        $params = $_GET;// url クエリを全て取得
        // 自サイトの場合、url のクエリにlang(言語設定)が付いていないときでもブラウザの言語設定がjaでなければページを英語表示にするためにlang=enを設定する
        if ( ! isset ( $params['lang'] ) and 'ja' !== $accpt_lang ) {
            $params['lang'] = 'en';
        }

        $constr = '?';//urlとクエリの接続文字
        $tarpara = array();// url クエリ格納用配列
        $paramstr = '';
        if ( count( $params ) > 0 ) {
            foreach ( $params as $key => $val ) {
                // paged 以外の url クエリを取得する
                if ( $key !== 'paged' ) {
                    $tmpkey = urlencode( $key );
                    $tmpval = urlencode( $val );
                    $tarpara[ $tmpkey ] = $tmpval;
                    $paramstr .= $constr . $tmpkey . '=' . $tmpval;
                    $constr = '&';
                }
            }
            // paged以外のオプションがあった場合
            if ( '&' === $constr ) {
                $basicurltop .= $paramstr;
            }
        }

        //$showjump = 7;

        $choices = array( [ 'bottom', 'top' ], [ 'Top', 'First' ], [ 'End', 'Last' ], [ [ 2, 2, 3 ], [ 4, 2, 3 ] ] );
        $topnav = $choices[0][ ( $dir & 1 ) ];
        
        $label = $label & 1;// 1 とビットAND させれば得られるのは0か1のみ
        $top_label = $choices[1][ $label ];
        $last_label = $choices[2][ $label ];
    
        //ここからhtml出力
        if ( $page_counts > 1 ) {
            echo "\n" . '<nav id="' . $topnav . 'pagelink"><div class="wp-pagenavi">
                <!-- echo_pagelist built-in ver.5.0 new advanced type-->
                <form method="get" class="jump-form" action="">
                <span class="pages">' . ( string ) $page_no . '/' . ( string ) $page_counts . '</span>' . "\n";

            if ( $liststr ) {// 変数に入っている既に生成されたデータが入っている場合
                echo "<!-- reused version page-navi-list -->\n" ;
                echo $liststr;
                $liststr = '';
            } else {

                $setting = $setting & 1;
                $near = $choices[3][ $setting ][0];// カレントページに接するページの表示数
                $far = $choices[3][ $setting ][1];// カレントページから離れているページで10の倍数のページの表示数
                $distant = $choices[3][ $setting ][2];// 間隔が100より多い時に、100の倍数のページの表示数。
    
                $page_list = array();// 生成する html を蓄えていく変数
                $hiddenclass = ' hiddena';
                $karastr = '<span class="hiddena">~</span>';

                if ( $page_no !== 1 ) {
                    $page_list[] = '<a href="' . $basicurltop . '" class="first" title="先頭ページへ Jump!">«' . $top_label . '</a>';
                    $page_list[] =  '<a href="' . $basicurltop . $constr . 'paged=' . ( string ) ( $page_no - 1 ) . '" class="previouspostslink" rel="next" title="次のページへ"><</a>';
                }

                // 表示するページ番号によるリストを取得
                $tmplist = make_page_num_list ( $page_no, $page_counts, array( $near, $far, $distant ) );

                $keys = array( 'current' => '', 'oneb' => '' );
                $numary = array();

                // 各ページ番号にリンク要素を付加してhtmlを完成させる
                foreach ( $tmplist as $key => $value ) {
                    $kara = array( $karastr, '*' );

                    if ( isset( $keys[ $key ] ) or ! $value ) {
                        $kara = array( '', '' );
                    }
                    $page_list[] = $kara[0];
                    $numary[] = $kara[1];

                    if ( 'current' === $key ) {

                        $numary[] = $value[0];
                        $page_list[] = '<span class="current">' . ( string ) $value[0] . '</span>';
                    } else {
                        foreach ( $value as $val ) {
                            $numary[] = $val;
    
                            $valstr = ( string ) $val;
                            $page_list[] = '<a href="' . $basicurltop . $constr . 'paged=' . $valstr . '" class="page larger' . $hiddenclass . '">' . $valstr . '</a>';
                        }
                    }
                }
                // 余分な'<span class="hiddena">~</span>'を取り除く
                $numary = array_values( array_filter( $numary ) );

                if ( '*1' === ( $numary[0] . ( string ) $numary[1] ) ) {
                    $res = array_search( $karastr, $page_list );

                    if ( false !== $res ) {
                        unset ( $page_list[ $res ] );
                    }
                }

                // 最後に'<span class="hiddena">~</span>'が必要なら付加する
                $lastnum = ( int ) end( $numary );
                if ( $page_counts !== $lastnum ) {
                    $page_list[] = $karastr;
                }

                if ( ( int ) $page_no !== $page_counts ) {
                    $page_list[] = '<a href="' . $basicurltop . $constr . 'paged=' . ( string ) ( $page_no + 1 ) . '" class="nextpostslink" rel="prev" title="前のページへ">></a>';
                }
                if ( $lastnum !== $page_counts ) {
                    $page_list[] =  '<a href="' . $basicurltop . $constr . 'paged=' . ( string ) $page_counts . '" class="last" title="最終ページへ Jump!">' . $last_label . '»</a>';
                }

                $liststr = implode( '', $page_list );
                echo $liststr;
            }

            // url クエリが存在するならform送信の場合にそれらが付加されるようにする
            //if ( $page_counts > $showjump ) {
                if ( count ( $tarpara ) ) {
                    foreach ( $tarpara as $key => $val ) {
                        echo '<input type="hidden" name="' . $key . '" value="' . $val . '">';
                    }
                }
                echo '<span class="jumpnav"><input type="number" class="jump-field" value="' . ( string ) $page_no . '" name="paged" min="1" max="' . ( string ) $page_counts . '" title="Direct Jump : input page number and enter key."></span>';
            //}
            echo '</form>
                </div></nav>';
        }
    }
?>
PHP
CopyExpand

と、いうことでやはりパーマリンク設定をしてあっても使える汎用性をもたせたものも作ってみるかということになります。まぁ、結局それはプラグインとして使うことになるわけです。ちなみにそのプラグインは WordPressプラグイン公式ディレクトリからダウンロードできます。

Simplistic page navi Plugin

そしてこのサイトにあるそのプラグインの詳細ページはここです->「ページネーション(ページャー)を作り直してプラグイン」
と、いいつつ、2ページめではその汎用性をもたせた関数となります。

Leave a Reply!

JavaScript is necessary to send a comment.
You can edit and delete your comment if you input a edit key.
Edit key is necessary for attesting you when you edit and delete it.
The tag of HTML cannot be used in comment.
When you comment for the first time, it is displayed after the approval of the administrator.
Because I cannot speak English so much, it takes time to answer.
Required fields are marked *.

※Please enter more than 5 characters only alphabets.
※Edit or delete are possible for 2000 days after approval.

*

♠Simplistic Comment User Editable v4.0

♠When visitors leave comments on the site this site collect the data shown in the comments form, and also the visitor’s IP address and browser user agent string to help spam detection.
♠This site does not use cookie when visitors leave comments and commenter edit comment.
♠This site uses Akismet to reduce spam. Learn how your comment data is processed.

Comments feed

Trackback URL : https://strix.main.jp/wp-trackback.php?p=48154

Sanbanse Funabashi
2011.01.01 sunrise

Top

スクロールさせるか画像をクリックすると元に戻ります。