WordPressの記事にプラグインなしで目次を作る方法

WordPressの記事ページに、プラグインなしで目次を作成する方法の備忘録です。

目次を表示するjQueryの作成

まずはじめに、記事内の見出し<h2>、<h3>を取得して、目次として一覧で自動表示する「toc.js」を作成します。

jQuery(function ($) {
  var idcount = 1;
  var toc = '<ol>';
  var level = 0;
  jQuery("article h2,article h3", this).each(function () {
    this.id = "toc-id" + idcount;
    idcount++;
    if (this.nodeName.toLowerCase() == "h2") {
      if (level > 0) {
        toc += '</ol></li>';
        level = 0;
      }
    } else if (this.nodeName.toLowerCase() == "h3") {
      if (level == 0) {
        toc += '<li><ol>';
        level = 1;
      }
    }
    toc += '<li><a href="#' + this.id + '">' + jQuery(this).html() + "</a></li>\n";
  });
  toc += '</ol>';
  if (jQuery("article h2")[0]) {
    jQuery("#toc").html('<div class="toc-title">目次</div>' + toc);
  }
   jQuery('a[href^="#"]').click(function(){
        var	speed = 400,
            href= $(this).attr("href"),
            target = $(href == "#" || href == "" ? 'html' : href),
            position = target.offset().top;
        $('body,html').animate({scrollTop:position}, speed, 'swing');
        return false;
    });
});

見出し<h2>と<h3>を取得して、levelに合わせた階層になるようにリストのタグを制御しています。
idcountで見出しのアンカーリンクとなるidの数字を管理しています。

最後の「click(function()」では、hrefに「#」のついたアンカーリンクがクリックされた際に、スクロールするように設定しています。

作成した「toc.js」は、テーマフォルダの中に保存します。テーマファイルに直接記述する場合は、footer.phpの</body>の直前に記入します。
ちなみに「toc」は「table of contents(目次の英語表記)」の略です。

jQueryを読み込む

作成した「toc.js」を読み込むためのスクリプトをfunctions.phpに記述します。テーマファイルに直接記述する場合は不要です。

function toc_enqueue_scripts(){
  wp_enqueue_script( 'toc', get_template_directory_uri() .'/js/toc.js', array('jquery') );
}
add_action( 'wp_enqueue_scripts' , 'toc_enqueue_scripts' );

function.phpを編集に誤りがあると、WordPress自体が動かなくなります。必ずバックアップをとってから慎重に作業します。

記事に目次を設置する

作成した目次は、「<div id=”toc”></div>」と記述するだけで読み込むことができます。

「<div id=”toc”></div>」を記事ページごとに記入した場合、目次を付けないことも、記事内の任意の箇所に読み込むことが可能ですが、毎度記入するのは少し手間です。

single.php内に記入して自動で読み込むこともできます。その場合は、記事内に目次を入れることはできません。

今回は、作成した目次を記事ページ内の一つ目の段落の下に表示出来るようにしてみました。functions.phpに設定を追記します。

function toc_in($the_content) {
  if (is_single()) {
    $toc = "<div id=\"toc\"></div>";
 
    $inpoint = '@<p>(.*?)</p>@si';
    if ( preg_match( $inpoint, $the_content, $inpoints )) {
      $the_content  = preg_replace($inpoint, $inpoints[0].$toc, $the_content, 1);
    }
  }
  return $the_content;
}
add_filter('the_content','toc_in');

preg_matchで記事内の<p>タグの部分を取得し、preg_replaceで一番初めの<p>タグの後ろに目次を表示する<div id=’toc’></div>を挿入しました。

目次は、下記のようなリストの形で一覧表示されます。<h3>の見出しは<h2>の入れ子となって表示されます。

<ol>
  <li><a href="#toc-id1">見出し1</a></li>
  <li><a href="#toc-id2">見出し2</a></li>
  <li>
    <ol>
      <li><a href="#toc-id3">見出し2-1</a></li>
      <li><a href="#toc-id4">見出し2-2</a></li>
    </ol>
  </li>
</ol>

cssでデザインを設定して目次の完成です。
目次をクリックするとアンカーリンクによって、該当箇所の見出しにスクロールします。

目次があることで、記事内の情報の詳細が分かりやすくなり、目的の箇所へのページ遷移も簡単になりました。

WordPressには、目次を簡単に作ることのできるプラグインもたくさんありますが、動作が重くなってしまったり、コードやデザインがサイトにマッチしない場合は、自作してみるのも良いかもしれません。

参考

jQueryを使いプラグインなしで目次をWordPressの記事に自動追加する|plusers

【コピペでできる】WordPress プラグインなしで目次を作成する方法|CodeLabo

関連記事
WordPressで固定ページに投稿ページ一覧を表示する方法
WordPressで固定ページに投稿ページ一覧を表示する方法
WordPressで記事内に同じカテゴリーの記事一覧を表示する方法
WordPressで記事内に同じカテゴリーの記事一覧を表示する方法
RewriteモジュールでURLを書き換える方法
RewriteモジュールでURLを書き換える方法