WordPressのページナビ(ページャー)は、なんと言ってもWP-PageNaviが有名ですが、もっとシンプルでコントローラブルなものが出来ないかと思い自分で作ってみました。
出力されるHTMLのソースを見てもらえれば分かりますが、CSSのclassの変更がパラメータで出来たり、種類が豊富に指定されるため、多様なデザインをカバーできることも、喜んでもらえる点ではないでしょうか。
[2011.06.30追記]
プラグイン版を公開いたしました。一部機能追加と修正してありますので、こちらをご利用ください。
導入方法
- 使っているテーマのfunctions.phpにCODE 1を追記してください。あるいは、独自プラグインにしてしまってもいいです。(独自プラグインの作り方は、初心者でも10秒でできる WordPress プラグインの作り方やWordPress でスニペットを簡単に管理する方法あたりを参考に)
- テーマファイルのページナビを表示したい位置に
<?php page_navi(); ?>
を追加してください。
これだけでも一応は、ページナビが表示されるようになりますが、いくつかのパラメータで表示方法を変更することができます。
指定可能なパラメータ
- items
- 表示する前後ナビゲーションの数。現状表示しているページを含むため、前後の表示数を揃えたい場合は奇数を指定してください。デフォルトは11
- show_adjacent
- 前後ページへのリンクを表示するかどうか。デフォルトはtrue(表示)
- prev_label
- 前ページリンクのリンクテキスト。デフォルトは、<(<)
- next_label
- 次ページリンクのリンクテキスト。デフォルトは、>(>)
- show_boundary
- 最初と最後のページへのリンクを表示するかどうか。デフォルトはtrue(表示)
- first_label
- 最初のページへのリンクテキスト。デフォルトは«(«)
- last_label
- 最後のページへのリンクテキスト。デフォルトは»(»)
- 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' => '<', 'next_label' => '>', 'show_boundary' => true, 'first_label' => '«', 'last_label' => '»', '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/">«</a></li> <li class="previous"><a href="http://www.example.com/date/2011/04/page/6/"><</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/">></a></li> <li class="last"><a href="http://www.example.com/date/2011/04/page/13/">»</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件のフィードバック