WordPressの投稿にプラグインなしで自動で目次を表示させる方法
WordPress
2023.6.28

WordPressの投稿にプラグインなしで自動で目次を表示させる方法

WordPressの投稿にプラグインなしで自動で目次を表示する方法です。

※ここでは投稿記事(ブログ)のみに目次を表示させる方法を記載しています。

投稿記事だけに目次を自動表示させる方法

function.phpに以下を記述します。

function generate_article_toc($content) {
    // 目次を自動生成する条件を指定(投稿のみ)
    if (is_singular('post')) {
        // 目次を生成するHTMLを格納する変数
        $toc_html = '';

        // 目次の見出しを抽出するための正規表現パターン
        $pattern = '/<h([2-6]).*?>(.*?)<\/h[2-6]>/';

        // 投稿本文から目次の見出しを抽出し、目次を生成する
        if (preg_match_all($pattern, $content, $matches)) {
            $toc_html .= '<div class="p-mokuij">';
            $toc_html .= '<div class="c-mokuij__ttl">目次</div>'; // 目次のタイトルを追加
            $toc_html .= '<ul>';
            foreach ($matches[2] as $i => $title) {
                $heading_level = intval($matches[1][$i]);
                $title = urldecode($title);
                $slug = 'chapter-' . ($i + 1);

                // タイトルにIDを付与する
                $title_with_id = '<h' . $heading_level . ' id="' . $slug . '">' . $title . '</h' . $heading_level . '>';

                // 目次のリンク先にタイトルを追加
                $toc_html .= '<li><a href="#' . $slug . '">' . $title . '</a></li>';

                // タイトルを置換する
                $content = str_replace($matches[0][$i], $title_with_id, $content);
            }

            $toc_html .= '</ul>';
            $toc_html .= '</div>';
        }

        // 投稿本文に目次のHTMLを挿入する
        $content = $toc_html . $content;
    }

    return $content;
}
add_filter('the_content', 'generate_article_toc');

7〜8行目の

        // 目次の見出しを抽出するための正規表現パターン
        $pattern = '/<h([2-6]).*?>(.*?)<\/h[2-6]>/';
に見出しに表示させるタイトル(H2〜H6の場合=[2-6])(H2〜H3の場合=[2-3])を記述。
このコードをfunctions.phpに追加すれば、投稿ページで記事の本文を表示するときに、自動で目次が生成できます。

ただ上記の場合、目次内ではH2もH3・・すべて同じスタイルが適用されてしまうためタイトルの大小の見分けがつきません。

あまりいいとは言えません。。

目次内のタイトル(H2,H3・・)ごとに異なるスタイルを適用する方法

目次内のタイトルごとにスタイルを分けて適用したい場合は以下のコードを記述します。

function generate_article_toc($content) {
    // 目次を自動生成する条件を指定(投稿のみ)
    if (is_singular('post')) {
        // 目次を生成するHTMLを格納する変数
        $toc_html = '';

        // 目次の見出しを抽出するための正規表現パターン
        $pattern = '/<h([2-3]).*?>(.*?)<\/h[2-3]>/';

        // 投稿本文から目次の見出しを抽出し、目次を生成する
        if (preg_match_all($pattern, $content, $matches)) {
            $toc_html .= '<div class="p-mokuij">';
            $toc_html .= '<div class="c-mokuij__ttl">目次</div>'; // 目次のタイトルを追加
            $toc_html .= '<ul>';
            foreach ($matches[2] as $i => $title) {
                $heading_level = intval($matches[1][$i]);
                $title = urldecode($title);
                $slug = 'chapter-' . ($i + 1);

                // タイトルにIDを付与する
                $title_with_id = '<h' . $heading_level . ' id="' . $slug . '" class="c-anchor">' . $title . '</h' . $heading_level . '>';

                // 目次のリンク先にタイトルを追加
                $toc_html .= '<li><a href="#' . $slug . '" class="';
                $toc_html .= ($heading_level === 2) ? 'c-mokuij__h2' : 'c-mokuij__h3';  // H2とH3の目次項目に異なるクラスを適用
                $toc_html .= '">' . $title . '</a></li>';

                // タイトルを置換する
                $content = str_replace($matches[0][$i], $title_with_id, $content);
            }

            $toc_html .= '</ul>';
            $toc_html .= '</div>';
        }

        // 投稿本文に目次のHTMLを挿入する
        $content = $toc_html . $content;
    }

    return $content;
}
add_filter('the_content', 'generate_article_toc');

これでH2、H3、タイトルごとに異なるスタイルの適用が可能です。

まとめ

あとはスタイルやCSSクラス名など、目次のデザインに関する部分を必要に応じてカスタマイズして完成。
プラグンを使用せず、投稿記事のみに目次を作成することができます。