WordPress

【WordPress】カテゴリー・アーカイブの投稿数をリンクに含める方法と、その正規表現部分の解説

2019/08/04

WordPressを使ったブログで、サイドバーにカテゴリーとアーカイブを表示している人は多いと思います。
設定で投稿数を表示することが出来ますが、この投稿数がデフォルトだとリンク内に含まれないんです

こんな感じに、リンクの下線が「月」までしかいってない↓
(リンクタグ の外側に投稿数がある)

これを、この画像でいえば「(4)」まで持ってくる方法です。
「functions.php」というファイルを編集するので、事前にバックアップを取ってください。

記事数の表示方法

まずは記事数の表示方法。前提の部分のため説明は簡単に終わります。

[ダッシュボード] → [外観] → [ウィジェット]を開きます。
サイドバートップやサイドバーウィジェットにある[アーカイブ] または [カテゴリー]を開いて、[投稿数を表示]にチェック

記事数をリンクに含める方法

「functions.php」に以下を追加します。
このコードは、コチラの記事を参考にさせていただきました。ありがとうございました。

//アーカイブの数表示
add_filter( 'get_archives_link', 'my_archives_link' );
function my_archives_link( $output ) {
  $output = preg_replace('/<\/a>\s*(&nbsp;)\((\d+)\)/',' ($2)</a>',$output);
  return $output;
}

//カテゴリーの数表示
add_filter( 'wp_list_categories', 'my_list_categories');
function my_list_categories( $output ) {    
  $output = preg_replace('/<\/a>\s*\((\d+)\)/',' ($1)</a>',$output);
  return $output;
}

このカテゴリーの方の、
preg_replace('/<\/a>\s*\((\d+)\)/',' ($1)',$output)という部分を解説していきます。

正規表現の解説

問題の部分はこのようになっています。

preg_replace('/<\/a>\s*\((\d+)\)/',' ($1)',$output)

わかりづらいので分解します。

まずはメインの関数 preg_replace は、
preg_replace( (1)正規表現パターン , (2)置換後の文字列 , (3)置換対象の文字列 )

当てはめてみると、
(1)正規表現パターン:'/<\/a>\s*\((\d+)\)/'
(2)置換後の文字列:' ($1)'
(3)置換対象の文字列:$output
となります。

これを日本語で言うと、
「(3)の中から、(1)に一致するパターンを検索して、(2)に置き換える」です。
(1)~(3)を1つ1つ見ていきます。

(3)置換対象の文字列

先に(3)を解説します。
例として、$outputには以下のような文字列が入ってくるとします。
(実際の$outputにはリストタグ等も入ってきますが、わかり易いようにリンク部分だけ)

<a href="http://paya02/category/udon/">うどん</a> (5)

うどんカテゴリーがあり、このカテゴリーでは5記事書かれている状態です。
(5)がリンクタグの外側にいますよね。

(1)正規表現パターン

次に正規表現パターン。
'/<\/a>\s*\((\d+)\)/'

・「''」 一番外側
文字列を囲うためのシングルコーテーション。phpの決まりですね。

・「//」 二番目外側
正規表現パターンのデリミタ(要素の区切り)。「/」が使われることが多いようです。
他の文字でも囲うことが出来ます。

ここまでは決まりごとのようなものです。

・「<\/a>」
わかりづらい部分ですが、これでリンクタグの終了を表しています。
1文字目「<」はリンクの終了タグ
2文字目「\」はエスケープ文字で、「\」の次にくる文字をエスケープしています。
エスケープとは、正規表現をする時に、特別な意味のある文字を「ただの文字列として」出したい時に使います。
3文字目「/」がエスケープして出したい文字であるスラッシュ。
スラッシュは正規表現で特別な意味(役割)があるためそのままでは出ません。
なのでそれを「ただの文字列として」出すために2文字目のエスケープ文字が必要なのです。
これがないとリンクタグが正しく閉じられません。
4~5文字目「a>」はそのままで、リンクタグ終了の閉じる部分です。

・「\s*」
1~2文字目「\s」は空白文字を表します。
3文字目「*」は前の文字を0個以上。
つまり、これで空白文字が0個以上という意味になります。
空白が無くても、空白1個でも2個でも三幸の♪……失礼しました。1個でも2個でもヒットします。

・「\((\d+)\)」
ここもわかりづらい部分ですが、エスケープ文字がそうさせているだけだと思うので落ち着いて。
1~2文字目「\(」が「(」のエスケープ。括弧も特別な意味があるためエスケープしないと出ません。

3~7文字目「(\d+)」の「()」は、この括弧内の文字が (2)置換後の文字列 で置き換える対象になります。
そして「\d」が数値(0~9)、「+」は前の文字が1個以上、つまり数値が1文字以上という意味になります。
全体の意味としては、「外側括弧の中の、数値1文字以上の部分を後で置き換えるよ」ということです。

これらをまとめると、
<a href="http://paya02/category/udon/">うどん</a> (5)」という文字列から、
</a> (5)」という部分を抽出するよ、ということになります。

分からなければ分割した1つ1つをまずは理解してみてください!

(2)置換後の文字列

最後に置換後の文字列。このようになっています。
' ($1)</a>'

「$1」以外の部分はそのまま置換されるだけです。
「()」がありますが、この括弧は正規表現ではないただの括弧です。投稿数を囲う括弧ですね。

そして「$1」ですが、(1)で「外側括弧の中の、数値1文字以上の部分を後で置き換えるよ」と書きました。
その置き換える対象である数値1文字以上の部分が「$1」という変数に代入されていると考えて下さい。

正規表現によって括弧内の数値部分を取得して、それを変数に代入し、置換後の文字としてその変数を使用(出力)しているのです。

(1)~(3)をまとめると…

<a href="http://paya02/category/udon/">うどん</a> (5)」という文字列が、

<a href="http://paya02/category/udon/">うどん (5)</a>」という文字列に置き換えられるのです!

どんなカテゴリー名であっても、正規表現なら1行で対応出来てしまうんですね。
これが正規表現の凄いところです!!

終わりに

正規表現は最初は理解が難しいと思います。
そういう時はそのまま理解しようとするんじゃなくて、今回の記事のようになるべくパーツを分割しましょう。
パーツごとに改行したり、メモ入れたりしてゆっくり解析すると良いですよ。

文字列編集や特定の文字パターンの行を検索する時等、正規表現は活躍の場が広いです。
今回はphpでしたけど、どの言語でも微妙な表現の違いはあれど正規表現に対応してます。

是非習得して、文字列操作に強くなってください!




-WordPress