見出し画像

wordpressの投稿に目次を入れる際にプラグインを使わない方法(shabellbase更新ログ 2023.3.20)

wordpressの投稿にデフォルトの目次だと、複数ページに記事を分割すると目次もページごとに分かれてしまうのがネックで、なかなか複数ページを導入できないのですが、その際の対応策をご紹介。
複数ページに分割した場合にも、全ページ分の目次を全てのページの上部に表示させる方法です。
プラグインを使用しないのでページスピードも落ちず、おすすめの対策方法です。
ぜひ試してみて下さい。

運用メディアshabellbaseの現在、使用しているテーマはthe thorです。
Cocoonにも対応しています。

長文となった記事を複数ページに分割したりすると、それらのページごとの目次が作られます。
SEOの観点だったり、基本的な考え方のベースにページ単位で完結するというものがあったりするのでしょう。でも、分割されていても、記事が一つなら、目次もその記事全体分で一つという方が、しっくりくるという人もいるでしょう。また、2ページ目を読み進めている人が、1ページ目のあの箇所に戻りたいという人もいるでしょう。

functions.phpにコードを書きこむ

the thorにももちろん、目次表示の機能はあるのですが、表示しない設定にします。[the thor 設定]の[投稿ページ設定]の[目次設定]から、[目次を表示するか選択]の表示する→表示しないに変更してください。

では、早速、複数ページに分割された記事で、全ページ分の目次を全ページに表示させる為のコードです。[外観]の[テーマエディター]から、functions.phpに下記のコードを書きこみます。

記事中のhタグに応じて目次を作っていきます。ひとまず、h1~h6全てに対応します。本来h1タグは記事タイトル以外では使わないルールですが、WordPressではh1タグを使えない仕様にはなっていないので、対応しています。このコードの特徴は「$up_down」という配列にリストを作るためのタグ「ol」と「li」の組み合わせを11個用意して、連続するhタグの階層差に着目して呼び出します。それによってループの回数を減らし、タグの微調整はWordPressのタグ補正機能に委ねることにより、50行足らずのシンプルなコードで実現しています。


「以下を子テーマ用の関数を書く」の下に貼付してください。

//目次をページ跨いでも表示するコード
function toc_by_percredere($content){
  if(is_singular()){
    global $post;
    $current_page_num = (get_query_var('page') == 0) ? 0 : get_query_var('page') - 1;
    $htags = array();
    $tag_num = array();
    $p_link = get_permalink();
    $pages = explode('<!--nextpage-->', $post->post_content);
    $up_down = array("</li></ol></ol></ol></ol></ol></li>", "</li></ol></ol></ol></ol></li>", "</li></ol></ol></ol></li>", "</li></ol></ol></li>", "</li></ol></li>", "</li>", "<ol>", "<ol><ol>", "<ol><ol><ol>", "<ol><ol><ol><ol>", "<ol><ol><ol><ol><ol>");
    for($p = 0; $p < count($pages); $p++){
      preg_match_all('/(<h([1-6])>.+)<\/h[1-6]>/u', $pages[$p], $tag_each_page, PREG_SET_ORDER);
      $htags[] = array_column($tag_each_page,1);
      $tag_num = array_merge($tag_num, array_column($tag_each_page, 2));
    }
    if(!empty($tag_num)){
      $tag_num[] = min($tag_num);
      $htag_init = $tag_num[0] - min($tag_num) + 6;
    }
    $c = 0;
    for($a = 0; $a < count($htags); $a++){
      for($b = 0; $b < count($htags[$a]); $b++){
        $htags_diff = $tag_num[$c + 1] - $tag_num[$c] + 5;
        if($a == $current_page_num){
	  $for_toc .= preg_replace('/<h[1-6]>/u', "<li><a href='". "#". $b. "'>", $htags[$a][$b]). "</a>". $up_down[$htags_diff];
          $content = preg_replace('/(<h[1-6])>/u','$1'. " id='". $b. "'>", $content, 1);
        }else{
          if($a == 0){
            $for_toc .= preg_replace('/<h[1-6]>/u', "<li><a href='". $p_link. "#". $b. "'>", $htags[$a][$b]). "</a>". $up_down[$htags_diff];
          }else{
            $for_toc .= preg_replace('/<h[1-6]>/u', "<li><a href='". $p_link. ($a + 1). "/#". $b. "'>", $htags[$a][$b]). "</a>". $up_down[$htags_diff];	
          }
        }
        $c++;
      }
    }
    if($current_page_num == 0){
      $content = preg_replace('/(<h[1-6].+<\/h[1-6]>)/u', "<div class='toc'><div class='toc-title'>目次</div>". $up_down[$htag_init]. $for_toc. "</ol></div>". '$1', $content, 1);
    }else{
      $content = "<div class='toc'><div class='toc-title'>目次</div>". $up_down[$htag_init]. $for_toc. "</ol></div>". $content;	
    }
  return $content;
  }
}
add_filter('the_content','toc_by_percredere');
//目次をページ跨いでも表示するコードここまで

※wordpressのテーマエディター内で保存した際に、エラーが出て保存できない場合には、サーバー内より該当するthe thorのchild内にあるfunctions.phpに、以下を書き込みます。
方法:サーバーパネルより、public_html → wp-content → themes →  the-thor-child → functions.php
私もエラーが出てしまい、保存できなかったので、この方法で実行しました。

目次のスタイルを整える

上記のコードだけで、目次は生成されますが、少しスタイルを整えたり、表示、非表示の切り替えができるようにします。この辺は皆さんのお好みでカスタマイズしてみてください。

style.cssにコードを書きこむ

目次表示の微調整と表示、非表示(open、close)切替の設定のコードです。[外観]の[テーマエディター]から、style.cssに下記のコードを書きこみます。

※私は、こちらもエラー出てしまったので、一旦はthe thorのコントロールパネル → 追加CSSから追加でスタイル決めてから、サーバーパネル内のstyle.cssに下記のコードを書き込みました!

.toc{
   margin:auto;
	border: 1px dotted #D8D8D8;
    padding: 20px;
    display: inline-block;
}
.toc-title::after {
   content: '[close]';
   margin-left: .5em;
   cursor: pointer;
   font-size: .8em;
}
.toc-title.active::after {
   content: '[open]';
}
.article ol{
   padding-left:15px;
}

javascript.jsにコードを書きこむ

最後に、目次の表示、非表示を動作させるコードです。[外観]の[テーマエディター]から、javascript.jsに下記のコードを書きこみます。

$('.toc-title').click(function(){
   $(this).toggleClass("active").next().fadeToggle();
})

これで、スタイルも整って、表示、非表示もできる目次が自動で生成されます。

shabellbaseのサイト構築に2022年2月からジョインしましたが、これまでの山のようなSEO検証結果やUIUXでのサイト修正のログが無く・・・

ひとまとめにして今後の皆様の引き出しのヒントに繋がれがいいな、と、思い作ることに決めました。
実を言うと、自分でbookmarkやwikiでキープしたりログが限界を迎え、どうするかと悩んだ末にまずはnoteに残すことに致しました。

かなり一握りの方の活用となるかと思いますが、今後も
継続して投稿させていただき、shabellbaseがどうしてSEOで大きく成長したかをご紹介できたら幸いです。

質問やお問合せも受け付けておりますので、お気軽にご相談ください。

最後に、今回私がgoogle検索から参照したブログを紹介させていただきます。
ありがとうございました。
【WordPress】複数ページに分割された記事で、全ページ分の目次を表示させる方法


この記事が気に入ったらサポートをしてみませんか?