menu

【コピペで完成】WordPressで目次の作り方。プラグイン不要です

2023年1月21日

Code

プラグインを使いたくないという方向けに、WordPressで目次を作る方法をご紹介します。

functions.phpにコピペで完成します。

記事の見出しに基づいた目次を自動生成します。

なお見出しが1つしかない時は作成しません。
↓こんなやつですね。

【コピペで作成】目次の作り方

以下をfunctions.phpにコピペする。(作業前にバックアップはとってくださいね)

// 目次
function add_index($content)
{
  if (is_single()) {
    $pattern = '/<h[1-6]>(.+?)<\/h[1-6]>/s';
    preg_match_all($pattern, $content, $elements, PREG_SET_ORDER);
    if (count($elements) >= 1) {
      $toc          = '';
      $i            = 0;
      $currentlevel = 0;
      $id           = 'chapter-';
      foreach ($elements as $element) {
        $id           .= $i + 1;
        $regex         = '/' . preg_quote($element[0], '/') . '/su';
        $replace_title = preg_replace('/<(h[1-6])>(.+?)<\/(h[1-6])>/s', '<$1 id="' . $id . '">$2</$3>', $element[0], 1);
        $content       = preg_replace($regex, $replace_title, $content, 1);
        if (strpos($element[0], '<h2') !== false) {
          $level = 1;
        } elseif (strpos($element[0], '<h3') !== false) {
          $level = 2;
        } elseif (strpos($element[0], '<h4') !== false) {
          $level = 3;
        } elseif (strpos($element[0], '<h5') !== false) {
          $level = 4;
        } elseif (strpos($element[0], '<h6') !== false) {
          $level = 5;
        }
        while ($currentlevel < $level) {
          if (0 === $currentlevel) {
            $toc .= '<ol class="index__list">';
          } else {
            $toc .= '<ol class="index__list_child">';
          }
          $currentlevel++;
        }
        while ($currentlevel > $level) {
          $toc .= '</li></ol>';
          $currentlevel--;
        }
        // 目次の項目で使用する要素を指定
        $toc .= '<li class="index__item"><a href="#' . $id . '" class="index__link">' . $element[1] . '</a>';
        $i++;
        $id = 'chapter-';
      } // foreach
      // 目次の最後の項目をどの要素から作成したかによりタグの閉じ方を変更
      while ($currentlevel > 0) {
        $toc .= '</li></ol>';
        $currentlevel--;
      }
      $index = '<div class="single__index index" id="toc"><div class="index__title">Contents</div>' . $toc . '</div>';
      $h2    = '/<h2.*?>/i';
if (preg_match($h2, $content, $h2s)) {
$content = preg_replace($h2, $index . $h2s[0], $content, 1);
}
}
}
return $content;
}
add_filter('the_content', 'add_index');

CSSもコピペで。ご自由にいじってください。

/* 目次 */ 
.single__index {
  border: 1px solid #d2d2d2;
  padding: 10px;
  border-radius: 10px;
  background-color: #fcfcfc;
}
.single__index .index__title {
  text-align: center;
  font-size: 18px;
}
.single__index .index__title .index__button {
  border: none;
  font-size: 11px;
  color: #4e4e4e;
}
.single__index ul,
.single__index ol {
  border: none !important;
  padding: 0 0 0 30px !important;
  background-color: #fcfcfc !important;
}
.single__index a {
  color: #4e4e4e !important;
  font-size: 13px;
}

コード解説

一応コードの解説です。気になる方のみどうぞ。

function add_index($content)
{
  if (is_single()) {
    $pattern = '/<h[1-6]>(.+?)<\/h[1-6]>/s';
    preg_match_all($pattern, $content, $elements, PREG_SET_ORDER);

この部分では、記事の内容を引数として受け取り、その中の見出し(h1からh6)を抽出しています。is_single()は、表示されているページが単一の投稿ページである場合にtrueを返すWordPressの組み込み関数です。つまり、このコードは単一の投稿ページでのみ動作します。

    if (count($elements) >= 1) {
      $toc          = '';
      $i            = 0;
      $currentlevel = 0;
      $id           = 'chapter-';

ここでは、抽出した見出しの数が1以上である場合に、目次の生成を開始します。$tocは生成される目次のHTMLを保持し、$currentlevelは現在の見出しのレベル(h1からh6までの数値)を保持します。$idは各見出しに付けるIDのプレフィックスです。

if (strpos($element[0], '<h2') !== false) {
          $level = 1;
        } elseif (strpos($element[0], '<h3') !== false) {
          $level = 2;
        } elseif (strpos($element[0], '<h4') !== false) {
          $level = 3;
        } elseif (strpos($element[0], '<h5') !== false) {
          $level = 4;
        } elseif (strpos($element[0], '<h6') !== false) {
          $level = 5;
        }

この部分では、各見出しのレベルを判定しています。見出しのタグ(h2からh6)によって、その見出しのレベルを設定します。

      $index = '<div class="single__index index" id="toc"><div class="index__title">Contents</div>' . $toc . '</div>';
      $h2    = '/<h2.*?>/i';
if (preg_match($h2, $content, $h2s)) {
$content = preg_replace($h2, $index . $h2s[0], $content, 1);
}

最後に、生成した目次を記事の内容に挿入します。具体的には、記事の最初のh2見出しの前に目次を挿入します。

以上が、このコードの主要な動作となります。このコードを使えば、WordPressの記事に自動的に目次を挿入することができます。

Follow Me!

Aji ろぐろぐみー筆者

フリーランスエンジニア。
詳しいプロフィールはこのページで色々書いてます。Twitterもやってます。コメント頂けると陸に上がった魚のようにピチピチ喜びます!

関連記事

コメントはこちらからどうぞ

プライバシーポリシーはこちら
また、コメントはこちらで承認の作業を行うまでは表示されません。ご了承ください。

CAPTCHA