2016-09-27

Bloggerで目次と見出し番号を自動生成させるカスタマイズ方法

Bloggerで、投稿記事の見出しを元に自動で目次を作成し、かつ各見出しに自動で番号を振るテンプレート・カスタマイズ方法です。

カスタマイズの適用例

具体的にどうなるかと言いますと、以下のように見出し入りの投稿記事を作成すると・・・
Blogger目次カスタマイズ・サンプル下書きの画像

以下のように目次が作成され、各見出しにも対応する番号が自動で添付されます。
目次をクリックでジャンプします。
Blogger目次カスタマイズ・サンプル記事の画像
※記事には「追記の区切り」(<!--more-->)を入れてください。目次は「追記の区切り」の直下に作成されます。

カスタマイズ方法

<head>タグの末尾にカスタマイズ用スクリプトを追記するだけですが、一応手順を載せておきます。
標準テンプレートでは動作確認していますが、テンプレートによっては相性が悪いかもしれません。
事前にバックアップを取ってから作業されることをお勧めします。

変更前テンプレートのバックアップ

既にご自分でカスタマイズされている場合、バックアップを作成しておきましょう。
標準テンプレートでは確認していますが、テンプレートによっては上手く機能しないかもしれません。
以下からバックアップができます。xmlファイルをダウンロードします。
管理画面>テンプレート>右上の「バックアップ/復元」
テンプレートのバックアップ1


>テンプレートをすべてダウンロード をクリック
「このサイトを離れてもよろしいですか?」と警告が出るので、「このページを離れる」を選択するとダウンロードされます。(メッセージのバグ?一応フィードバックしておきました。)

テンプレートのHTML編集よりカスタマイズ用ソースを追加

Bloggerの各ブログ管理画面>テンプレート>HTMLの編集 を選択します。
テンプレート・HTML編集の画像

 <head>タグの末尾にカスタマイズ用ソースを追記します。
ソースを選択し[Ctrl]+[F]を押すと検索窓(右上のSearch:)が開くので</head>で検索します。
</head>の直前に下記カスタマイズ用ソースを挿入します。
内容は後述します。
<script type='text/javascript'>
  //<![CDATA[
  if (typeof(jQuery) == 'undefined') {
    document.write("<scr" + "ipt type=\"text/javascript\" src=\"//ajax.googleapis.com/ajax/libs/jquery/2.1.4/jquery.min.js\"></scr" + "ipt>");
  }
  //]]>
</script>
<script type='text/javascript'>
  //<![CDATA[
  $(document).ready(function() {
    console.log("call func");
    $('a[name="more"]').after("<div id='toc' />");
    var idcount = 1;
    var h2cnt = 0;
    var h3cnt = 0;
    var h4cnt = 0;
    var toc = '';
    var currentlevel = 0;
    $(".post-body h2,.post-body h3,.post-body h4", this).each(function() {
      var chapid = "chapter-" + idcount;
      $(this).before("<div class='chapter-no' id='" + chapid + "' />");
      idcount++;
      var level = 0;
      var chapNo;
      if (this.nodeName.toLowerCase() == "h2") {
        level = 1;
        h2cnt++;
        h3cnt = 0;
        h4cnt = 0;
        chapNo = h2cnt + ".";
      } else if (this.nodeName.toLowerCase() == "h3") {
        level = 2;
        h3cnt++;
        h4cnt = 0;
        chapNo = h2cnt + "-" + h3cnt + ".";
      } else if (this.nodeName.toLowerCase() == "h4") {
        level = 3;
        h4cnt++;
        chapNo = h2cnt + "-" + h3cnt + "-" + h4cnt + ".";
      }
      if (currentlevel == level) {
        toc += "</li><li>";
      }
      while (currentlevel < level) {
        toc += '<ul class="chapter"><li>';
        currentlevel++;
      }
      while (currentlevel > level) {
        toc += "</li></ul><li>";
        currentlevel--;
      }
      toc += '<a href="#' + chapid + '">' + chapNo + $(this).text() + "</a>";
      $(this).html(chapNo + $(this).html());
    });
    while (currentlevel > 0) {
      toc += "</li></ul>";
      currentlevel--;
    }
    if ($(".post-body h2")[0]) {
      $("#toc").html(toc);
    } else {
      $('#toc').attr('class', 'no-toc');
    }
  });
  //]]>
</script>
<style><!--
  /*  目次のデザイン  */
  #toc:before{
    content:"目次";/*目次のタイトル*/
    padding-left:1em;
    font-weight:800;
  }
  #toc{
    background-color:#f9f9f9; /*目次の背景色*/
    padding:1em;
    display:block;
    margin:1em 0;
    border:1px solid #e6e6fa;/*目次の枠線*/
  }
  #toc li{list-style:none;margin-bottom:1em;}
  #toc ul{margin-bottom:0;}
  #toc:before{display:block;text-align:center;}
  .chapter-no{position: relative;top:-2.5em;}
--></style>

テンプレートを保存して動作を確認する

記事ページを表示してPCとSPで動作を確認してください。
PCとスマホで確認する
  1. 目次が生成されていること。
  2. 目次をクリックすると見出しに移動すること。
  3. 見出しに番号が付番されていること。

失敗したらバックアップから復元する

もしもカスタマイズが上手く機能しなかった場合は、バックアップしたxmlファイルからアップロードしましょう。
アップロードは「バックアップ/復元」の下側のボタンから可能です。

うまく動かないんですけど?

見出しどおりに目次が作成されない場合

Bloggerで編集するとタグがずれている場合があります。(見出しを書いて消してを繰り返すとずれる。)
HTML表示にしてタグが間違っていないか確認してみてください。
見出しとタグは以下で対応しています。

  • 見出し:<h2>
  • 小見出し:<h3>
  • 準見出し:<h4>

目次から移動したときに位置がずれる場合

利用しているテンプレートによってずれる場合があります。
カスタマイズソースのCSSを編集して調整してください。
.chapter-no{position:relative;top:-2.5em;}

その他の問題

コメント欄に書き込んでください。

カスタマイズソースの説明

下記はjqueryのロードです。
<script type='text/javascript'>
  //<![CDATA[
  if (typeof(jQuery) == 'undefined') {
    document.write("<scr" + "ipt type=\"text/javascript\" src=\"//ajax.googleapis.com/ajax/libs/jquery/2.1.4/jquery.min.js\"></scr" + "ipt>");
  }
  //]]>
</script>
下記JavaScriptで各見出し(h2~h4)を取り出し、目次の生成と見出しの編集を行っています。
目次の移動先は<div class='chapter-no' id='chapter-#' />で作成しています。
<script type='text/javascript'>
  //<![CDATA[
  $(document).ready(function() {
    console.log("call func");
    $('a[name="more"]').after("<div id='toc' />");
    var idcount = 1;
    var h2cnt = 0;
    var h3cnt = 0;
    var h4cnt = 0;
    var toc = '';
    var currentlevel = 0;
    $(".post-body h2,.post-body h3,.post-body h4", this).each(function() {
      var chapid = "chapter-" + idcount;
      $(this).before("<div class='chapter-no' id='" + chapid + "' />");
      idcount++;
      var level = 0;
      var chapNo;
      if (this.nodeName.toLowerCase() == "h2") {
        level = 1;
        h2cnt++;
        h3cnt = 0;
        h4cnt = 0;
        chapNo = h2cnt + ".";
      } else if (this.nodeName.toLowerCase() == "h3") {
        level = 2;
        h3cnt++;
        h4cnt = 0;
        chapNo = h2cnt + "-" + h3cnt + ".";
      } else if (this.nodeName.toLowerCase() == "h4") {
        level = 3;
        h4cnt++;
        chapNo = h2cnt + "-" + h3cnt + "-" + h4cnt + ".";
      }
      if (currentlevel == level) {
        toc += "</li><li>";
      }
      while (currentlevel < level) {
        toc += '<ul class="chapter"><li>';
        currentlevel++;
      }
      while (currentlevel > level) {
        toc += "</li></ul><li>";
        currentlevel--;
      }
      toc += '<a href="#' + chapid + '">' + chapNo + $(this).text() + "</a>";
      $(this).html(chapNo + $(this).html());
    });
    while (currentlevel > 0) {
      toc += "</li></ul>";
      currentlevel--;
    }
    if ($(".post-body h2")[0]) {
      $("#toc").html(toc);
    } else {
      $('#toc').attr('class', 'no-toc');
    }
  });
  //]]>
</script>
最期が目次のCSSです。見た目や目次のタイトルはこちらで編集できます。
目次の移動先がずれる場合は.chapter-noを調整してください。
<style><!--
  /*  目次のデザイン  */
  #toc:before{
    content:"目次";/*目次のタイトル*/
    padding-left:1em;
    font-weight:800;
  }
  #toc{
    background-color:#f9f9f9; /*目次の背景色*/
    padding:1em;
    display:block;
    margin:1em 0;
    border:1px solid #e6e6fa;/*目次の枠線*/
  }
  #toc li{list-style:none;margin-bottom:1em;}
  #toc ul{margin-bottom:0;}
  #toc:before{display:block;text-align:center;}
  .chapter-no{position: relative;top:-2.5em;}
--></style>

参考記事

目次の作成にあたり、下記サイトを参考にさせていただきました。

This Is The Newest Post