はじめに
これまで大きなZendeskカスタマイズの受託を2件ほど経験してきました。あまりZendeskのカスタマイズについて、個別具体的に解説している記事がないので、我流のカスタマイズで恐縮ですがここに残したいと思います。
「Zendeskとは?」 という方へ
私自身ZendeskのGuide機能しか取り扱っていないのですが、ざっくり説明すると「企業のヘルプセンターがノーコード(カスタマイズ等を実施する場合はローコード) で構築できるよ!」というSaaSです。もっと詳しく知りたい方はこちらを読んでみてください。
Zendeskで目次機能を実装する
最終的に目指している状態
記事内の任意の場所に<Toc/>
と記述することで、記事内のヘッダー要素を取得して下記のような目次を作成する。(前提としてjQueryを使用しています。)変数名の前に「$」を付けることで、その変数がjQueryオブジェクトを格納していることを明示しています。
記事の状態
記事内の任意の場所に<Toc/>
と記述してみた
記事のソースコードのようす
画面描写の様子
実際のソースコード解説
記事中の<Toc/>
を取得して、HTMLタグに変換する
<Toc/>
のままだと何も変換されないので、まずHTMLタグに変換します。
$('p:contains("<Toc/>")').replaceWith('<div id="toc"></div>');
.article-body
中のヘッダー要素を取得する
h6
タグくらいまでのヘッダー要素を取得します。
var $headers = $('.article-body').find('h1, h2, h3, h4, h5, h6');
目次のベースとなるリスト要素を準備する
ヘッダー要素が複数確認できた場合にベースのHTML要素を設置します。
これらの処理は$(document).ready(function () {})
内に設置します。
if ($headers.length > 1) {
var $toc = $('<div class="toc">');
var $firstUl = $('<ul>');
var $currentUl = $firstUl;
var previous_level = 1;
$firstUl.appendTo($toc);
$('#toc').append($toc);
insertHeadings($headers);
}
ヘッダー要素を繰り返しチェックしてネストさせていく
insertHeadings
ではヘッダー要素をネストさせています。
function insertHeadings(headers) {
headers.each(function(index, heading) {
var $heading = $(heading);
var current_level = headingLevel(heading);
if (current_level === 1) {
newLi($heading, $firstUl);
$currentUl = $firstUl;
} else if (current_level === previous_level) {
newLi($heading, $currentUl);
} else if (current_level > previous_level) {
nestUl();
newLi($heading, $currentUl);
} else {
while (current_level < previous_level) {
$currentUl = $currentUl.parent().closest('ul');
previous_level--;
}
newLi($heading, $currentUl);
}
previous_level = current_level;
});
}
nestUl
では追加のul
タグを設置しています。
function nestUl() {
var $newUl = $('<ul>');
$newUl.appendTo($currentUl);
$currentUl = $newUl;
}
headingLevel
ではヘッダーに対応する番号をリターンしています。
function headingLevel(heading) {
switch (heading.nodeName) {
case 'H1':
return 1;
case 'H2':
return 2;
case 'H3':
return 3;
case 'H4':
return 4;
case 'H5':
return 5;
case 'H6':
return 6;
case 'H7':
return 7;
case 'H8':
return 8;
case 'H9':
return 9;
case 'H10':
return 10;
default:
return 0;
}
}
newLi
では渡された要素をli
要素として設置しています。
function newLi(heading, $list) {
var $heading = $(heading);
var $wrapper = $('<li></li>');
var $link = $('<a>').prop('href', '#' + $heading.prop('id'));
$link.html($heading.text());
$link.appendTo($wrapper);
$wrapper.appendTo($list);
}
おわりに
当初は「どうやって実装するんだよ」状態だったんですが、ゴリゴリ実装してみると意外と実現できたので嬉しかったです。このカスタマイズに対して、もっとこうしたほうがいいとかアドバイスがあればよろしくお願いします!
ここまで読んでいただきありがとうございました。