こんにちは、柴田です。
「目次って作れますか?」というお問い合わせをちょくちょくいただくので、作ってみた系の記事を書いてみたいと思います。
本microCMSブログにもいつの間にかに目次が付いたのに気付きましたか?
地味にちょっとずつ改良を続けております。
目次の作り方
一般的に、目次は記事の本文から見出しを抜き出して作成します。
よって、microCMSにおいてはリッチエディタで作成したHTMLを構文解析し、見出しタグを抜き出せばOKです。
具体的にどうやるのか見ていきましょう。
const $ = cheerio.load(body);
const headings = $('h1, h2, h3').toArray();
const toc = headings.map(data => ({
text: data.children[0].data,
id: data.attribs.id,
name: data.name
}));
cheerioというHTMLパーサーを利用して、h1〜h3を抜き出します。
配列形式で取得できるので、整形してテキスト・ID・タグ名の配列に書き換えます。
ちなみにtocはTableOfContentsの略です。
こんな形で取得できます。
[
{ text: '目次の作り方', id: 'hkY7o3DlYB2', name: 'h1' },
{ text: '目次機能のオンオフ', id: 'h4AL9B4qAV6', name: 'h2' },
{ text: 'おわりに', id: 'hBwwL6rm8B7', name: 'h1' }
]
ご覧の通り、microCMSでは各見出しタグにidが振られています。
よって、この配列から作成した目次から各見出しタグに対してアンカーリンクを張ってあげればOKです。
一応参考までに、テンプレート側の実装の例も置いておきます。(Nuxtで作成しています)
<ul class="lists">
<li :class="`list ${item.name}`" v-for="item in toc" :key="item.id">
<n-link v-scroll-to="`#${item.id}`" to>
{{ item.text }}
</n-link>
</li>
</ul>
見出しが深くなるほどインデントをつけたいので、liタグにh1〜h3などのタグ情報をclassとして渡して、CSSで装飾しています。
また、リンクをクリックするとスムーズにスクロールされるように、vue-scroll-toというライブラリを使用しています。
目次機能のオンオフ
目次を実装してみたのは良いけど、目次を表示するほどでもないなぁという記事もありますよね。
そんな時のために簡単に目次機能をオン/オフできる機能を用意しましょう。
API設定 > APIスキーマから以下のようにBooleanフィールドを用意します。
また、右の設定アイコンをクリックして、良い感じな説明文を入力しておきましょう。
そうすると、入力フォームにこんな感じのスイッチが出来上がります。
このBoolean値は同様に記事APIから取得できるので、この値を見て表示するかどうかを出し分けてあげればOKです。
おわりに
今回はmicroCMSを使って目次を作成しました。
APIから受け取ったデータはクライアントサイドでいくらでも加工できるので、良い感じの使い方を見つけてみてください。
-----
microCMSは日々改善を進めています。
ご意見・ご要望は管理画面右下のチャット、公式Twitter、メールからお気軽にご連絡ください!
引き続きmicroCMSをよろしくお願いいたします