WordPressでプラグインやJavascriptなしで目次(もくじ)を実装したいんですけど、どうしましょう?

WordPressで目次(もくじ)機能が欲しかったので探していたところ、複雑なものばかりだったのでプラグインも使いたくなかったのし、お手頃な感じで簡易的な関数を作成。

アニメーション付きでページ内を移動する場合はJavascript – アクセシビリティを考慮したアニメーション付きでスルスルっと移動するページ内スクロールで設定できます。

h2タグにIDを自動付与

<?php the_content(); ?>内にh2タグがあれば自動でidを付与。
/<(h2)(.*?)>(.+?)<\/h2>/imのh2の部分を変更すれば対象を変更できます。

1
function __the_content($content)
2
{
3
    // 目次
4
    $tag = '/<(h2)(.*?)>(.+?)<\/h2>/im';
5
    if (preg_match_all($tag, $content, $tags)) {
6
        $num = 1;
7
        for ($i = 0; $i < count($tags[0]); ++$i) {
8
            if (!preg_match_all('/id *\= *["\'](.+?)["\']/i', $tags[0][$i], $id)) {
9
                $id[1][0] = 'sec-' . $num;
10
                $content = preg_replace("/" . str_replace('/', '\/', $tags[0][$i]) . "/", preg_replace($tag,
11
                    "<$1 id=\"{$id[1][0]}$2\">$3</$1>", $tags[0][$i]), $content, 1);
12
            }
13
            ++$num;
14
        }
15
    }
16
    return $content;
17
}
18
add_action('the_content', '__the_content');

目次の書き出し

目次を置きたい場所に<?php toc(); ?>を記入。
対象(h2タグ)がなければ何も出力されません。

1
function toc()
2
{
3
    global $post;
4
    
5
    $toc = '';
6
    $tag = '/<h2.*?>(.+?)<\/h2>/im';
7
    if (preg_match_all($tag, get_the_content($post->ID), $tags)) {
8
        $num = 1;
9
        for ($i = 0; $i < count($tags[0]); ++$i) {
10
            $id[1][0] = '#sec-' . $num;
11
            $toc .= "<li><a href=\"{$id[1][0]}\">" . preg_replace($tag, "$1", strip_tags($tags[0][$i])) . "</a></li>\n";
12
            ++$num;
13
        }
14
        $toc = "<div id=\"toc\"><p><b class=\"toc-title\">もくじ</b></p><ol class=\"toc-list\">{$toc}</ol></div>";
15
    }
16
    echo $toc;
17
}