WordPressの記事本文の大見出しを自動生成で目次で出力にしてくれるようにするソースコードを紹介したいと思います。
- 目次をのHTMLを自由に出力させたい!
- シンプルな機能だけでいい!
って方にお勧めの方法です。
プラグインなしで、自作する簡易もくじの作り方
functions.phpに下記を追記してください。
<?php
/**
* 『toc』ショートコードの追加と目次の追加
*
* - [toc] ショートコード の追加
* - 目次パーツの生成
* - 目次にはリンクをつける
* - ページ分割ごとに遷移先リンクを調整
* - no-index をつけるとスキップ
*/
add_shortcode('toc', function () {
global $post;
$content = $post->post_content;
$paged_counter = 1;
$heading_counter = 1;
$toc_html = '<div class="p-toc"><p class="p-toc__title">もくじ</p><ul class="p-toc__content">';
if ( preg_match_all('/<([hH][1-2])(.*?)>(.*?)<\/[hH][1-2].*?>|<!--nextpage-->/u', $content, $heading) ) {
for ($i = 0; $i < count($heading[0]); $i++) {
// ページ分割があったら分割カウンターをカウントアップ
if ($heading[0][$i] === '<!--nextpage-->') {
$heading_counter = 1;
$paged_counter++;
continue;
}
// 除外文字列が入っている場合除外
if (strpos($heading[2][$i],'no-index') !== false) {
continue;
}
// リンクを生成
$url_paged = '';
if ($paged_counter > 1) {
$url_paged = get_the_permalink().'/'.$paged_counter.'/';
}
$toc_html .= '<li><a href="'.$url_paged.'#index-'.$heading_counter.'">'.$heading[3][$i].'</a></li>';
$heading_counter++;
}
$toc_html .= '</ul></div>';
}
return $toc_html;
});
/**
* 本文の対象見出しにアンカーを追加
*/
add_filter('the_content', function ($content) {
if ( preg_match_all('/<([hH][1-2])(.*?)>(.*?)<\/[hH][1-2].*?>/u', $content, $heading) ) {
$heading_counter = 1;
for ($i = 0; $i < count($heading[0]); $i++) {
// 除外文字列が入っている場合除外
if (strpos($heading[2][$i],'no-index') !== false) {
continue;
}
$replace_tag = '<'.$heading[1][$i].' id="index-'.$heading_counter.'"'.$heading[2][$i].'>'.$heading[3][$i].'</'.$heading[1][$i].'>';
$content = str_replace($heading[0][$i], $replace_tag, $content);
$heading_counter++;
}
}
return $content;
});
この目次機能の特徴は…
- the_content内の大見出し(h1 と h2)を目次として出力します。
- 出力する場所は、ショートコードの 『toc』を記述すれば目次を自動生成します。
- 目次のリストはページ内リンクをつけて出力される!
- 目次として判定されたくない場合は、class=””に『no-index』をつけてね!
- ページ分割(nextpage)ごとにリンクを調整
- liを使ってリスト出力したりしてますが、HTMLを修整して使ってね!
まとめ
簡易版の目次機能を追加する方法を紹介しました。かなりシンプルなつくりにしているのでここからカスタマイズするのも容易かと思います。ぜひ参考にしてみてください。