「WP-PageNavi」で出力されるHTMLを任意の形に変更・整形する方法!

5,133 view

こんにちは、制作部のkeishibukiです。
今回のテーマはWordPressプラグインの「WP-PageNavi」。

投稿一覧などで使われるページャー機能(上の画像のようなもの)を
簡単に実装できる便利なプラグインです。

「WP-PageNavi」の簡単な使い方

プラグインのインストール

まずは以下の手順でプラグインをインストールしてください。

管理画面>プラグイン>新規追加>「WP-PageNavi」で検索>インストール&有効化

プラグインの使い方

ページャー機能を実装したい箇所(archive.phpなど)に以下のコードを書いてください。

<?php wp_pagenavi(); ?>

出力結果

<div class="wp-pagenavi">
<span class="pages">1 / 4</span>
<span class="current">1</span>
<a class="page larger" href="http://example.com/category/news/page/2/">2</a>
<a class="page larger" href="http://example.com/category/news/page/3/">3</a>
<a class="page larger" href="http://example.com/category/news/page/4/">4</a>
<a class="nextpostslink" rel="next" href="http://example.com/category/news/page/2/">»</a>
</div>

無事出力できました。

「WP-PageNavi」のちょっとした問題点

このように簡単にページャーを実装できるのですが、
出力されるHTMLを管理画面上で変更できないというちょっと不便な所もあります。

例えばCSSの指定上、下記のような形でHTMLを組みたいとします。

<nav id="pager">
<ul class="pager-inner">
<li class="pages"><span>1 / 4</span></li>
<li class="is-current"><span>1</span></li>
<li><a href="http://example.com/category/news/page/2/">2</a></li>
<li><a href="http://example.com/category/news/page/3/">3</a></li>
<li><a href="http://example.com/category/news/page/4/">4</a></li>
<li><a href="http://example.com/category/news/page/2/">»</a></li>
</ul>
</nav>

「WP-PageNavi」で標準的に出力されるHTMLと、
実際に出力させたいHTMLが一致していないケースがよくあります。

この場合、これらを一致させるにはどうすればいいのでしょう?

ステップ1:まずは<nav>を追加しよう!

まずは「wp-pagenavi」を囲う「<nav id=”pager”></nav>」を追加します。
wordpressのpluginsディレクトリからwp-pagenaviのコードを直接みてみましょう。

wp-content/plugins/wp-pagenavi/core.php

function wp_pagenavi( $args = array() ) {
if ( !is_array( $args ) ) {
$argv = func_get_args();
$args = array();
foreach ( array( 'before', 'after', 'options' ) as $i => $key ) {
$args[ $key ] = isset( $argv[ $i ]) ? $argv[ $i ] : '';
}
}
$args = wp_parse_args( $args, array(
'before' => '',
'after' => '',
'wrapper_tag' => 'div',
'wrapper_class' => 'wp-pagenavi',
'options' => array(),
'query' => $GLOBALS['wp_query'],
'type' => 'posts',
'echo' => true
) );
// 以下略

大事なのは$argsの中身。
今回使うのは下記の4つです。

‘before’ => ”,
‘after’ => ”,
‘wrapper_tag’ => ‘div’,
‘wrapper_class’ => ‘wp-pagenavi’,

「wrapper_tag」は出力される<span>や<a>を囲う要素、
デフォルトでは「<div class=”wp-pagenavi”></div>」の部分ですね。
「wrapper_class」は「wrapper_tag」に付けられるclassです。

「before」「after」は「wrapper_tag」を更に囲うもの指定できます。

まずは使用しているテーマのfunctions.phpに以下のコードを書いてください。

function my_pagenavi($args=array()){
if( !function_exists('wp_pagenavi') ) return;
$defaults = array(
'before' => '<nav id="pager">',
'after' => '</nav>',
'wrapper_tag' => 'ul',
'wrapper_class' => 'pager-inner'
);
$args = is_array($args) ? array_merge($defaults, $args) : $args;
wp_pagenavi($args);
}

これでmy_pagenavi()を実行するとwp_pagenavi()が呼ばれ、
$argsの中身が$defaultsで設定した内容で上書きされるようになりました。

試しにarchive.phpなどに書いたwp_pagenavi()をmy_pagenavi()に変えてみてください。

出力結果

<nav id="pager">
<ul class="pager-inner">
<span class="pages">1 / 4</span>
<span class="current">1</span>
<a class="page larger" href="http://example.com/category/news/page/2/">2</a>
<a class="page larger" href="http://example.com/category/news/page/3/">3</a>
<a class="page larger" href="http://example.com/category/news/page/4/">4</a>
<a class="nextpostslink" rel="next" href="http://example.com/category/news/page/2/">»</a>
</ul>
</nav>

無事navで囲うことができました!
次にspanやaをliで囲っていきます。
ついでに不要なclassも削除しちゃいましょう。

ステップ2:フックに引っ掛けて置換しよう!

フックに引っ掛けよう!

wp_pagenavi()が実行されるタイミングでフックに引っ掛けましょう。
先程書いたコードを下記のコードに書き換えてください。

function my_pagenavi($args=array()){
if( !function_exists('wp_pagenavi') ) return;
$defaults = array(
'before' => '<nav id="pager">',
'after' => '</nav>',
'wrapper_tag' => 'ul',
);
$args = is_array($args) ? array_merge($defaults, $args) : $args;
add_filter('wp_pagenavi', 'my_filter_wp_pagenavi', 10, 1);
wp_pagenavi($args);
remove_filter('wp_pagenavi', 'my_filter_wp_pagenavi', 10);
}

add_filter()を使い、wp_pagenavi()が実行されるタイミングで出力されるHTMLを整形する関数を作りましょう。

WordPressではこのような「何らかの処理のタイミング」のことを「フック」と呼び、
これにより様々なタイミングで機能の追加や挙動の変更が行えます。

11行目を見てください。

add_filter('wp_pagenavi', 'my_filter_wp_pagenavi', 10, 1);

第一引数には引っ掛けるフック名(wp_pagenavi)
第二引数には設定する関数名(my_filter_wp_pagenavi)
第三引数の数字には実行順序(10)
第四引数の数字には第二引数で設定した関数が受け付ける引数の個数(1)を設定します。

ちなみにremove_filter()は、add_filter()で登録した関数を削除する関数です。
今回は念のため記述しておきます。
※remove_filter()について説明すると長くなりますので、今回は割愛させて頂きます。

my_filter_wp_pagenavi()の用意

先程第二引数で設定した関数を用意しましょう。
※my_filter_wp_pagenavi()は自作関数ですので設定しないと動作しません!

使用しているテーマのfunctions.phpの続きに以下のコードを書いてください。

function my_filter_wp_pagenavi($html) {
// <a>タグの不要なclassの削除+<li>で囲む
$pattern     = "/<a[\s\S]+?href=.([^\'\"]+)[\'\"][^>]*?>([^<]*?)<\/a>/u";
$replacement = '<li><a href=${1}>${2}</a></li>';
$html        = preg_replace($pattern, $replacement, $html);
// class="pages"付きの<span>を置換
$pages_ptn = "/<span class=[\'\"]pages[\'\"]>([\s\S]*?)<\/span>/u";
$pages_rep = '<li class="pages"><span>${1}</span></li>';
$html      = preg_replace($pages_ptn, $pages_rep, $html);
// class="current"付きの<span>を置換
$current_href = esc_attr( get_pagenum_link( get_query_var('paged', 1) ) );
$current_ptn  = "/<span class=[\'\"]current[\'\"]>([\s\S]*?)<\/span>/u";
$current_rep  = '<li class="is-current"><span>${1}</span></li>';
$html         = preg_replace($current_ptn, $current_rep, $html);
return $html;
}

正規表現を使ってwp_pagenavi()で出力されるHTMLを整形しています。

コメントに書きましたが、
3~7行目では<a>を<li>で囲いつつ、不要なclassを削除しています。
7~9行目では総ページ数(class=”pages”)のspanを<li>で囲っています。
11~14行目では現在のページ(class=”current”)のspanを<li>で囲っています。

出力結果

<nav id="pager">
<ul class="pager-inner">
<li class="pages"><span>1 / 4</span></li>
<li class="is-current"><span>1</span></li>
<li><a href="http://example.com/category/news/page/2/">2</a></li>
<li><a href="http://example.com/category/news/page/3/">3</a></li>
<li><a href="http://example.com/category/news/page/4/">4</a></li>
<li><a href="http://example.com/category/news/page/2/">»</a></li>
</ul>
</nav>

無事、希望の形で出力されました!

ステップ3:class名のみ変更したい場合(おまけ)

先程は<li>で囲う必要があったため、置換という方法を取りましたが、
特定のclass名を変更したい場合でしたらもっと簡単な方法があります。

class=”current”を変更したい場合

add_filter('wp_pagenavi_class_current', 'my_filter_wp_pagenavi_class_current');
function my_filter_wp_pagenavi_class_current($class_name) {
return 'is-current';
}

先程と同じようにadd_filter()を使用し、
「class=”current”が設定されるタイミング」で
「my_filter_wp_pagenavi_class_current()」を実行しています。

  • wp_pagenavi_class_pages
  • wp_pagenavi_class_first
  • wp_pagenavi_class_previouspostslink
  • wp_pagenavi_class_extend
  • wp_pagenavi_class_smaller
  • wp_pagenavi_class_page
  • wp_pagenavi_class_current
  • wp_pagenavi_class_larger
  • wp_pagenavi_class_nextpostslink
  • wp_pagenavi_class_last

それぞれフックが用意されていますので、
class名を変更したいだけならこっちの方が簡単ですね。

最後に

正規表現がパッと理解し辛いですが
ちょっと勉強すればこれくらいは理解出来るようになります。
僕も正規表現は勉強し始めたばかりなので、もっと使いこなせるようにならねば。

以上、「WP-PageNavi」で出力されるHTMLを任意の形に変更・整形する方法!でした。

\ SNSでシェア /

WRITER

keishibuki

制作 keishibuki

新潟生まれ、新潟育ちの新潟Boy。
95年生まれのラストゆとり世代。

専門学校に通いながらアルバイトとして働いていたが、
2017年度の春で晴れて正社員にランクアップ。

TAGS