リオラボ
icon

【サンプル】WordPress自作テーマで目次を作る方法 階層化/ネスト【プラグインなし】

この記事ではWordPress自作テーマで目次を作る方法を解説しています。

サンプルコードを紹介していますが、WordPressの投稿に目次を自動生成する機能です。見出しタグ(h2~h6)から目次を自動生成するようになっています。

このコードによって生成される目次は見出しに番号が振られ、見出しの階層(ネスト)が反映されたデザインになります。見出しタグ(h2〜h6)が存在する場合、それぞれに対応した番号が自動的に振られ、見出しが階層化されます。

目次の階層化と番号の振り方

階層化: 例えば、h2タグの中にh3タグがある場合、h2が親要素として扱われ、h3はその中にネストされた要素(子要素)として扱われます。このように、h2からh6までの見出しタグが階層に応じて入れ子(ネスト)状に表示されます。

番号の振り方: 各階層内で番号が振られるようになっており、h2タグは「1.」「2.」のように、h3タグはその親要素であるh2の中で「1.」「2.」のように階層ごとに番号が付きます。

サンプルコード

このコードは、WordPressの投稿に対して目次(Table of Contents)を自動的に生成し、本文の中に挿入する機能を提供します。以下に、各部分を詳しく説明します。

generate_table_of_contents 関数

役割
見出しタグ(h2~h6)から目次を生成し、HTML形式で返す関数です。

引数
$headings:投稿本文から抽出された見出し情報(タグ、テキスト、ID)を含む配列。

処理の流れ
$toc:目次のHTMLを格納する変数で、目次のラップ用の <div> 要素と <ol>(番号付きリスト)で初期化されています。
$current_level:現在処理している見出しの階層(h2~h6)。初期値は1(h2)。
$numbering:各階層の見出しの番号を追跡する配列です。見出しレベルごとに番号が増えるため、各レベルに対して番号を保持します。

見出しの処理
ループで $headings の各見出しを処理します。
$heading_level:見出しタグ(例: h2, h3)のレベル(2, 3など)を取得し、現在の階層と比較します。

階層の変化に応じたリストの制御
見出しのレベルが現在のレベルより高ければ、ネストされたリストを作成するために <ol> を追加。
見出しのレベルが低ければ、現在のレベルに戻るまでリストを閉じるために </ol> を追加します。

番号付け
各レベルの番号をインクリメントし、全階層の番号を結合して番号を作成します。
番号のフォーマットを調整し、先頭の「0」を削除して、最上位のレベルの番号だけを表示します。

見出しのリスト化
各見出しは <li> 要素として目次に追加され、<a> タグでその見出しにリンクされます。

最後の処理
すべての見出しを処理した後、まだ閉じていないリストがあれば、</ol> タグで閉じます。
完成した目次HTMLを返します。

insert_table_of_contents 関数

役割
投稿の本文に対して目次を挿入する関数です。

処理の流れ
見出しの検索:正規表現で本文中の h2~h6 タグをすべて検索します。$heading_pattern 変数に正規表現が定義されています。
<(h[2-6])(.*?)>(.*?)<\/\1> のパターンで、h2~h6タグの開始タグ・終了タグ、その中のテキストをマッチさせます。
preg_match_all() 関数を使って、全てのマッチ結果を $matches 配列に格納します。

見出しの配列作成
見つかった見出しを $headings 配列に格納します。この配列には、タグ名、属性、テキスト、IDが含まれます。
各見出しにはユニークなIDが付与され、heading-1, heading-2 のように番号が振られます。

本文内の見出しにIDを追加
preg_replace_callback() を使用して、見出しにIDを追加しながら本文を置換します。各見出しは <span> タグで囲まれ、IDが挿入されます。

目次の生成と挿入
generate_table_of_contents() 関数を呼び出し、目次を生成します。
最初の h2 タグの前に目次を挿入するために、strpos() 関数を使用して本文中の最初の h2 タグを見つけ、その位置に目次HTMLを挿入します。

add_filter フック

WordPressの the_content フィルターフックを利用して、投稿の本文に目次を自動的に挿入します。

add_filter(‘the_content’, ‘insert_table_of_contents’); で、投稿の本文が表示される際に、insert_table_of_contents() 関数が実行されます。

コード全文

CSS

目次をCSSでデザイン調整しています。

目次全体(.toc__container): 枠線、背景色、角を丸くして、中央に配置。最大幅600pxに制限し、余白とパディングを追加。
タイトル(.toc__title): 文字を中央に揃え。
リスト(.toc__list, .toc__sublist): 左に余白を付け、階層化された見出しをインデント。
リスト項目(.toc__item): アイテム同士の余白をなくす。
リンク(.toc__link): 下線を消し、色は親要素に従わせる。
レスポンシブ対応: 画面幅767px以下では、パディングを左に0にしてモバイル表示に最適化。

好みでデザイン調整してください。