Ryota Kondo

Ryota Kondo

2023/01/16

microCMS|プログラミング言語を指定してシンタックスハイライトを行う方法

microCMSを使ってソースコードのシンタックスハイライトをする場合、公式ブログ「サーバサイドでシンタックスハイライトを行う | microCMSブログ」でも紹介されているとおり、highlight.jsを使って実装する方法があります。

このブログの中ではhighlight.jsのhighlightAuto()という関数を使って、自動でどのプログラミング言語なのかを判定していい感じにシンタックスハイライトをしているのですが、コードの一部のみ抜粋した場合や1行のコードの場合は自動判定がうまくいかず、配色がおかしくなるということがありました。

ですので今回はプログラミング言語を自動判定させるのではなく、指定する方法について説明します。

なお、一つのフィールド中で指定する言語の切り替えが可能であることも考慮に入れた方法となっています。

【2023/06/05追記】
当記事は2023/05/24にリリースされた新リッチエディタではなく、旧リッチエディタを対象としています。新リッチエディタを利用される場合は、こちらの記事「microCMS|新リッチエディタでシンタックスハイライトとファイル名表示をする方法」を参照してください。

microCMSの設定

まずはmicroCMS側の設定についてです。現状ではmicroCMSのリッチエディタのコードブロックに言語指定することはできませんので、カスタムフィールドを使う形となります。

カスタムフィールドの登録

下のようにセレクトフィールド(必須項目 ON)とリッチエディタを持つカスタムフィールドを登録してください。

custom feald

セレクトフィールドにてプログラミング言語を指定し、指定した言語のシンタックスハイライトをリッチエディタのコードブロックに適用するという形になります。

シンタックスハイライトを行う言語をセレクトフィールドの選択肢に設定してください。設定値についてはhighlight.jsのSupported LanguagesにあるAliasesから選択してください。

コンテンツ(API)の設定

次にシンタックスハイライトを行うコンテンツ(API)のAPI設定を行います。

API設定の中からAPIスキーマを選択し、繰り返しフィールドを追加してください。繰り返す項目については先ほど登録したカスタムフィールドを設定してください。

api schema

一つのフィールド中で指定する言語の切り替えをするために繰り返しフィールドを使用しています。

言語の切り替えが不要な場合は、APIスキーマに登録したカスタムフィールドを設定することでも実現可能ですが、後々の拡張性を考えると繰り返しフィールドにしておくことをおすすめします。

理由については以前まとめたブログ「microCMS|ブログの記事本文にはリッチエディタではなく、繰り返しフィールドをおすすめする理由」を参照ください。

サーバサイドの実装

例としてNext.jsを使って説明します。

microCMSから取得したコンテンツからセレクトフィールドの設定値を取り出し、リッチエディタのコードブロックに指定する言語として、highlight.jsのhighlight()という関数に渡します。

コンテンツを格納するtypeは下の通りとして話を進めます。

export type Content = {
  fieldId: "rich_editor";
  // richeditor
  pg_language: string[];
  rich_text: string;
};

export type Blog = {
  id: string;
  createdAt: string;
  updatedAt: string;
  publishedAt: string;
  revisedAt: string;
  article_body: Content[];
};

getStaticPropsの処理

ビルド時に呼ばれるgetStaticPropsに、下のようにシンタックスハイライトを行う処理を追加します。

export const getStaticProps = async (context: any) => {
  const id = context.params.id;
  const data = await client.get({ endpoint: "blogs", contentId: id });

  // ---- 追加する処理 ここから ----
  for (let i = 0; i < data.article_body.length; i++) {
    const body = data.article_body[i];

    // fieldIdの種類によって処理を分ける
    if (body.fieldId == "rich_editor") {
      // Rich Editorの場合は、シンタックスハイライトのためのクラスを付与
      const $ = load(body.rich_text);
      $("pre code").each((_, elm) => {
        const result = hljs.highlight($(elm).text(), {
          // ハイライトするプログラミング言語を指定
          language: body.pg_language[0],
        });
        $(elm).html(result.value);
        $(elm).addClass("hljs");
      });
      data.article_body[i].rich_text = $.html();
    }
  }
  // ---- 追加する処理 ここまで ----

  return {
    props: {
      blog: data,
    },
  };
};

export default functionの処理

繰り返しフィールドに対応するよう、下のように処理を記載します。

export default function BlogId({ blog }: Props) {
  return (
    <div>
      {blog.article_body?.map((content) => (
        <div key={content.fieldId}>
          {content.fieldId === "rich_editor" ? (
            <div
              dangerouslySetInnerHTML={{
                __html: `${content.rich_text}`,
              }}
            />
          ) : null}
        </div>
      ))}
    </div>
  );
}

以上で実装は完了です。

microCMSでの編集イメージ

編集を行う際には下のようなイメージになります。セレクトフィールドでシンタックスハイライトを行う言語を指定して、リッチエディタのコードブロックにソースコードを記載してください。

edit screen

おわりに

プログラミング言語を指定してシンタックスハイライトを行う方法について説明しました。

繰り返しフィールドやカスタムフィールドを使用するため処理が複雑になりますが、必要なケースもあると思いますので参考となれば幸いです。

関連タグの記事

Ryota Kondo
Ryota Kondo

システムエンジニア・プログラマー|このブログサイトの運営もしており、思いついたことをまとめて記事を書いています💡