
WordPressでブログを書いて情報発信している会社は多いと思います。
いろんなブログを見に行ってる時に、記事ページはやっぱり目次があったほうが見やすいなと思いました。
プラグインでもいいんですが、サイトによっては重くなったりするし、コンフリクトのリスクもあります。
phpなんとなくわかるんだったら、書いた方が軽いので色々検索して合体させました。
プラグインの場合
有名どころはEasy Table of Contentsです。
入れるだけで文字くを作ってくれます。
サクッとやりたい方はこれをインストールして有効にしてください。
自作の場合
function.phpにコードを書いて動かします、function.phpを触ると危ないからバックアップを!
といった記載をよく見ますが、個人的には思っていません。
どこを触ったか覚えていればいいんです。
どんな仕組み?
ざっくり言うと、「記事内のコードを見て、h2とh3があればアンカーを作って表示する」
と言うプログラムです。
the_content内のタグをpreg_matchで検索、h2とh3があれば、それをアンカータグにして、かつそれぞれに対応するidを振ってくれます。
h2の数で発動管理もできますし、囲むタグも自分で指定できます。
注意点としては、記事内のh2とh3にクラスがついていると発動しないところです。
function.php
function my_add_content( $content ) { if ( is_single() ) { $pattern = '/<h[2-3]>(.*?)<\/h[2-3]>/i'; // 属性を持たないh2・h3要素を正規表現で表すパターン preg_match_all( $pattern, $content, $matches, PREG_SET_ORDER ); // 本文の中から、すべてのh2・h3要素を検索 // ページ内のh2・h3要素が3つ以上の場合に目次を出力 if( count( $matches ) > 1 ){ $toc = '<div class="toc_wrap"><h2 class="twt">目次</h2><ol class="olw">'; $hierarchy = NULL; $i = 0; // 本文内のh2・h3要素を上から順番にループで処理 foreach( $matches as $element ){ $i++; $id = 'chapter-' . $i; $chapter = preg_replace( '/<(.+?)>(.+?)<\/(.+?)>/', '<$1 id ="' . $id . '">$2</$3>', $element[0] ); $content = preg_replace( $pattern, $chapter, $content, 1); if( strpos( $element[0], '<h2' ) === 0 ){ $level = 0; }else{ $level = 1; } if( $hierarchy === $level ){ $toc .= '</li>'; }elseif( $hierarchy < $level ){ $toc .= '<ol class="oli">'; $hierarchy = 1; }elseif( $hierarchy > $level ){ $toc .= '</li></ol></li>'; $hierarchy = 0; }elseif( $i == 1 ){ $hierarchy = 0; } $title = $element[1]; $toc .= '<li><a href="#' . $id . '">' . $title . '</a>'; } if( $level == 0 ){ $toc .= '</li></ol>'; }elseif( $level == 1 ){ $toc .= '</li></ol></li></ol>'; } $toc .= '</div>'; //ナビを出す場所の指定(1個目のh2の下に出す) $h2 = '/^<h2.*?>.+?<\/h2>$/im';//H2見出しのパターン if ( preg_match_all( $h2, $content, $h2s )) { if ( $h2s[0] ) { if ( $h2s[0][0] ) {//1番目のH2見出し手前に挿入 $content = str_replace($h2s[0][0], $toc.$h2s[0][0], $content); } } } } } return $content; } add_filter( 'the_content', 'my_add_content' );
コピペでいけると思います。
細かい説明は参考引用のリンクから見に行ってください!
参考引用:コード全体
参考引用2:出す場所の指定