【Godios】目次を自動表示するカスタマイズをしてみた

当サイトで利用している無料テーマ「Godios」で、目次を自動表示したかったので紹介します。

目次を手動で表示する方法は既にある

投稿画面のテキストエディタ上にクイックタグが提供されています。

これをクリックすると目次のテンプレートが挿入されますが、自分で目次に沿って書き直ししなければなりません。見出しが数個であれば手作業でもいいかもしれませんが、数千文字のコンテンツになると手動で目次を設定するのは非常に大変です。 目次といえば、WordpressプラグインのTable of Contentsが有名ですが、これを使ってしまうとGodios標準の見た目の良いデザインが損なわれてしまうんですよね。 それが嫌なので実装しました。

実現したこと

Godiosの既存の目次を動的に追加する

クイックタグをわざわざ使わなくてもh2、h3タグを自動的に目次化できるようにします。「既存の」というところがポイントです。デザインを損なわずに目次を表示したいので。

手順

※Godiosの子テーマを導入していること

①子テーマのfunctions.phpに下記コードを追加する

function read_toc_scripts(){
  wp_enqueue_script( 'toc', get_stylesheet_directory_uri() .'/js/toc.js', array('jquery') );
}
add_action( 'wp_enqueue_scripts' , 'read_toc_scripts' );
function toc_in($the_content) {
  if (is_single()) {
    $toc = "<div id=\"contents\"></div>";
 
    $h2 = '/<h2.*?>/i';//H2見出し
    if ( preg_match( $h2, $the_content, $h2s )) {
      $the_content  = preg_replace($h2, $toc.$h2s[0], $the_content, 1);
    }
  }
  return $the_content;
}
add_filter('the_content','toc_in');

②jsファイルを実装する

子テーマのjsフォルダ直下にtoc.jsを作成し、下記コードを貼り付け、保存します

※jsのファイル名は任意で構いませんが、その場合は上記コードの2行目のファイル名を合わせる必要があります。


jQuery(function($){
let toc = '<ol>';
    // 目次の階層の判断に使用する変数
    let hierarchy;
    // h2、h3の判断に使用する変数 
    let element = 0;
    // ループの回数をカウントする変数
    let count = 0;
    
    $('article h2,article h3').each(function(){
        // ループのカウント数を増加 
        count ++;  
        // h2、h3タグにIDの属性値を指定
        this.id = 'chapter-' + count;
            
        // 現在のループで扱う要素を判断する条件分岐
        if(this.nodeName == 'H2'){
            element = 0;
        }else{               
            element = 1;
        }  
        
        // 現在の状態を判断する条件分岐
        if(hierarchy === element){ // h2またはh3がそれぞれ連続する場合
            toc += '</li>';
        }else if(hierarchy < element){ // h2の次がh3となる場合
            toc += '<ul>';               
            hierarchy = 1;
        }else if(hierarchy > element){ // h3の次がh2となる場合
            toc += '</li></ul></li>';               
            hierarchy  = 0;
        }else if(count == 1){ // ループ1回目の場合
            hierarchy = 0;
        } 
        
        // 目次の項目を作成。※次のループで<li>の直下に<ol>タグを出力する場合ががあるので、ここでは<li>タグを閉じていません。
        toc += '<li><a href="#' + this.id + '">' + $(this).html() + '</a>';  
    });
    
    // 目次の最後の項目をどの要素から作成したかにより、タグの閉じ方を変更
    if(element == 0){
        toc += '</li></ol>';
    }else if(element == 1){
        toc += '</li></ul></li></ol>';
    }
    
    if (jQuery("article h2")[0]) {
        jQuery("#contents").append('<span class="contents-title">目次</span>'+ toc);
    }
});

参考記事:【jQuery】ページ内の目次を自動出力|h2・h3要素を目次の項目に

 

今後実現したいこと

h4までの項目を目次化する

既存の目次だとh2,h3を想定して作られており、h4まで対応していません。なのでh4まで対応できるようにCSSもカスタマイズします。

目次に開閉機能を付与する

これも地味に大切かなと。コンテンツが長くなれば目次も長くなりがちですが、ページを開いたときに目次が長々と表示されたらユーザーは嫌なはずです。開閉機能を付与して、デフォルトでは閉じた状態にします。

最後に

たかが目次、されど目次。 無料Wordpressテーマ「Godios」は私の中で非常にお気に入りのテーマなのでこれからもどんどんカスタマイズしていきたいと思います。 上記2つも実現次第、紹介します。