WordPress プラグインなしで記事の見出しから目次を作成

WordPress でプラグインを使用しないで、記事の見出しから目次を作成する方法を紹介します。

※ ちなみに、目次は英語で table of contents (【略】 TOC )です。

ググってみると既に多くのサイトで紹介されていますが、JavaScript (jQuery) による実装ばかりだったので、ここでは PHP コード (functions.php) による実装(目次を作成する部分)をしてみました。

PHP コード

functions.php などに下記のコードを記述します。

/**
 * 目次ショートコードです。
 *
 * @version 3.0.0
 */
class Toc_Shortcode {

	private $add_script = false;
	private $atts = array();

	public function __construct() {
		add_shortcode( 'toc', array( $this, 'shortcode_content' ) );
		add_action( 'wp_footer', array( $this, 'add_script' ), 999999 );
		add_filter( 'the_content', array( $this, 'change_content' ), 9 );
	}

	function change_content( $content ) {
		return "<div id=\"toc_content\">{$content}</div>";
	}

	public function shortcode_content( $atts ) {
		global $post;

		if ( ! isset( $post ) )
			return '';

		$this->atts = shortcode_atts( array(
			'id' => '',
			'class' => 'toc',
			'title' => '目次',
			'toggle' => true,
			'opentext' => '開く',
			'closetext' => '閉じる',
			'close' => false,
			'showcount' => 2,
			'depth' => 0,
			'toplevel' => 2,
			'scroll' => 'smooth',
		), $atts );

		$this->atts['toggle'] = ( false !== $this->atts['toggle'] && 'false' !== $this->atts['toggle'] ) ? true : false;
		$this->atts['close'] = ( false !== $this->atts['close'] && 'false' !== $this->atts['close'] ) ? true : false;

		$content = $post->post_content;

		$headers = array();
		preg_match_all( '/<([hH][1-6]).*?>(.*?)<\/[hH][1-6].*?>/u', $content, $headers );
		$header_count = count( $headers[0] );
		$counter = 0;
		$counters = array( 0, 0, 0, 0, 0, 0 );
		$current_depth = 0;
		$prev_depth = 0;
		$top_level = intval( $this->atts['toplevel'] );
		if ( $top_level < 1 ) $top_level = 1;
		if ( $top_level > 6 ) $top_level = 6;
		$this->atts['toplevel'] = $top_level;

		// 表示する階層数
		$max_depth = ( ( $this->atts['depth'] == 0 ) ? 6 : intval( $this->atts['depth'] ) );

		$toc_list = '';
		for ( $i = 0; $i < $header_count; $i++ ) {
			$depth = 0;
			switch ( strtolower( $headers[1][$i] ) ) {
				case 'h1': $depth = 1 - $top_level + 1; break;
				case 'h2': $depth = 2 - $top_level + 1; break;
				case 'h3': $depth = 3 - $top_level + 1; break;
				case 'h4': $depth = 4 - $top_level + 1; break;
				case 'h5': $depth = 5 - $top_level + 1; break;
				case 'h6': $depth = 6 - $top_level + 1; break;
			}
			if ( $depth >= 1 && $depth <= $max_depth ) {
				if ( $current_depth == $depth ) {
					$toc_list .= '</li>';
				}
				while ( $current_depth > $depth ) {
					$toc_list .= '</li></ul>';
					$current_depth--;
					$counters[$current_depth] = 0;
				}
				if ( $current_depth != $prev_depth ) {
					$toc_list .= '</li>';
				}
				if ( $current_depth < $depth ) {
					$class = $current_depth == 0 ? ' class="toc-list"' : '';
					$style = $current_depth == 0 && $this->atts['close'] ? ' style="display: none;"' : '';
					$toc_list .= "<ul{$class}{$style}>";
					$current_depth++;
				}
				$counters[$current_depth - 1]++;
				$number = $counters[0];
				for ( $j = 1; $j < $current_depth; $j++ ) {
					$number .= '.' . $counters[$j];
				}
				$counter++;
				$toc_list .= '<li><a href="#toc' . ($i + 1) . '"><span class="contentstable-number">' . $number . '</span> ' . $headers[2][$i] . '</a>';
				$prev_depth = $depth;
			}
		}
		while ( $current_depth >= 1 ) {
			$toc_list .= '</li></ul>';
			$current_depth--;
		}

		$html = '';
		if ( $counter >= $this->atts['showcount'] ) {
			$this->add_script = true;

			$toggle = '';
			if ( $this->atts['toggle'] ) {
				$toggle = ' <span class="toc-toggle">[<a class="internal" href="javascript:void(0);">' . ( $this->atts['close'] ? $this->atts['opentext'] : $this->atts['closetext'] ) . '</a>]</span>';
			}

			$html .= '<div' . ( $this->atts['id'] != '' ? ' id="' . $this->atts['id'] . '"' : '' ) . ' class="' . $this->atts['class'] . '">';
			$html .= '<p class="toc-title">' . $this->atts['title'] . $toggle . '</p>';
			$html .= $toc_list;
			$html .= '</div>' . "\n";
		}

		return $html;
	}

	public function add_script() {
		if ( ! $this->add_script ) {
			return false;
		}

		$var = wp_json_encode( array(
			'open_text' => isset( $this->atts['opentext'] ) ? $this->atts['opentext'] : '開く',
			'close_text' => isset( $this->atts['closetext'] ) ? $this->atts['closetext'] : '閉じる',
			'scroll' => isset( $this->atts['scroll'] ) ? $this->atts['scroll'] : 'smooth',
		) );

		?>
<script type="text/javascript">
var xo_toc = <?php echo $var; ?>;
let xoToc = () => {
  const entryContent = document.getElementById('toc_content');
  if (!entryContent) {
    return false;
  }

  /**
   * スムーズスクロール関数
   */
  let smoothScroll = (target, offset) => {
    const targetRect = target.getBoundingClientRect();
    const targetY = targetRect.top + window.pageYOffset - offset;
    window.scrollTo({left: 0, top: targetY, behavior: xo_toc['scroll']});
  };

  /**
   * アンカータグにイベントを登録
   */
  const wpadminbar = document.getElementById('wpadminbar');
  const smoothOffset = (wpadminbar ? wpadminbar.clientHeight : 0) + 2;
  const links = document.querySelectorAll('.toc-list a[href*="#"]');
  for (let i = 0; i < links.length; i++) {
    links[i].addEventListener('click', function (e) {
      const href = e.currentTarget.getAttribute('href');
      const splitHref = href.split('#');
      const targetID = splitHref[1];
      const target = document.getElementById(targetID);

      if (target) {
        e.preventDefault();
        smoothScroll(target, smoothOffset);
      } else {
        return true;
      }
      return false;
    });
  }

  /**
   * ヘッダータグに ID を付与
   */
  const headers = entryContent.querySelectorAll('h1, h2, h3, h4, h5, h6');
  for (let i = 0; i < headers.length; i++) {
    headers[i].setAttribute('id', 'toc' + (i + 1));
  }

  /**
   * 目次項目の開閉
   */
  const tocs = document.getElementsByClassName('toc');
  for (let i = 0; i < tocs.length; i++) {
    const toggle = tocs[i].getElementsByClassName('toc-toggle')[0].getElementsByTagName('a')[0];
    toggle.addEventListener('click', function (e) {
      const target = e.currentTarget;
      const tocList = tocs[i].getElementsByClassName('toc-list')[0];
      if (tocList.hidden) {
        target.innerText = xo_toc['close_text'];
      } else {
        target.innerText = xo_toc['open_text'];
      }
      tocList.hidden = !tocList.hidden;
    });
  }
};
xoToc();
</script>
		<?php
	}

}

new Toc_Shortcode();

ショートコード

投稿または固定ページの表示したい場所に toc ショートコードを記述します。

[toc]

使用例:

[toc title="目次" depth="2"]

オプション

オプションデフォルト説明
id“”ID です。
class“toc”クラスです。
省略(”” を指定) することはできません。
title“目次”目次のタイトルです。
toggle“true”目次リストの開閉リンクを表示するかどうか。
表示する場合 “true”、表示しない場合は “false”。
opentext“開く”開くリンクのテキストです。
closetext“閉じる”閉じるリンクのテキストです。
close“false”最初に目次リストの開閉リンクを閉じた状態にするかどうか。
閉じた状態の場合は “true”、開いた状態の場合は “false”。
showcount2目次を表示する見出し項目の数(以上)です。
depth0出力する階層数(階層レベルではありません)です。
0 の場合はすべての階層を表示します。
toplevel=”2″ depth=”4″ の場合は、h2, h3, h4, h5 のヘッダーが対象となります。
toplevel2トップの階層のヘッダー(1 から 6)を指定します。
scroll“smooth”スクロールの動作を指定します。
スクロールするのに滑らかにアニメーションする場合は “smooth”、一回のジャンプで瞬時に行う場合は “auto”。

スタイル(CSS)

スタイル(CSS)の例です。テーマの style.css 等に記述してください。

.toc {
    width: auto;
    display: table;
    margin: 0 0 10px;
    padding: 10px;
    color: #333;
    word-break: break-all;
    word-wrap: break-word;
    border: #ccc solid 1px;
    border-radius: 3px;
    background-color: #fafafa;
}
.toc .toc-title {
    margin: 0;
    padding: 0;
    text-align: center;
    font-weight: bold;
}
.toc .toc-toggle {
    font-weight: normal;
    font-size: 90%;
}
.toc ul {
    list-style: none;
}
.toc .toc-list {
    margin: 0;
    padding: 0;
}

サンプルイメージ

toc

投稿に目次を自動挿入

下記コードは、全ての投稿に目次を自動挿入するサンプル コードになります。

このサンプル コードでは、全ての投稿(シングル)ページの h2 ヘッダー(見出し2)の直前に目次を挿入しています。

function add_toc_content( $content ) {
	if ( is_single() ) {

		$shortcode = '[toc showcount="4"]';

		$pattern = '/<h2.*?>/i';
		if ( preg_match( $pattern, $content, $matches ) ) {
			$content = preg_replace( $pattern, $shortcode . $matches[0], $content, 1 );
		}
	}
	return $content;
}

add_filter( 'the_content', 'add_toc_content', 10 );

追記

2016年4月20日 jQuery バージョン 1.12 でエラーが発生する不具合を修正しました。

2017年3月9日 ヘッダーが順番に並んでいない場合に正しく目次を作成できない不具合を修正しました。

2017年3月12日 コードを改修しました(修正はなし)。念のため jQuery をエンキュー(組み込み)する処理を追加しました。

2017年7月7日 目次の開閉リンクをクリックすると、ページトップへスクロールする不具合を修正しました。

2017年11月23日 最初に目次の開閉リンクを閉じた状態にするためのオプションを追加しました。

2017年12月4日(バージョン1.0.0) 閉じた状態オプションを指定した場合に正しく目次を作成できない不具合を修正しました。

2017年12月5日(バージョン1.1.0) ページに目次を複数配置できるように変更しました。

2018年8月20日(バージョン2.0.0) 目次を作成する対象のコンテンツを自動取得するように変更しました。これに伴い、targetclass パラメータを削除しました。

2019年6月30日(バージョン2.0.1) 「投稿に目次を自動挿入」の場合、アンカーリンクにスクロールしない不具合を修正しました。

2019年9月17日(バージョン2.0.2) JavaScript をフッターに移動しました。

2021年4月19日(バージョン3.0.0) jQuery を使用しない (組み込まない) ようにしました。

コメント

  • 石鷹さんが「WordPress プラグインなしで記事の見出しから目次を作成(https://xakuro.com/blog/wordpress/277)」で紹介されているPHPコードを使わせて頂いたのですが、どうしても目次の値がすべて「0」になってしまいます。目次の値を1,2,3…と順に並ぶようにしたいのですが、どうすればよいでしょうか。ご教授お願い致します。ちなみに、ショートコードは現在、[toc title="目次" toplevel="2" depth="2"]と入力しています(目次をh2とh3だけで作りたいから)。

    • すみません、コードに不具合がありました。
      コードを修正しましたので、もう一度お試しください。
      お手数をおかけして申し訳ございません。m(__)m

      • 早速ご対応いただき誠にありがとうございました。ただ、先日と同じコード([toc title=”目次” toplevel=”2″ depth=”2″])を入力したところ、h2でしか目次が生成されず(下層のh3では目次が生成されない)、各目次リンクをクリックしても各見出しに移動しないという現象が起こりました。とくに急を要しているわけではないので、時間をかけてゆっくりと対処していただいてかまいません。こちらでもコードの不具合を修正できないか試みてみます。

    • 度々すみません。指定した階層よりも実際の階層が深い場合に正しく動作しませんでした。
      とりあえず修正したもとをアップしましたが、週末にでもじっくり動作確認したいとおもっているので、お急ぎでなければ、しばらくお待ちください。
      それにしても改めてソースををみてみるとぐちゃぐちゃしていて汚いなと反省しています。

      • そんなことないですよ。石鷹さんのコードなら「PageSpeed Insights」 にも「The W3C Markup Validation Service」にも引っかからないので、とても助かっています。WordPressの目次作成プラグイン「Table of Contents」だとどちらか一方に必ず引っかかってしまうんですよ。気長に待っているので、どうか無理しないでくださいね。

    • 一通りの動作確認してみましたが、正しく動作しているようです。
      ただし、ちょっとだけコードを(シンプルに)改修し、念のため jQuery を組み込む処理を追加したものをアップしたので、今回のものを使用してみてください。
      お手数かけます。m(__)m

  • 石鷹さんはじめまして。
    ショートコードを[toc title="目次" depth="0"]で使用しました。
    すると閉じる、開くを押すとページトップにスクロースしてしまうのですが、スクロールしない事は出来ないでしょうか。Javascriptで何かソースが必要でしょうか。

    お忙しいところすみません。よろしくお願いします。

    • こんにちは
      開閉リンクのリンク先(href)を “#” にしていたためスクロールしていました。
      スクロールしないほうがいいですよね。というかバグですね。コードは修正しておきます。
      修正箇所は下記の通りです。
      101行目
      $toggle = ' <span class="toc-toggle">[<a class="internal" href="#">' . $this->atts['closetext'] . '</a>]</span>';
      $toggle = ' <span class="toc-toggle">[<a class="internal" href="javascript:void(0);">' . $this->atts['closetext'] . '</a>]</span>';

      • ありがとうございます!!開く、閉じるを押してもページトップにスクロースされなくなりました。

        あと、もうひとつ質問なのですが、目次のタイトルがダブルコーテーションで囲まれて表示されてしまいます。該当すると思われる箇所のtoc-titleのソースを見たのですがダブルコーテーションがどこにも記述されていないように見えるのにダブルコーテーションが表示されてしまいます。

        キャッシュの問題なのでしょうか?できれがこのダブルコーテーション消したいのですが手段はありますか?

    • ダブルコーテーション(”)が全角になっているのかもしれません。チェックしてみてください。
      それから、[toc title="目次" depth="0"] でしたら、デフォルトのパラメーターなので [toc] とするだけでも OK ですよ。

  • この記事のコードを実際にfunction.phpに書いてみたのですが、そのまま貼ると何故かページの読み込みが出来なくなってしまいます。
    Twenty Twelveをベースにカスタマイズしているのですが、何か考えられる原因は思い当たりますでしょうか。
    php初心者なりに努力しているのですが、どうもうまく行かず。。
    アドバイスやヒントを頂ければ幸いです。

    • こんにちは
      当該コードの先頭の <?php の行を削除してみてください。
      削除してもページが読み込めない場合は、下記ページを参考にエラーを確認してみてください。
      https://wpdocs.osdn.jp/WordPressでのデバッグ
      当該コードのエラーはもちろん、それ以外でも、なるでく対応していきたいとおもいますので、返信お待ちしております。ではでは。

      • 返信ありがとうございます。
        さっそく先頭行を削除してみたところ無事ページは表示されました。

        しかし「閉じる」や、h2,3タグまでのジャンプが効かない状態になっています。今現在こちらでも試行錯誤しているところです。

      • もう一度トライしたところ無事表示されました!
        大変丁寧に対応して頂きありがとうございました!

        • おっ、よかった!
          今後も何かありましたら気軽にコメントしてください。

  • 初めまして。
    プラグインなしで目次を作りたくて、こちらの記事にたどり着きました。
    簡単に目次が作れて非常に感謝しています。

    1点質問なのですが、はじめに目次を閉じた状態にするにはどこのコードを変えれば良いのでしょうか。
    お手隙で構いませんので、返信いただけたら嬉しいです!

    • こんにちは
      おっ、そうですよね初めに閉じた状態がいい場合ありますよね。
      早速、初めに閉じた状態にするためのショートカットのオプション(close)を追加しました。詳細は本文を参照してください。
      なお、デフォルトでは開いた状態としたのでオプションを指定するか、コードの 'close' => false;(26 行目)の false を true にしてください。

  • はじめまして!使い易い目次のコード、ありがとうございます!
    早速導入させて頂いたのですが、目次の数字の消し方がわかりません・・・。
    教えていただければ幸いです。

    • こんにちは、コメントありがとうございます。
      目次の数字は、下記のスタイル(CSS)で消すことができます。テーマの style.css またはカスタマイズの追加 CSS 等に追記してみてください。
      .toc .contentstable-number { display: none; }

      • .toc を入れ忘れておりました!!!
        おかげさまで消すことができました。ご親切にありがとうございました。

  • 優良テーマの「TCD」の「gorgeous」にテーマを変更したら、それまできちんと動いていた目次移動が、目次の表示はできるのですがクリックしても移動しなくなってしまいました。何か方法はないでしょうか?

    • こんにちは、コメントありがとうございます。
      有料テーマなので検証できていませんが、
      [toc targetclass="post"]
      では、どうでしょうか。
      コードを変更する場合は、40行目の
      'targetclass' => 'entry-content',
      を、
      'targetclass' => 'post',
      へ変更してみてください。

      • 出来ました!

        テーマを変えたら突然動かなくなり、何日も悩んでいたので感動です!本当にありがとうございました。

  • はじめまして。
    コード使用させていただいております。
    ありがとうございます。

    ご質問です。
    h2タグより下の(h3以下)階層で目次を表示させたいと考えております。
    表示自体は出来るのですが、h2タグに入っている「id=”toc2″」が、目次のh3を表示しているリンクに入ってしまいます。

    お手数をおかけいたしますが、ご教授いただけますでしょうか。

    • こんにちは、初めまして。
      すみません、ちょっと症状を把握できていません。目次の表示は正しいがリンクが正しくないということでしょうか?
      もう少し具体的(ショートコードのパラメータやヘッダー構成など)に教えてもらえませんか。

      ショートコード:
      [toc toplevel=3]

      ヘッダー構成:
      ヘッダー2
       ヘッダー3
       ヘッダー3
        ヘッダー4
       ヘッダー3
      ヘッダー2
       ヘッダー3

      • 迅速なお返事ありがとうございます。
        現状をお伝えいたします。

        HTML内の自動ID挿入で、
        ヘッダー1(h1)タグに「id=”toc1″」、
        ヘッダー2(h2)タグに「id=”toc2″」、
        ヘッダー3(h3)タグに「id=”toc3″」、
        が挿入されており、

        目次のリンク生成の始まりが「a href=”#toc2″」
        となっております。

        「’toplevel’ => 3,」でヘッダー3(h3)タグからスタートさせたいです。

        ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー
        ‘showcount’ => 0,
        ‘depth’ => 2,
        ‘toplevel’ => 3,

        $shortcode = ‘[toc showcount="4"]‘;
        $pattern = ‘//i’;

        ヘッダー構成:
        ヘッダー1
         ヘッダー2
          ヘッダー3
           ヘッダー4
          ヘッダー3
          ヘッダー3

        説明が下手ですがわかりますでしょうか?

    • 「投稿に目次を自動挿入」のコードにて、自動挿入する場合のことでしょうか?
      この場合は、

      $shortcode = '[toc showcount="4"]';

      $shortcode = '[toc toplevel="3"]';

      目次を挿入する位置をヘッダー3の直前にする場合は、

      $pattern = '/<h2.*?>/i';

      $pattern = '/<h3.*?>/i';

      となります。

      • ありがとうございました。

        はい。
        投稿に目次を自動挿入です。

        「’targetclass’ => ”,」の設定をh1タグのクラスがないところに変更したらうまくいきました。

        もうひとつ教えていただきたいのですが、「showcount」はどんな設定になりますでしょうか?

        • 何度もすみません。

          やはりリンクタグの取得がずれてしまいます。
          サイトリンクをお送りしますので、一度ご確認いただけますでしょうか?

          お手数をおかけいたしますが、何卒よろしくお願いいたします。

          • コードを下記のように変更してみてください。

            'targetclass' => 'entry-content',

            'targetclass' => 'article-body',

            showcount は、この値より目次の項目が少ない場合に目次を表示しないようにするパラメータです。

  • ご回答ありがとうございます。
    ‘targetclass’ => ‘article-body’,に変更いたしました。
    ありがとうございます。

    既定のhタグに「toc」を挿入しないようにすることはできますでしょうか?

    • 「既定のhタグ」とはどこのことかしら?
      過去の投稿に目次を自動挿入しないということかしら?この場合は「投稿に目次を自動挿入」のコードは不要です。目次を挿入したい投稿の場所にショートコードを記述してください。

      • お返事遅くなりすみません。
        サイトURLのページでは「MEMO」のh3タグにtoc6が挿入されています。
        このtoc6が目次に表示されていないためにリンクタグが1つずれているものと思われます。

        「MEMO」のh3タグにtocを追加しないようにすることはできませんでしょうか?

        • 実はあれからバージョンアップ (2.0.0) しました。
          以前は、targetclass パラメータで目次の対象とする場所を指定していましたが、これがコンテンツと一致しない場合に不具合が起こることがありました。
          お手数ですが、コードを更新してみてください。なお、targetclass パラメータは不要となったので削除してください。

          • お世話になります。

            バージョンアップしたコードを使用してみましたが、Hタグにtocクラスが追加されなくて、目次のリンクを押してもスクロールしません。

            何度も何度もすみませんが、ご確認お願いできますでしょうか。

          • 前バージョンのコードでカスタマイズした箇所が残っているようです。
            下記のように変更してみてください。
            $(".article-body :header").each(function () {

            $("#toc_content :header").each(function () {

          • すみません。
            前のバージョンに戻していました…。

            変更してみましたが、うまく動作しません。

            何度もすみませんが、何卒よろしくお願いいたします。

          • 同じ構成のコンテンツを用意して、検証してみたのですが、正しく動作するんですよね。
            謎です。もうすこし検証作業をしてみるつもりですが・・・時間がかかりそうです。
            お手数おかけしてすみません。

          • $content = “{$content}”;

            このコードは何を意味しますでしょうか?

          • $content = "<div id=\"toc_content\">{$content}</div>";
            ですかね。
            これは、目次の対象とするコンテンツを明確に特定するために、コンテンツをラップするタグ(#toc_content)を追加する処理です。
            以前は、パラメータで指定するようにしていましたが、テーマによって変更する必要があったため、このような処理にしました。

          • お世話になります。

            ご回答ありがとうございました。

            他のサイトでテストしてみましたが、動作しませんでした。
            もしかしたらテーマに問題があるのかもしれませんね。
            賢威というテーマを使用しています。

            また何か進展がありましたらご連絡させていただきます。
            ご丁寧な対応感謝しています。引き続きよろしくお願いいたします。

          • 賢威テーマに備わっている目次機能と競合しているのかもしれません。
            有料テーマなのでコードを確認できないため、断定はできませんが・・・。
            お役に立てずにすみません。

  • こんにちは。
    プラグイン無しで目次を表示させる方法を探していたらここにたどり着きました。

    改ページ(ページ分割)タグを入れた時、ほとんどのプラグインがそのページにある見出ししか目次に挿入されません。
    次のページの見出しは次のページの目次に、というような形になります。
    Extended Table of Contents (with nextpage support)というプラグインは分割した2ページ目の見出しもすべて1つの目次内に入るのですが、日本語に対応できていないようです。
    分割したページにも対応する目次にするには、どのようにすればいいかおわかりになりますでしょうか?

    • こんにちは、コメントありがとうございます。
      申し訳ありませんが、今のところ対応する予定はありません。m(__)m
      (時間が取れたら・・・)

      • わざわざ返信ありがとうございます^^
        日本語でページ分割に対応するプラグインは今のところ1つもないので、
        プラグイン化したらかなりの数使われると思います。
        もしお時間があって気が向いたらプラグイン化ぜひお願いします!
        (勝手なお願いすみません。。)

  • お世話になります。
    記事中にある「投稿に目次を自動挿入」というコードをfunction.phpに貼り付けました。目次は表示されるのですが、各目次へのリンクが動作しません。
    ちなみに記事投稿ページで[toc]とするとちゃんと各目次をクリックした際に該当の目次まで飛ぶのですが・・・。
    「投稿に目次を自動挿入」のコードはfunction.phpに書くものではないのでしょうか?

    • こんにちは、コメントありがとうございます。
      すみません、コードに不具合がありました。m(__)m
      コードを修正(バージョン 2.0.1)しましたので、今一度お試しください。

      • 石鷹 様
        迅速なご対応ありがとうございます!
        問題無く表示されることを確認いたしました。プラグインを使わずに目次が清々でき、大変助かっております。

  • お世話になります。
    質問申し訳ありません。
    タグ文章内にタグが入るとタグを
    目次として拾ってくれません。

    どの様に変更すれば良いでしょうか?

    • ご返信ありがとうございます。
      <h4>タグでした。
      パラメータ
      <?php echo do_shortcode(‘[toc toplevel="3" depth="5"]‘); ?>
      タグ
      <h4>○○○○○○○○○<br>○○○○○○○</h4>
      パラメータとタグは上記の様になっています。

      • 同じ条件で検証してみましたが、問題なく目次として拾ってきました。
        ちょっと分からないですね。もう一度、コードを貼り直して確認してみてもらえませんか?
        お手数おかけしてすみません。m(__)m

        • こちらこそお手数おかけします。
          試してみます。
          ありがとうございました。

  • お世話になります。
    質問申し訳ありません。
    <h3></h3>タグ文章内に<br>タグが入ると<h3></h3>タグを
    目次として拾ってくれません。

    どの様に変更すれば良いでしょうか?

    • こんにちは、コメントありがとうございます。
      返信が遅くなってすみません m(__)m
      ヘッダータグ内にタグが含まれている場合も、目次として拾う作りにはなっています。h3 タグに br タグを含めて検証してみましたが、問題なく目次として拾ってきました。
      もう少し具体的(使用テーマ、HTML、ショートコードのパラメータなど)に教えてもらえますか?

  • お世話になります。
    質問申し訳ありません。

    投稿に目次を自動挿入にて、目次を「h2 ヘッダー(見出し2)の直前」ではなく、先頭に挿入したい場合はどの様に変更すれば良いでしょうか?

    ご教授宜しくお願いします。

    • こんにちは、コメントありがとうございます。

      add_toc_content() を下記のように変更すると、投稿(コンテンツ)の先頭に挿入されます。

      function add_toc_content( $content ) {
      if ( is_single() ) {
      $shortcode = '[toc]';
      $content = $shortcode . $content;
      }
      return $content;
      }
      add_filter( 'the_content', 'add_toc_content', 10 );

  • 石鷹さんはじめまして。
    プラグイン無しで目次を表示させる方法を探していたらこちらのページにたどり着きました。
    .toc .contentstable-number { display: none; }をCSSに記述すると、すべての目次番号が消えますが、h2のみ目次番号を残す(h3以下を消す)方法はありますでしょうか?
    また、目次リンクをクリックすると一旦ページTOPを表示してから、当該箇所まで降りていく挙動を起こします。
    なにか解決方法がありましたら、お手すきの際にご教示いただけますと幸いです。
    よろしくお願いいたします。

    • こんにちは、コメントありがとうございます。
      >h2のみ目次番号を残す(h3以下を消す)方法はありますでしょうか?
      h2 のみを表示する場合は、下記のショートコードでできると思います
      [toc depth=1]
      ※ 目次が h1 からなら depth=2。
      >目次リンクをクリックすると一旦ページTOPを表示してから、当該箇所まで降りていく挙動を起こします。
      現象を再現できませんでしたが、今回、大幅に PHP コードを変更したので改善されているかもしれません。再度、PHP コードをコピペして試してみてください。

      • 早々にご返信いただきましてありがとうございます。
        PHPコードを書き換えますと、ページTOPに飛ぶ挙動は直りました。
        ありがとうございます。
        >h2のみ目次番号を残す(h3以下を消す)方法はありますでしょうか?
        こちらの質問方法がまずかったようでして、h3のタイトルは表示したまま、番号のみ消したいという意図でした。
        例としては以下の場合に2.1という数字のみ非表示にし、h3のテキストはそのまま残したいです。
        1 テキスト
        2 テキスト
        2.1 テキスト
        よろしくお願いいたします。

        • 下記のような CSS で h3 (h2 が1段目) 以降の番号を消すことができます。
          .toc ul ul .contentstable-number { display: none; }
          h4 以降なら、
          .toc ul ul ul .contentstable-number { display: none; }
          もし消えないようでしたら、!important を付けてみてください。

          • ご返信ありがとうございます。
            希望通りにすることができました。

  • 質問失礼致します。
    目次表示でh3にインデントがされず、全て左揃えで表示されてしまいます。
    もしかすると、リセットcssが原因かもしれませんが、どのプロパティかわかりません。
    原因わかりますでしょうか?

    • こんにちは、コメントありがとうございます。
      下記 CSS ではどうでしょうか?
      .toc ul ul { padding-left: 2rem; }
      反映されない場合は、!important を付与してみてください。
      .toc ul ul { padding-left: 2rem !important; }
      ※ 2rem は適当に変更してください。

      • ありがとうございます!
        解決いたしました!

        追加で質問なのですが、目次の開閉ボタンの角かっこ( [] )とテキストを削除し、画像を当てることは可能でしょうか?

        • 下記のような CSS で画像を当てることができます。
          .toc .toc-toggle {
          font-size: 0 !important;
          }
          .toc .toc-toggle .internal::before {
          content: '';
          display: inline-block;
          width: 28px;
          height: 28px;
          background-image: url(//example.com/画像.jpg);
          background-size: contain;
          vertical-align: top;
          }

  • はじめまして。
    こちらのコードを少し編集して使用させていただいております。
    ありがとうございます!
    こちらの内容を元に自分のブログに共有したいのですが、
    大丈夫でしょうか?

    • はじめまして、こんにちは。
      ライセンス表記のないコード(このページのコードなど)はご自由に利用してください。もちろん改変して配布しても問題ありません。CC0 ライセンスを選択されても問題ありません。ライセンス表記のあるコード(「Search Regex による Markdown 記法の一括置換」ページのコードなど)は、そのライセンスに従ってください。
      記事の文章や画像に関しては常識の範囲内でご利用ください。詳細は下記ページをご覧ください。
      https://xakuro.com/about/

コメントを残す

メールアドレスが公開されることはありません。

日本語でコメントを入力してください。(スパム対策)