Cocoonの目次機能はDOMパーサーを使っていないので高速に動作するのでお気に入りです。PHPで動作するので、Snowmonkeyの目次ブロックのようなCLSの問題もありません。
Cocoonの目次機能にはキーワードで特定の見出しを除外する機能がありません。
フォーラムで以前、要望があったようですが、まろやかに却下されていました。
目次のカスタマイズがしたいです hタグに設定された特定のクラスを目次から除外するような設定はできないでしょうか?
機能としては、そういった設定はないです。
そのような設定を追加するには、get_toc_tag関数をオーバーライドして、カスタマイズするか
https://github.com/yhira/cocoon/blob/de085a9b41b5eed5d9aba2addb452f8b1c22758f/lib/toc.php#L35‘get_toc_tag’をフックして、該当箇所のタグを除外するしか方法はないかもしれません。
https://wp-cocoon.com/community/demands/h%E3%82%BF%E3%82%B0%E3%81%AB%E8%A8%AD%E5%AE%9A%E3%81%95%E3%82%8C%E3%81%9F%E7%89%B9%E5%AE%9A%E3%81%AE%E3%82%AF%E3%83%A9%E3%82%B9%E3%82%92%E7%9B%AE%E6%AC%A1%E3%81%8B%E3%82%89%E9%99%A4%E5%A4%96%E3%81%99/
https://github.com/yhira/cocoon/blob/de085a9b41b5eed5d9aba2addb452f8b1c22758f/lib/toc.php#L189
もしくは、JavaScriptで動的に除外するか。
この記事では、Cocoonの目次にclass指定で見出しを除外するカスタマイズについてご説明いたします。
Cocoonの目次から指定のclassを含む見出しを除外するカスタマイズ
yhiraさんのコメントだと3つのやり方があるとのこと
- ①get_toc_tag関数をオーバーライドしてカスタマイズ
- ②’get_toc_tag’をフックして、該当箇所のタグを除外
- ③JavaScriptで動的に除外
目次部分のHTMLにはclassが含まれていないので、②や③で判断して除外するのは無理。
変更をすくなくするには、①以外は厳しそうだったので、①で検討することにしました。
get_toc_tag関数をオーバーライドしてカスタマイズ
この方法は、親テーマの関数を子テーマにコピーして書き換えるので本来ならあまりやりたくはないですが、背に腹は代えられません。
最小限の変更で済ませられないか検討した結果、目次部分のHTMLを生成する部分を条件指定して除外するだけで、目次から特定の見出しを除外できることがわかりました。
#https://github.com/yhira/cocoon/blob/de085a9b41b5eed5d9aba2addb452f8b1c22758f/lib/toc.php#L137
除外するclassを指定
class指定を配列で外部から指定できるようにフックを追加します。
変更前
if($header_count > 0){
$toc_list .= '<' . $list_tag . (($current_depth == $top_level - 1) ? ' class="toc-list open"' : '') . '>';
}
for($i=0;$i < $header_count;$i++){
変更後
if($header_count > 0){
$toc_list .= '<' . $list_tag . (($current_depth == $top_level - 1) ? ' class="toc-list open"' : '') . '>';
}
// 除外リストの処理追加 ここから
$exclude_list = [];
$exclude_list = apply_filters( 'toc_exclude_array', $exclude_list );
// 除外リストの処理追加 ここまで
for($i=0;$i < $header_count;$i++){
除外するclassを含む場合は目次から除外
見出しにclassが含まれているか判定して、classがあれば出力しません。
それだけです。
本文側は特に除外の処理はしません。
変更前
$toc_list .= '<li><a href="#toc' . $counter . '" tabindex="0">' . strip_tags($headers[2][$i]) . '</a>';
変更後
if( str_ireplace( $exclude_list, '', $headers[0][$i] ) === $headers[0][$i] ){
$toc_list .= '<li><a href="#toc' . $counter . '" tabindex="0">' . strip_tags($headers[2][$i]) . '</a>';
}
カスタマイズの手順
①子テーマのfunctions.phpにget_toc_tag関数をコピペ
#https://github.com/yhira/cocoon/blob/de085a9b41b5eed5d9aba2addb452f8b1c22758f/lib/toc.php#L33
②除外するclassを指定を追加
#https://github.com/yhira/cocoon/blob/de085a9b41b5eed5d9aba2addb452f8b1c22758f/lib/toc.php#L94
の手前に、【除外するclassを指定】を追加
③除外するclassを含む場合は目次から除外
#https://github.com/yhira/cocoon/blob/de085a9b41b5eed5d9aba2addb452f8b1c22758f/lib/toc.php#L137
を【除外するclassを含む場合は目次から除外】のif文で囲む
④除外するclassを指定する
除外するclassを配列で指定する
add_filter('toc_exclude_array', function(){
return array(
'c-entry-summary__title',
'ez-toc-exclude-headings',
);
});
まとめ
Cocoonの目次から、class指定で見出しを除外するカスタマイズの手順を説明しました。
通常のブログでは、見出しを除外したいことは殆どないと思いますが、コンテンツを自動で生成している場合などは不要な見出しはclassで除外したいこともあると思います。
今回のカスタマイズは、オーバーライドするカスタマイズなので、親テーマのバージョン管理が大変になるのが難点です。
少ない修正なので、Cocoon本体で取り込んでもらえるとありがたいです。