PrismicのPreformattedTextの内容をシンタックスハイライト表示 Part.2

  • NuxtJS
  • Prismic

はじめに

前の記事の続編という形で紹介させていただきます。

前回はhighlight.jsで自動で言語検出してシンタックスハイライト表示させる内容でした。今回は投稿画面から言語を指定できるようにする方法について考えてみたので紹介します。

今回も下記のプロジェクトのコードを元に試します。

👉 https://github.com/nemuvski/nuxtjs-prismic-starter

このプロジェクトについての記事は下記のものです。

📖 【Nuxt.js + Prismic.io】第3回 簡単なサイトを作ってみよう

余談

Prism.jsはシンタックスハイライト表示させる時に言語指定しなければならないので、今回紹介する方法は有効です。記事ではhighlight.jsで紹介しますが、同じような感じで可能です。

Slices機能の利用

PrismicにSlicesという機能があります。とても便利な機能で、Prismicを推す機能の1つと言っても良いと思います。この機能によってページコンテンツの要素の並び替えや挿入操作が容易になったり、コンテンツのレイアウトの自由度が上がります。本サイトではこの機能を大いに活用しています。👍

この機能を用いて、本文部分をPreformatted TextRich Textのスライスで記述できるようにします。(Pic.1-1を参照)

Preformatted Textスライスは次のフィールドを持ちます。

  • 言語のセレクタフィールド
  • Preformatted入力だけを許可したリッチテキストフィールド

言語のセレクタフィールドには選択肢を設定することができるので、任意の言語名を入力します。例としてjavascript, css, htmlを入れておきます。(Pic.1-2を参照)

Pic.1-3に上記の設定をしたカスタムタイプの記事投稿画面を示します。任意の言語を選択をしてテキストエリアにソースコード等を記述する感じです。

https://github.com/nemuvski/nuxtjs-prismic-starter/tree/demo/slices-preformatted-textcustom_types/page.jsonの内容をカスタムタイプの設定画面にてJSONを貼り付ければ確認できます。Slices機能のあたりは使ってみないとイメージ掴み難いと思いますのでぜひ。

実装

記事詳細ページのvueファイルでhighlight.jsとカラーCSSの読み込み、シンタックスハイライト表示させる要素の指定等をします。

本文部分の内容(Slices)は配列で取得できるので、v-forでスライスの要素を1つずつ取り出し、v-ifでスライスタイプごとに表示する内容切り替えます。

注目していただきたいのは、Preformatted Textスライスの時の箇所です。

<template>
  <div class="js-body">
    <div v-for="(slice, idx) in slices" :key="`slice-${idx}`">
      <!-- スライス: Rich Text -->
      <template v-if="slice.slice_type == 'rich_text'">
        <prismic-rich-text :field="slice.primary.text" />
      </template>
      <!-- スライス: Preformatted Text -->
      <template v-else-if="slice.slice_type == 'preformatted_text'">
        <pre>
          <!--
            言語選択フィールドの内容(言語名)をcode要素のクラスに設定することで
            highlight.jsが指定された言語のシンタックスハイライトをすることができます。
           -->
          <code :class="`${slice.primary.lang}`">{{ $prismic.asText(slice.primary.text) }}</code>
        </pre>
      </template>
    </div>
  </div>
</template>

<script>
import hljs from 'highlight.js'
import 'highlight.js/styles/railscasts.css'

// 重要部分のみ抜粋
export default {
  async asyncData({ $prismic, params, error }) {
    try {
      const content = await $prismic.api.getByUID('page', params.uid)
      return {
        slices: content.data.body,
      }
    } catch(e) {
      error({ statusCode: 404 })
    }
  },
  mounted() {
    const preformattedNodeList = this.$el.querySelectorAll('.js-body pre code')
    for (let i = 0; i < preformattedNodeList.length; i++) {
      hljs.highlightBlock(preformattedNodeList[i])
    }
  },
}
</script>

実際に動かして、記事中のソースコードがハイライト表示されていることが確認できました。🙌

Pic.1-3の内容をページで見るとPic.2-1のように表示されます。

さいごに

Prismic + Nuxt.jsで言語指定してシンタックスハイライト表示させる方法について紹介させていただきました。

今回の方法は自己流なので、他にスマートなアプローチがあるかもしれません。調べても見当たらなかったので今回は自分で考えてみました。

今回の内容は以下のリポジトリにコミットしてありますのでご覧ください。

https://github.com/nemuvski/nuxtjs-prismic-starter/tree/demo/slices-preformatted-text

この記事を共有

アバター

K.Utsunomiya
男・20代
主にWebフロントエンド技術と気になった音楽について投稿していきます。
最近ハマっていることは、クロスバイクで走ることとジムでの運動です。
詳しいプロフィール

© 2020–2021 コレ棚