★★★ たった "1日" でできるWordPressブログの作り方講座 ★★★ はじめてみる

WordPressで目次をプラグインなしで表示…具体的に解説

WordPressでの目次表示。

普通はTOC+プラグインを使うと思います。

※ TOC = Table of Content

でも自分で目次表示したい人もいます。

  • 極力プラグインを使いたくない
  • 目次程度なら自力で表示したい

そういう変わった人のために、
プラグインなしで目次表示の方法を解説します。

ここで行う目次実装の概要と注意点

大まかな手順はこのようになってます。

  • 記事内の各見出しに自動でidを割り振る
  • その見出し+idを元に目次を自動生成
  • 目次内から見出しにスクロールもできる

こういう実装を目指すことにします。

当たり前だけど初心者向けではありません。
ギリギリ中級者向けかなという程度の内容です。

だから次の人は試さないでください。

  • WordPressの仕組みを理解してない
  • PHPコードを読めない書けない

そういう人がこの記事に手を出すと、
間違いなくトラブルの原因になります。

もし目次表示のカスタマイズが必要なら…

▼ こういうサービスもあるのでご相談を

WordPressのトラブル解決相談始めました!
WordPressが真っ白になった、デザインが崩れた・・・そんなWordPressのトラブル解決相談ができるサービスをココナラで始めました!もしWPのブログ運営で困った時は是非ご利用ください。お得な割引情報もお知らせ・・・

警告しておきました(念押し)

1.使用中テーマのfunctions.phpを開こう

ここでは使用中テーマを編集していきます。

具体的にはfunctions.phpに対する編集作業です。

▼ 外観 ⇒ テーマファイルエディタを開く

WordPressメニューから 外観 ⇒ テーマファイルエディタ を開く

▼ テーマファイル ⇒ functions.php を開く

テーマファイルエディタを開いた現在使用中テーマのfunctions.phpを編集する

これは本当に重要なファイルです。

この内容を編集して構文エラーが起きたなら、最悪ブログがダウンします。もっとも最近のワードプレスなら更新前に警告してくれますが…

だからここからは慎重に作業してください。

ここまでで2回も念押ししました。

2.見出しに自動でidを振るコード追加

見出しとはh2~h6タグまでのこと

その見出しに自動生成したidを割り当てます。

具体的にはfunctions.phpに以下を追加します。

▼ このようなPHPコード追加

function auto_id_to_headings( $content ) {
	$content = preg_replace_callback(
		'/(\<h[1-6](.*?))\>(.*)(<\/h[1-6]>)/i',  function( $matches ) {
		if ( ! stripos( $matches[0], 'id=' ) ) {
			/// 見出しにidがないなら自動生成
			$matches[0] = $matches[1] . $matches[2] 
				. ' id="' . sanitize_title( $matches[3] ) 
				. '">' . $matches[3] . $matches[4];
		}
		return $matches[0];
	}, $content );
    return $content;
}
add_filter( 'the_content', 'auto_id_to_headings', 10 );

ポイントは見出しのタイトルから自動的にidを設定していることです。連番とか使う方法もあるけど、ここではこの方法を採用しました。

具体的には sanitize_title() によりタイトルから無効文字を除外し、idに使っても問題ない形式にしてます(参考記事 : https://elearn.jp/wpman/function/sanitize_title.html

例えばこういう感じになるはず

<h2>Hello, I'm h2 tag</h2>

↓ 変換後 ↓

<h2 id="hello-im-h2-tag">Hello, I'm h2 tag</h2>
<h2>こんにちは、見出しです</h2>

↓ 変換後 ↓

<h2 id="%e3%81%93%e3%82%93%e3%81%ab%e3%81%a1%e3%81%af%e3%80%81%e8%a6%8b%e5%87%ba%e3%81%97%e3%81%a7%e3%81%99">こんにちは、見出しです</h2>

※ 日本語はエンコードされる

自動でタイトルからidが割り振られます。

3.目次(TOC)を自動生成・表示するコード追加

いよいよ目次(TOC)を生成・表示してみます。

ここでは最初の見出し前に表示してみました。

▼ その具体的なPHPコード

function collate_toc_row($depth, $anchor, $heading) {
	$level = substr($depth, 1);
	if ( $anchor ) {
		return ["<a href='#{$anchor}' class='{$depth} toc-link'>{$heading}</a>", $level];
	} else {
		$slug = sanitize_title($heading);
		return ["<a href='#{$slug}' class='{$depth} toc-link'>{$heading}</a>", $level];
	}
}

function add_toc_before_1st_heading( $content ){
	/// 目次を自動生成して最初の見出し前に表示

	preg_match_all('/<(h\d*)(?: id="(.*?)")?>((.*?))</',$content,$matches);
	$levels = $matches[1];
	$anchors = $matches[2];
	$headings = $matches[3];
	if ( $headings ) {
		/// 見出しが1つ以上あるなら目次表示
		
		$toc = '<div class="toc_container">';
		$toc .= '<div class="title">Table of Contents</div>';
		$collated = array_map('collate_toc_row', $levels, $anchors, $headings );
		$previous_level = 2;
		$toc .= '<ol class="toc-list">';
		foreach ($collated as $row) {
			$current_level = $row[1];
			if (  $current_level == $previous_level ) {
				$toc .= '<li>' . $row[0];
			} else if (  $current_level < $previous_level ) {
				$toc .= str_repeat('</ol>', $previous_level - $current_level) . '<li>'. $row[0];
			} else {
				$toc .= '<ol><li>' . $row[0];
			}

			$previous_level = $row[1];

		}
		$toc .= str_repeat('</ol>', $previous_level) . '</li></ol>';
		$toc .= '</div>';

		$content_parts = preg_split("/(<h\d*)/", $content, 2, PREG_SPLIT_DELIM_CAPTURE);
		$content = $content_parts[0]  . $toc . $content_parts[1].$content_parts[2];
	}
	return $content;
}
add_filter( 'the_content', 'add_toc_before_1st_heading', 11);

長すぎるから細かな解説はしません。

記事内のすべての見出し(h1~h6)をスキャンし、それを元に目次を自動生成。最初の見出しの前にTOCを挟み込んでるだけです。

見出しが1つもない記事には目次表示されません。

4.目次のレイアウト用にCSSを追加

できあがった目次は質素な見た目です。

だからレイアウトを整えます。

具体的には次のようなCSSコードを追加しました。

▼ 目次に適用したCSSコード例

.toc_container{
  overflow: auto;
  padding: 10px;
  background: #f9f9f9;
  border: 1px solid #aaa;
}
.toc_container .title{
  text-align: center;
  padding-top: 10px;
}
.toc-list{
  list-style: none;
  font-size: 20px !important;
  margin: 0;
  padding: 10px;
  float: left;
  position: relative;
  left: 50%;
  transform: translateX(-50%);
}
.toc-list ol{
  list-style: none;
}
.toc-list a{
  font-size: 16px;
}

ここまで読み進められる人なら「このCSSどこに追加すればいいの?分からないよ~(泣」なんてバカなことは言わないはずです。

好きなようにCSSは改変してください。

こんなビジュアルの目次ができた!

できあがった目次はこんなビジュアルです。

プラグインなしで実装した目次の例。目次は自動で各見出しをスキャンして自動生成される。レイアウトはTOC+プラグインを参考にしたが、全て自前のコードで表示できた!

見てわかる通り、レイアウトは完全にTOC+プラグインのそれです。あと目次リンクをクリックすると各見出しにスクロールもしてくれます。

まだ未完全だけど目次としては機能してます。

WordPressでプラグインなしでの目次の作り方は以上。

チャレンジ精神のある人は試してみてください。

The following two tabs change content below.

フク郎

昔はプログラミングに熱中していたが、ブログとWordPressに興味を持ち始め今はサイト・ブログ作りが生きがい。自分の「好き」をブログに変えたい、情報発信したい人に役立つWordPress術・サイト構築術を発信中。一日一歩楽しんでブログ構築できるように読みやすい&楽しい記事作りを心がけています。メールアドレス : fukuropress@gmail.com