プラグイン不要!WordPressに目次を表示する方法

WordPressで作ったページに、記事の目次を追加する方法を紹介します。

自作しなくてもTable of Contents Plusなどのプラグインを使えば目次を追加できますが、プラグイン同士の相性が気になる時なんかには便利です。また、自分でコードを把握していると、WordPressをバージョンアップする際に修正が必要かなども、判別しやすくなるという利点もあります。

他には、WordPress以外の記事に目次を付けたくなった場合にも応用が効くと思います。

  • 2016/1/13修正 見出しのレベルが変わった時に、そのレベル以下の見出しの出現回数をリセットするように修正しました。
  • 2016/1/13修正 見出しの番号の後に「.」を表示するように修正しました。

作成物について

今回作成するのは、ページ内にある最初のhタグの前に目次を挿入する機能です。また、記事内に[outline]と書くと、その場所に目次を挿入するようにします。加えて、記事毎に目次出力のON/OFFを切り替えられるようにします。

なお、目次は記事内のh1〜h6タグから組み立てます。

挿入される目次の画像例

挿入される目次の例

第1段階: h1〜h6タグの前に目次を自動挿入

まずは第1段階として、本文から目次を組み立てます。そして、その目次を本文中の最初のhタグの前に挿入するところまで作ります。

作成元本文と作成される目次

第1段階では、以下のような本文から、目次を作成することを目標とします。また、本文のh1〜h6タグに、data-outline属性を追加します。このdata-outline属性は、目次をクリックした時の、移動先の目印になります。

作成元本文

<h1>見出しa</h1>
<h2>見出しaa</h2>
<h2>見出しab</h2>
<h3>見出しaba</h3>
<h2>見出しac</h2>
<h1>見出しb</h1>
<h2>見出しba</h2>
<h3>見出しbaa</h3>

作成される目次

<ul class="indent_1">
  <li>
    <a href="#outline_1">1 見出しa</a>
    <ul class="indent_2">
      <li>
        <a href="#outline_1_1">1.1 見出しaa</a>
      </li>
      <li>
        <a href="#outline_1_2">1.2 見出しab</a>
        <ul class="indent_3">
          <li>
            <a href="#outline_1_2_1">1.2.1 見出しaba</a>
          </li>
        </ul>
      </li>
      <li>
        <a href="#outline_1_3">1.3 見出しac</a>
      </li>
    </ul>
  </li>
  <li>
    <a href="#outline_2">2 見出しb</a>
    <ul class="indent_2">
      <li>
        <a href="#outline_2_4">2.4 見出しba</a>
        <ul class="indent_3">
          <li>
            <a href="#outline_2_4_2">2.4.2 見出しbaa</a>
          </li>
        </ul>
      </li>
    </ul>
  </li>
</ul>

修正後本文

<h1 data-outline="#outline_1">見出しa</h1>
<h2 data-outline="#outline_1_1">見出しaa</h2>
<h2 data-outline="#outline_1_2">見出しab</h2>
<h3 data-outline="#outline_1_2_1">見出しaba</h3>
<h2 data-outline="#outline_1_3">見出しac</h2>
<h1 data-outline="#outline_2">見出しb</h1>
<h3 data-outline="#outline_2_3_2">見出しbaa</h3>

functions.phpにコードを追加

本文から目次(ul, li)を作成

以下のように、目次情報を取得する関数get_outline_infofunctions.phpに定義します。

get_outline_infoは引数に本文を取り、修正された本文と、目次が入った配列を返します。

add_actionに登録

add_outlineという関数を定義して、add_actionを使ってthe_contentにその関数をフックします。

なお、add_outlineの処理内容は以下の通りです。

  1. 目次を表示するページ(個別記事など)かを判定する。
  2. 先ほど作成したget_outline_infoを呼び、目次情報を取得する。
  3. 目次を装飾する。
  4. 最初のhタグの前に、装飾した目次を追加する。

JSファイルにコードを追加

表示・非表示ボタンの処理追加

最後に、非表示ボタンをクリックしたときに目次が消え、表示ボタンをクリックしたときに目次が現れるようにコードを書きます。

目次クリックでスクロールする処理追加

目次をクリックしたときに、hタグまでスクロールするようにコードを書きます。

第2段階: 仕上げ

第2段階として、ショートコード[outline]を有効にします。また、記事単位で目次のON/OFFを切り切り替えられるようにします。

functions.phpにコードを追加

[outline]と書いた場所に目次を挿入

もし本文中に[outline]がある場合は、そのに目次を表示するようにします。本文中に[outline]がない場合は、今までどおり、最初のhタグの前に目次が表示されるようにします。

ページ毎に、目次を非表示にできるようにする。

各個別記事で、カスタムフィールドdisable_outlinetrueを指定すると、目次が表示されないようにします。

完成形コード

完成形のコードはgithub上に公開してあります。

https://github.com/yusukemurayama/blog-samples/tree/master/wordpress_outline

Table of Contents Plusっぽくスタイルを変更

以下のようなスタイルを適用すると、目次がTable of Contents Plusっぽくなって、イケてる感じになります。

Table of Contents Plusっぽくスタイルを適用

この記事が役に立った場合、シェアしていただけると励みになります!!