パラメータでカスタマイズしやすいWordPressのページナビを作ってみた

WordPressのページナビ(ページャー)は、なんと言ってもWP-PageNaviが有名ですが、もっとシンプルでコントローラブルなものが出来ないかと思い自分で作ってみました。

ページナビ(ページャー)

出力されるHTMLのソースを見てもらえれば分かりますが、CSSのclassの変更がパラメータで出来たり、種類が豊富に指定されるため、多様なデザインをカバーできることも、喜んでもらえる点ではないでしょうか。

[2011.06.30追記]
プラグイン版を公開いたしました。一部機能追加と修正してありますので、こちらをご利用ください。

導入方法

  1. 使っているテーマのfunctions.phpにCODE 1を追記してください。あるいは、独自プラグインにしてしまってもいいです。(独自プラグインの作り方は、初心者でも10秒でできる WordPress プラグインの作り方WordPress でスニペットを簡単に管理する方法あたりを参考に)
  2. テーマファイルのページナビを表示したい位置に<?php page_navi(); ?>を追加してください。

これだけでも一応は、ページナビが表示されるようになりますが、いくつかのパラメータで表示方法を変更することができます。

指定可能なパラメータ

items
表示する前後ナビゲーションの数。現状表示しているページを含むため、前後の表示数を揃えたい場合は奇数を指定してください。デフォルトは11
show_adjacent
前後ページへのリンクを表示するかどうか。デフォルトはtrue(表示)
prev_label
前ページリンクのリンクテキスト。デフォルトは、&lt;(<)
next_label
次ページリンクのリンクテキスト。デフォルトは、&gt;(>)
show_boundary
最初と最後のページへのリンクを表示するかどうか。デフォルトはtrue(表示)
first_label
最初のページへのリンクテキスト。デフォルトは&laquo;(«)
last_label
最後のページへのリンクテキスト。デフォルトは&raquo;(»)
show_num
現ページナンバーと全ページ数の表示をするかどうか。デフォルトはfalse(非表示)
num_position
現ページナンバーと全ページ数の表示位置。デフォルトはbefore(前)。後に表示したい場合はafterを指定
num_format
現ページナンバーと全ページ数の表示フォーマット。デフォルトは、<span>%d/%d</span>(nn/mm)
navi_element
ページナビのラッパー要素。divかnavを指定可能。デフォルトは空(ラッパー要素なし)
elm_class
ラッパー要素、ラッパー要素がない場合は ulのclass属性。デフォルトはpage_navi
elm_id
ラッパー要素、ラッパー要素がない場合は ulのid属性。デフォルトは空(id要素なし)
li_class
ページナビの全liに付くclass属性。デフォルトは空(classなし)
current_class
現ページのliに指定されるクラス名。デフォルトは current
current_format
現ページの表示フォーマット。デフォルトは <span>%d</span>
class_prefix
classの接頭辞。ページナビで出力されるclass全てに追加される。デフォルトは空。(接頭辞なし)
indent
タブインデント数。デフォルトは0
echo
ページナビの出力を行うかどうか。デフォルトは true(出力する)。false または 0 を指定するとPHPの値として returnする

パラメータ指定サンプル

パラメータ指定サンプル

<?php page_navi( 'items=7&prev_label=前へ&next_label=次へ&first_label=最初&last_label=最後&show_num=1&num_position=after' ); ?>
  • ナビ表示数は7
  • 前ページのリンクラベルは「前へ」
  • 次ページのリンクラベルは「次へ」
  • 最初のページのリンクラベルは「最初」
  • 最後のページのリンクラベルは「最後」
  • ページ数の表示を行い、位置は後

CODE 1

function page_navi( $args = '' ) {
	global $wp_query;
	
	if ( ! ( is_archive() || is_home() || is_search() ) ) { return; }
	$default = array(
		'items'				=> 11,
		'show_adjacent'		=> true,
		'prev_label'		=> '&lt;',
		'next_label'		=> '&gt;',
		'show_boundary'		=> true,
		'first_label'		=> '&laquo;',
		'last_label'		=> '&raquo;',
		'show_num'			=> false,
		'num_position'		=> 'before',
		'num_format'		=> '<span>%d/%d</span>',
		'echo'				=> true,
		'navi_element'		=> '',
		'elm_class'			=> 'page_navi',
		'elm_id'			=> '',
		'li_class'			=> '',
		'current_class'		=> 'current',
		'current_format'	=> '<span>%d</span>',
		'class_prefix'		=> '',
		'indent'			=> 0
	);
	$default = apply_filters( 'page_navi_default', $default );

	$args = wp_parse_args( $args, $default );
	
	$max_page_num = $wp_query->max_num_pages;
	$current_page_num = get_query_var( 'paged' ) ? get_query_var( 'paged' ) : 1;
	
	$elm = in_array( $args['navi_element'], array( 'nav', 'div', '' ) ) ? $args['navi_element'] : 'div';
	
	$args['items'] = absint( $args['items'] ) ? absint( $args['items'] ) : $default['items'];
	$args['elm_id'] = is_array( $args['elm_id'] ) ? $default['elm_id'] : $args['elm_id'];
	$args['elm_id'] = preg_replace( '/[^\w_-]+/', '', $args['elm_id'] );
	$args['elm_id'] = preg_replace( '/^[\d_-]+/', '', $args['elm_id'] );

	$args['class_prefix'] = is_array( $args['class_prefix'] ) ? $default['class_prefix'] : $args['class_prefix'];
	$args['class_prefix'] = preg_replace( '/[^\w_-]+/', '', $args['class_prefix'] );
	$args['class_prefix'] = preg_replace( '/^[\d_-]+/', '', $args['class_prefix'] );
	
	$args['elm_class'] = sanitize_attr_classes( $args['elm_class'], $args['class_prefix'] );
	$args['li_class'] = sanitize_attr_classes( $args['li_class'], $args['class_prefix'] );
	$args['current_class'] = sanitize_attr_classes( $args['current_class'], $args['class_prefix'] );
	$args['current_class'] = $args['current_class'] ? $args['current_class'] : $default['current_class'];
	


	$tabs = str_repeat( "\t", (int)$args['indent'] );
	$elm_tabs = '';
	
	$befores = $current_page_num - floor( ( $args['items'] - 1 ) / 2 );
	$afters = $current_page_num + ceil( ( $args['items'] - 1 ) / 2 );
	
	if ( $max_page_num <= $args['items'] ) {
		$start = 1;
		$end = $max_page_num;
	} elseif ( $befores <= 1 ) {
		$start = 1;
		$end = $args['items'];
	} elseif ( $afters >= $max_page_num ) {
		$start = $max_page_num - $args['items'] + 1;
		$end = $max_page_num;
	} else {
		$start = $befores;
		$end = $afters;
	}
		
	$elm_attrs = '';
	if ( $args['elm_id'] ) {
		$elm_attrs = ' id="' . $args['elm_id'] . '"';
	}
	if ( $args['elm_class'] ) {
		$elm_attrs .= ' class="' . $args['elm_class'] . '"';
	}
	
	$num_list_item = '';
	if ( $args['show_num'] ) {
		$num_list_item = '<li class="page_nums';
		if ( $args['li_class'] ) {
			$num_list_item .= ' ' . $args['li_class'];
		}
		$num_list_item .= '">' . sprintf( $args['num_format'], $current_page_num, $max_page_num ) . "</li>\n";
	}

	$page_navi = '';
	if ( $elm ) {
		$elm_tabs = "\t";
		$page_navi = $tabs . '<' . $elm;
		if ( $elm_attrs ) {
			$page_navi .= $elm_attrs . ">\n";
		}
	}
	
	$page_navi .= $elm_tabs . $tabs . '<ul';
	if ( ! $elm && $elm_attrs ) {
		$page_navi .= $elm_attrs;
	}
	$page_navi .= ">\n";
	
	if ($args['num_position'] != 'after' && $num_list_item ) {
		$page_navi .= "\t" . $elm_tabs . $tabs . $num_list_item;
	}
	if ( $args['show_boundary'] ) {
		$page_navi .= "\t" . $elm_tabs . $tabs . '<li class="' . $args['class_prefix'] . 'first';
		if ( $args['li_class'] ) {
			$page_navi .= ' ' . $args['li_class'];
		}
		$page_navi .= '"><a href="' . get_pagenum_link() . '">' . esc_html( $args['first_label'] ) . '</a></li>' . "\n";
	}
	
	if ( $args['show_adjacent'] ) {
		$previous_num = max( 1, $current_page_num - 1 );
		$page_navi .= "\t" . $elm_tabs . $tabs . '<li class="' . $args['class_prefix'] . 'previous';
		if ( $args['li_class'] ) {
			$page_navi .= ' ' . $args['li_class'];
		}
		$page_navi .= '"><a href="' . get_pagenum_link( $previous_num ) . '">' . esc_html( $args['prev_label'] ) . '</a></li>' . "\n";
	}
	
	for ( $i = $start; $i <= $end; $i++ ) {
		$page_navi .= "\t" . $elm_tabs . $tabs . '<li class="';
		if ( $i == $current_page_num ) {
			$page_navi .= $args['current_class'];
			if ( $args['li_class'] ) {
				$page_navi .= ' ' . $args['li_class'];
			}
			$page_navi .= '">' . sprintf( $args['current_format'], $i ) . "</li>\n";
		} else {
			$delta = absint( $i - $current_page_num );
			$b_f = $i < $current_page_num ? 'before' : 'after';
			$page_navi .= $args['class_prefix'] . $b_f . ' ' . $args['class_prefix'] . 'delta-' . $delta;
			if ( $i == $start ) {
				$page_navi .= ' ' . $args['class_prefix'] . 'head';
			} elseif ( $i == $end ) {
				$page_navi .= ' ' . $args['class_prefix'] . 'tail';
			}
			if ( $args['li_class'] ) {
				$page_navi .= ' ' . $args['li_class'] . '"';
			}
			$page_navi .= '"><a href="' . get_pagenum_link( $i ) . '">' . $i . "</a></li>\n";
		}
	}
	
	
	if ( $args['show_adjacent'] ) {
		$next_num = min( $max_page_num, $current_page_num + 1 );
		$page_navi .= "\t" . $elm_tabs . $tabs . '<li class="' . $args['class_prefix'] . 'next';
		if ( $args['li_class'] ) {
			$page_navi .= ' ' . $args['li_class'];
		}
		$page_navi .= '"><a href="' . get_pagenum_link( $next_num ) . '">' . esc_html( $args['next_label'] ) . '</a></li>' . "\n";
	}
	
	
	
	if ( $args['show_boundary'] ) {
		$page_navi .= "\t" . $elm_tabs . $tabs . '<li class="' . $args['class_prefix'] . 'last';
		if ( $args['li_class'] ) {
			$page_navi .= ' ' . $args['li_class'];
		}
		$page_navi .= '"><a href="' . get_pagenum_link( $max_page_num ) . '">' . esc_html( $args['last_label'] ) . '</a></li>' . "\n";
	}

	if ($args['num_position'] == 'after' && $num_list_item ) {
		$page_navi .= "\t" . $elm_tabs . $tabs . $num_list_item;
	}
	
	$page_navi .= $elm_tabs . $tabs . "</ul>\n";
	
	if ( $elm ) {
		$page_navi .= $tabs . '</' . $elm . ">\n";
	}
	
	$page_navi = apply_filters( 'page_navi', $page_navi );
	
	if ( $args['echo'] ) {
		echo $page_navi;
	} else {
		return $page_navi;
	}
}


function sanitize_attr_classes( $classes, $prefix = '' ) {
	if ( ! is_array( $classes ) ) {
		$classes = preg_replace( '/[^\s\w_-]+/', '', $classes );
		$classes = preg_split( '/[\s]+/', $classes );
	}

	foreach ( $classes as $key => $class ) {
		if ( is_array( $class ) ) {
			unset( $classes[$key] );
		} else {
			$class = preg_replace( '/[^\w_-]+/', '', $class );
			$class = preg_replace( '/^[\d_-]+/', '', $class );
			if ( $class ) {
				$classes[$key] = $prefix . $class;
			}
		}
	}
	$classes = implode( ' ', $classes );

	return $classes;
}

ページナビで出力されるHTMLソース

パラメータの指定なしで出力されるHTMLのソース例です。

<ul class="page_navi">
	<li class="first"><a href="http://www.example.com/date/2011/04/">&laquo;</a></li>
	<li class="previous"><a href="http://www.example.com/date/2011/04/page/6/">&lt;</a></li>
	<li class="before delta-5 head"><a href="http://www.example.com/date/2011/04/page/2/">2</a></li>
	<li class="before delta-4"><a href="http://www.example.com/date/2011/04/page/3/">3</a></li>
	<li class="before delta-3"><a href="http://www.example.com/date/2011/04/page/4/">4</a></li>
	<li class="before delta-2"><a href="http://www.example.com/date/2011/04/page/5/">5</a></li>
	<li class="before delta-1"><a href="http://www.example.com/date/2011/04/page/6/">6</a></li>
	<li class="current"><span>7</span></li>
	<li class="after delta-1"><a href="http://www.example.com/date/2011/04/page/8/">8</a></li>
	<li class="after delta-2"><a href="http://www.example.com/date/2011/04/page/9/">9</a></li>
	<li class="after delta-3"><a href="http://www.example.com/date/2011/04/page/10/">10</a></li>
	<li class="after delta-4"><a href="http://www.example.com/date/2011/04/page/11/">11</a></li>
	<li class="after delta-5 tail"><a href="http://www.example.com/date/2011/04/page/12/">12</a></li>
	<li class="next"><a href="http://www.example.com/date/2011/04/page/8/">&gt;</a></li>
	<li class="last"><a href="http://www.example.com/date/2011/04/page/13/">&raquo;</a></li>
</ul>

CSS例

本コードの他に、CSSの指定がないと当然ながらきれいに表示されません。
下記は、とりあえずのCSSサンプルです。あとは、好みのデザインを組み合わせてステキなページナビを作り上げて下さいね。

.page_navi {
	text-align: center;
}

.page_navi li {
	display: inline;
	list-style: none;
}

.page_navi li.current span {
	color: #000;
	font-weight: bold;
	display: inline-block;
	padding: 3px 7px;
	background: #fee;
	border: solid 1px #fcc;
}

.page_navi li a {
	color: #333;
	padding: 3px 7px;
	background: #eee;
	display: inline-block;
	border: solid 1px #999;
	text-decoration: none;
}

.page_navi li a:hover {
	color: #f00;
}

.page_navi li.page_nums span {
	color: #fff;
	padding: 3px 7px;
	background: #666;
	display: inline-block;
	border: solid 1px #333;
}

「パラメータでカスタマイズしやすいWordPressのページナビを作ってみた」への3件のフィードバック

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です