【コピペでできる】WordPress プラグインなしで目次を作成する方法

こんにちは。
今回はプラグインを使わずにワードプレスの目次を自動生成するプログラムを作りましたので、シェアできればと思います。
コピペでOKです!

今回作った目次プログラムを使ったサンプルページがこちらです。
目次をクリックするとその部分まで飛びます。

サイトを作るにあたって、目次をつけたいと思いました。
でも、プラグインは負荷がかかったら嫌なので極力使いたくないですし、自分でコーディングするのはめんどくさい(←おい)

なのでこのサイトで紹介しているプログラムを使わせていただこうと思いました。
結構いろんなサイトでもこのサイトのプログラムを紹介していましたし、結構よさそうです。
(非常に参考になりました。ありがとうございます。)

ですが、参考にさせていただいたプログラムが自分の理想的な操作でなかったため、修正しました。

作成したプログラムの特徴

  • 目次を自動的に生成し、クリックすると見出しまでスクロール
  • 見出しにリンクを貼っていても問題なし
  • URLに「#」を表示しない
  • h2からh6まで対応(階層表示)

参考にしたプログラムからの変更点

とりあえずサイトで紹介されていたプログラムをそのままこのサイトに使ってみました。
こんな感じでHTMLを作成して、

<h2>主なライセンスの内容と実用例</h2>
<h3 class="entry_pickup_title"><a href="http://www.gnu.org/licenses/gpl.html">GPL(GNU General Public License)</a>

表示してみます。

おわかりでしょうか?

<h2><h3>を使っているのに、同じ列になってしまっています。
コードを見てみると、こんな感じで<ul>が<ul>を子に持っています
(わかりやすくなるように内容は変えてます)。↓

<ul>
<li>1</li>
<ul>
<li>1.1</li>
<li>1.2</li>
</ul>
</ul>

これって実はHTMLの正しい使い方ではないんですよね。
(これでも問題なく動いてしまうのが問題なのですがw)
正しくはこういう感じです↓
(入れ子にするなら<li></li>の中に<ul>を記述していく)

<ul>
<li>1
<ul>
<li>1.1</li>
<li>1.2</li>
</ul>
</li>
</ul>

このように正しいタグの使い方に修正します。

また、<h2>タグなどにリンクを貼っていた場合、そのリンクが目次にも作用してしまって、目次を押すとリンクページに行ってしまいます。
(こちらは問題点というより、作者が<h2>などにリンクを貼る気がなかっただけでしょうけど)

こちらも直しました。

作成したプログラムと使い方

まずは下のコードをお使いのテーマに組み込みます。テーマを編集する際には子テーマを作ってそちらに編集したファイルを置くのがよいでしょう。

2017/12/27 追記
ワードプレスでは特殊な事情がない限りwp_head()によってjqueryがすでに読み込まれています。
もう一度読み込むとエラーになるので、
<script src=”//ajax.googleapis.com/ajax/libs/jquery/2.0.3/jquery.min.js”></script>
の記述を削除しました。

<style type="text/css">
#toc {
margin: 0 auto;
width: 100%;
background: #ffffff;
}
.mokuji_wrap {
border: 2px solid #888;
border-radius: 4px;
padding: 2% 2%;
}
.mokuji {
color: #888;
text-align: center;
}
#toc ul {
margin:0;	//テーマデフォルトのmarginをリセット
list-style-type: disc;	//はみ出し対策
font-size: 100%;
}
#toc li {
margin-left: 1em;	//はみ出し対策
line-height: 1.2;
}
</style>
<script type="text/javascript">
$(function() {
var idcount = 1;
var toc='';
var ht_arr = [];
var a_arr = [];
$(".entry-content :header",this).each(function(){
this.id = "toc_" + idcount;
idcount++;
if(this.nodeName.toLowerCase() == "h2") {
ht_arr.push(2);
} else if(this.nodeName.toLowerCase() == "h3") {
ht_arr.push(3);
} else if(this.nodeName.toLowerCase() == "h4") {
ht_arr.push(4);
} else if(this.nodeName.toLowerCase() == "h5") {
ht_arr.push(5);
} else if(this.nodeName.toLowerCase() == "h6") {
ht_arr.push(6);
}
var a = '<a href="#' + this.id + '">' + $(this).text() + "<\/a>";
a_arr.push(a);
});
toc += '<ul>';
for(var i=0; i+1<ht_arr.length; ++i){
if(ht_arr[i] == ht_arr[i+1]){
toc += '<li>'+ a_arr[i] + '</li>';
}
else if(ht_arr[i] < ht_arr[i+1]){
toc += '<li>'+ a_arr[i] + '<ul>';
}
else if(ht_arr[i] > ht_arr[i+1]){
toc += '<li>'+ a_arr[i] + '</li>';
var ulli_num = ht_arr[i]-ht_arr[i+1];
for(var j=0; j<ulli_num; ++j){
toc += '</ul></li>';
}
}
}
//最後の1つと</ul></li>の数合わせ
toc += '<li>'+ a_arr[ht_arr.length-1] + '</li>';
var ulli_num = ht_arr[ht_arr.length-1]-2;
for(var j=0; j<ulli_num; ++j){
toc += '</ul></li>';
}
toc += '</ul>';
if(toc){ toc = '<div class="mokuji_wrap"><div class="mokuji">【目次】</div>' + toc + '</div>'; }
$("#toc").html(toc);
//ページ内リンク#非表示。加速スクロール
$('a[href^=#]').click(function(){
var	speed = 400,
href= $(this).attr("href"),
target = $(href == "#" || href == "" ? 'html' : href),
position = target.offset().top;
$("html, body").animate({scrollTop:position}, speed, "swing");
return false;
});
});
</script>

僕が変更したところがきれいなコードじゃなくてすいません(;^_^A
javascriptを最初に読み込むとサイトのも見込みが遅くなるので、「footer.php」の</body>直前に入れるのがいいでしょう。

<?php
/*
* footer.php
*/
?>
<!-- ~省略~ -->
<!-- ここに先ほどのソースコードを挿入 -->
</body>
</html>

cssなどのレイアウトは自分のサイトに合うように変えてください。
「はみ出し対策」とコメントしているところですが、目次の点がはみ出すのを防止しています。(参考

目次を表示する部分に以下のコードを張り付けると目次が表示されます。

<div id="toc"></div>

ただ、毎回上のコードを張り付けるのはめんどくさいという人もいるでしょう。
そんな人はショートコードにしてしまえばいいと思います。

ショートコードを追加するにはfunction.phpに次のようなコードを追加します。
(function.phpを間違った編集をしてしまうとワードプレス全体の表示が真っ白になってしまうので、十分に調べたうえで、かつ慎重に編集してください。自信がなければ控えたほうがいいと思います。ちなみに失敗したらFTPからファイルを修正します。)

/*toc*/
/*js and css in footer.php*/
function toc_func(){
ob_start();
?>
<div id="toc"></div>
<?php
return ob_get_clean();
}
add_shortcode("toc","toc_func");

すると、ビジュアルエディタで目次を表示したい場所に

と入力するだけで、目次が生成されます。
以上になります。それでは良いWordpress日和を(*^-^*)

あわせて読みたい