Wonderful! WordPress

ページネーション(ページャー)を作り直してプラグイン

Page No.1

ページネーション(ページャー)は『ページネーション(ページャー)自作』で作成したのですが。
他人様のサイトのテーマに組み込もうと思ったところ、パーマリンク設定がデフォルトの場合専用ということもあったので(少しでも軽くしようとしたんです)、それを汎用型にして他にいくつか機能も追加してと再び書き直すことにしました。
この時から、WordPress PHP コーディング基準に則って書くようにしました。条件式の論理比較においても左側に定数やリテラル、右側に変数を常に配置するというYoda Conditions(ヨーダ条件式)の作法でやってるつもりなんですが、気が付くと以前のとおり書いていて、後で戻って訂正するという二度でま状態。慣れるまではね・・・。
と、いうことで、

  • *2015/9/26:オプションをチェックする部分を関数化して変更し、
  • *2015/11/29:再び全体を修正。全てをclass化しカプセル化しました。

と、いうように何度かの改良を経て、2016年7月、今回はWordPress プラグイン公式ディレクトリに登録しようと思い立って、再び手を入れることにしました。
この投稿の記事は、以前にあった記事は消し去って、2016年7月に新しく書き直したものです。
そして2019年12月にページリストを作成する部分のコードを刷新しver.3.0にアップデートさせたのを期に再び書き直し始めています。

≪ Simplistic page navi Plugin ≫

WordPress プラグイン公式ディレクトリからダウンロードできます。
2016/8/13に、バージョンアップする予定のWordPress 4.6 においてのテストもあり、より高速化を図ってリンクを生成する部分を見直し、そのときに気が付いたバグを直すことも含めて大幅に改良をくわえて2.0 にバージョンアップさせました。
WordPress 5.3 に、PHP 7.3 になって、それらにおいての動作確認、そしてPHP7 ではいずれ廃止されるとの方法を使用していたアンインストール時におけるオプション値の消去方法を変更、無駄な条件判断の処理の多かったページリスト作成部分のコードを新たに書き直し2019/12/13に、やっとというか3.0 にバージョンアップさせています。この部分はページ数が多いほど無駄が多かったわけであり、それに加えて同じページで二度目に関数が呼び出されたときは、一度目に作ったリストをメモリーにストアしておいてそれを再利用するようにしたので、機能的にはかなり軽くなったものと思っています。

そして、WordPress が、5.8 となり、PHP は 7.4 から 8.0 へと変わりゆくなかで、動作確認をしなくては!と思いつつ、ただ、だらだらと時間が過ぎてしまったのですが、2021年9月8日、気がついたバグを修正し、流れで Gutenberg 用のブロックを装備、テンプレートをいじらなくても JavaScript でページャーの要素を HTML に挿入する機能などを追加し、そしてさらなるスピードアップのための改善を少し施して ver4.0 へとバージョンアップさせています。

この記事もバージョンアップにあわせて、新しくした部分など、おいおい編集していくつもりです。

Simplistic page navi Plugin
インストールや使い方はこのページの下の方のここを
とりあえず機能的なことは、

  • オプションは管理画面で設定可能。
  • 数字を直接指定できるdirect input & jump用のinput box がある。
  • そのinput box の表示はオプションにて設定可能。
  • リストを逆順でも表示可能。
  • メディアクエリ等を使ってスマホなど小さいスクリーン用に対応する為に、必須でない要素をhiddenにするためのclassが設定されている。
  • そのナロースクリーン用のスタイルの書き出しの設定とメディアクエリのmax-widthのpx値をオプションにて設定可能。
  • デフォルトでスタイルシートを何種か用意。そして、その読み込みをオプションで選択可能。
  • 最低限必要な要素のリストで表示させる設定がオプションで可能。
  • 現在のページに隣接したページ番号を表示させる個数を設定可能。
  • ページ数が多い時に表示する10の倍数のページ番号の個数を設定可能。
  • 同様にページ数が多く、カレントページが両端のどちらかに寄っている時に最外のページから端までの間隔が広い時に表示する100の位のページ番号の個数を設定可能。
  • FirstとLastページへのリンクのラベル文字列とページ番号が離れている時のつなぎ文字列を設定可能。
  • ページリストの親タグの<div>のid名を指定可能。最外の親タグは<nav>。
  • 同ページ内に二つ表示させ、それぞれに位置設定を詳細に出来るように、最外の親タグ<nav>には二つのid名を設定済み。
  • 同ページ内に二つ表示させる場合、二度目に関数が呼び出された時は一度目に作成したリストをメモリーにストアしておいたものを再利用。
  • スタイルにおけるフォントサイズ、テキストアライン、マージンをオプションにて設定可能。
  • また、各オプションにおいてスタイルシートの読み込みに関する事以外は、テンプレートにおいてプラグインを起動する関数に引数として渡すことで設定することも可能。これは、同ページ内に二つ表示させた場合に、それぞれに違う表示をさせることが可能ということ。
  • Gutenberg Block Editor 用の Custom Block を装備
  • テーマのテンプレートにプラグインの関数タグを記述しなくても、ページャーを表示させたい HTML の要素の id を指定することで、Javascript によって、その指定された要素の先頭と末尾にページャーの要素を挿入する機能を装備
  • そもそも HTML のことなど全くわからないという場合は、Javascript で本文のコンテンツの要素を探させて、もし運良く見つけることができればその要素の先頭と末尾にページャーの要素を挿入するなんてことも可能
  • テーマが WordPress 標準のページャー wp_link_pages を使用している場合、その出力を消去することが可能

まずはオプション関連のコード部分。
オプションの設定と取得に関しては以前に自分で考えたものをそのまま使い回し。

<?php
//既存のオプション値を強制的にデフォルトに戻す時使用
//delete_option('splcpn_options');

class Simplistic_Page_Navi_List {

	private $current;
	private $default;
	private $ret_option;
	private $option_name;
	private $stylenum;
	private $td_loaded;
	private $domain;
	private $current_url = '';
	private $url_parameter = array();
	private $page_list = array();// v3.0 で追加。作成したリストを二度目に呼び出された時のためにストアしておく配列。

	public function __construct() {
		$this->option_name = 'splcpn_options';
		$this->td_loaded = false;
		$this->domain = 'splcpnl';
		$this->load_option();
	}

	private function load_option() {

		// options default value オプションのデフォルト値設定
		$this->default = array(
			'style'=>'3', // style : 0:don't load style sheet file, 1:standard design, 2:circle design, 3:circle white back, 4:circle orange back, 5:simple square, 6:white gradation
			'reverse'=>'0', // reverse list : 0:standard left start、1:reverse
			'above'=>'7', // direct jump box showed above page count
			'nr_style'=>'768',// This number is pixel value of madia query\'s max-width. The style of narrow screen will be showed if this number isn't 0. Default is 768
			'minimum_unit'=>'1',// list of minimum unit, 0: minimum, 1: standard
			'adjacent_num'=>'3',// Number of pages that adjacent to current page to display list
			'larger_page'=>'3',// Maximum number of larger page to display list
			'top_label'=>'Top',// Label of 'to top page'
			'last_label'=>'Last',// Label of 'to last page'
			'connection_str'=>'~',// Connection string, empty is disable.
			'div_id'=>'pagenavilist',// Id strings of parent div tag.
			'font_size'=>'0',// specify font size.
			'top_text_align'=>'0',// Text-align of  id selector "toppagelink" of "nav" tag. 0 : disable, 1:left, 2: right, 3:center.
			'top_margin'=>'',// Margin of  id selector "toppagelink" of "nav" tag. Empty is disable, top:right:bottom:left. This value can have from one to four values same as the format of css.
			'bottom_text_align'=>'0',// Text-align of  id selector "bottompagelink" of "nav" tag. 0 : disable, 1:left, 2: right, 3:center.
			'bottom_margin'=>'',// Margin of  id selector "bottompagelink" of "nav" tag. Same as "top_margin". 
			'distant_num'=>'3',// Number of pages to display list when the wide distance from the edge label.

		);
		$this->current = get_option( $this->option_name );

		// 初使用の時などオプションが設定されていない時
		if ( false === $this->current ) {

			// デフォルトでオプション設定
			update_option( $this->option_name, $this->default );
			$this->ret_option = $this->default;

		// 新規オプション増設時など既にあるオプションとデフォルトで数が違う時
		} elseif ( count( $this->current ) !== count( $this->default ) ) {

			// オプションの数を減らした時
			if ( count( $this->current ) > count( $this->default ) ) {
				$newary = array_intersect_key( $this->current, $this->default );
			}else{
				$newary = $this->current;
			}

			// ユーザー設定値で上書き
			$up_option = array_merge( $this->default, $newary );

			update_option( $this->option_name, $up_option );
			$this->ret_option = $up_option;
		} else {
			$this->ret_option = $this->current;
		}

		// スタイルシート読み込みのオプション値の無害化
		$rstyle = 0;
		$rstyle = intval( $this->ret_option['style'] );
		if ( $rstyle > 6 ) {
			$rstyle = 0;
		}
		$this->stylenum = $rstyle;

		// スタイルシートの登録
		if ( 0 !== $this->stylenum ) {
			add_action( 'wp_enqueue_scripts', array( $this, 'splcpn_style' ) );
		}

		// ナロースクリーン用のスタイルをテンプレートのwp_head()において吐き出すための登録
		if ( intval( $this->ret_option['nr_style'] ) ) {
			add_action( 'wp_head', array( $this, 'echo_nr_style' ) );
		}

		// v2.0にて追加
		$this->get_url_parameter();
	}

	// v2.0でページナンバーリンク生成方法を変更し、
	// それによって以下の二つの関数を追加
	// 現在表示されているページのurlを取得
	private function treat_current_url() {
		$this->current_url = get_pagenum_link( 1 );
	}

	// ページナンバーによるページリンクの作成関数
	private function make_pagenumlink( $pagenum = 1 ) {
		global $wp_rewrite;
		$targetlink = '';
		if ( '' !== $this->current_url ) {
			$targetlink = $this->current_url;

			if ( $pagenum > 1 ) {
				if ( $wp_rewrite->using_permalinks() ) {
					if ( false === strpos( $this->current_url, '?' ) ) {
						$targetlink = trailingslashit( $this->current_url ) . user_trailingslashit( $wp_rewrite->pagination_base . '/' . $pagenum, 'paged' );
					} else {
						$slash = ( false === strpos( $this->current_url, '/?' ) ) ? '/' : '';
						$targetlink = str_replace( '?', $slash . $wp_rewrite->pagination_base . '/' . $pagenum . '/?', $this->current_url );
					}
				} else {
					$connection = ( false === strpos( $this->current_url, '?' ) ) ? '?' : '&amp;';
					$targetlink = $this->current_url . $connection . 'paged=' . $pagenum;
				}
			}
		}
		return $targetlink;
	}
	// ↓class 続く
?>
PHP
CopyExpand

90行目と93行目以降はv2.0でページナンバーによるリンク生成方法を変更しているので、それによって追加した関数。
簡単に説明しておくと、プラグインの読みこみの時に一度だけ、ページ番号に1を指定してget_pagenum_link() にて、現在表示されているページのページ指定の無い素のurl を取得しておいて、それを元にしてその都度ページ番号を指定したurl を生成しようというのがmake_pagenumlink()関数ということになります。詳しくは、もう少し後で出てくる《get_pagenum_link() に関して》で書いています。
この関数ですが、実は最後に”/”が付かないパーマリンク設定のときに”?”でのパラメータの付加があるときに生成されたリンクがおかしくなってしまうのでv2.0にアップした数日後にすぐに改良してv2.1へと再びバージョンアップさせています。
そしておもにスタイルシート関連。

<?php
	// ↓class 続き

	// スタイルシート選択関数 (v2.0で以下のように変更)
	private function splcpn_select_style( $rstyle ) {
		$clary = array( '', 'st', 'cl', 'cd', 'co', 'sh', 'gr' );
		$tarfile = 'style_splc_pn_' . $clary[ $rstyle ] . '.css';
		return $tarfile;
	}

	// サイト読み込み時にオプション指定のスタイルシートを登録する関数
	public function splcpn_style() {
		$stylefile = $this->splcpn_select_style( $this->stylenum );
		wp_enqueue_style( 'splc_pn_style', plugins_url( $stylefile, __FILE__ ), false, date( 'YmdHis', filemtime(plugin_dir_path( __FILE__ ).$stylefile )) );
	}

	// テンプレートから指定のスタイルシートを登録する関数
	public function template_splcpn_style( $dir = 0 ) {

		if ( $dir > 6 ) {
			$dir = 0;
			return;
		}

		if ( 0 !== $dir and 0 === $this->stylenum ) {
			$stylefile = $this->splcpn_select_style( $dir );
			wp_enqueue_style( 'splc_pn_style', plugins_url( $stylefile, __FILE__ ), false, date( 'YmdHis', filemtime(plugin_dir_path( __FILE__ ).$stylefile )) );
		}
	}
	// ↓class 続く
?>
PHP
CopyExpand

管理画面にオプション設定ページを表示させる部分とアンインストールした時に保存してあるオプション値をデータペースから消去する処理の部分。
これらも他で使っているものと全く同じ処理のつかいまわし。
ただ、実際にオプション設定画面に表示させる部分のHTMLのコードに関しては、そこに使用説明書きを入れたこともあってとても長くなってしまい、しかしこの部分というのは通常のページを表示させる時には不必要なデータであると思われるので、別ファイルにして必要なときにinclude_onceで読み込まれるようにしました。こうすれば、多分、ページを表示する時には読み込まれないのではないかと思うのですが・・・。その、別ファイルにした部分はこのすぐ下に。

<?php
	// ↓class 続き

	// ↓ここから管理画面のメニューにオプション設定ページを登録する処理
	public function splcpn_add_menu() {
		$this->load_text_domain();
		add_options_page( 'Simplistic Page-navi Option', 'Simplistic Page-navi Option', 'administrator', 'splcpn_plugin_options', array( $this, 'splcpn_page_output' ) );
		add_action( 'admin_init', array( $this, 'register_splcpn_settings' ) );
	}
	 
	public function register_splcpn_settings() {
		register_setting( 'splcpn-settings-group', $this->option_name );
	}
	
	public function splcpn_page_output() {
?>
		<div class="wrap">
			<h2>Simplistic Page-navi option</h2>
			<form method="post" action="options.php">
<?php
			settings_fields( 'splcpn-settings-group' );
			do_settings_sections( 'splcpn-settings-group' );

			include_once 'explain.php';
	}
	//↑ここまで

	/*
	アンインストール時にデータベースに保存してあるオプション値を削除するための以下の関数は、
	php7ではいずれ廃止されるであろう手法とのことで、
	v3.0 においてuninstall.phpファイルを使用する方法に変更。
	よって実際には以下はすでに使用しておらず削除してしまっています。
	*/
	/*public function at_uninstall() {
		self::remove_option();
	}*/

	/*
	↓この関数を呼び出すat_uninstallはregister_uninstall_hookから呼び出されるが、
	このフックは特殊な関数で呼ばれており、その時点ではこのプラグインクラスはコールされておらず、
	疑似変数$thisを使ったり、クラス内のグローバル変数を利用できない。
	それ故にオプション名に変数を使うことが出来ず、このremove_optionをstaticにして
	静的にat_uninstallから呼び出す必要がある。
	*/
	/*private static function remove_option() {
		delete_option( 'splcpn_options' );
	}*/
	// ↓class 続く
?>
PHP
CopyExpand

上記の別ファイルにした部分、explain.php の内容。
実際にその部分にあったコードを抜き取って、ただ別ファイルとして保存しただけのものです。
オプション設定画面部分。
ちなみに今回は翻訳処理などを使ってみたので、_e() という関数が出てきます。これは翻訳ファイル( -ja.mo )を読み込んで引数の英文を設定された日本語に翻訳して表示するというものです。WordPress では当たり前なのですが、今回、やっと初めて使ってみたことになります。

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=58015

Sanbanse Funabashi
2010.10.24 sunrise

Top

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