最近ノリにのっているヘッドレスCMS。 現状、様々なサービスが提供されていますが、中でもContentfulでのブログ記事管理を行なっている方も多いのではないでしょうか。 実際、当ブログもContentfulでブログの記事を管理し、Gatsbyでフロント側を実装しています。
けれども、実際ContentfulをヘッドレスCMSに採用したところ、リッチテキストのフロントでの適用難易度がかなり高かったり、マークダウン、リッチテキストの両方とも、コードブロックのデフォルトデザインがほぼあってないようなくらいに洗練されていないことにストレスを覚えたのは私だけではないはずです。。
そこで本記事では、contentfulのリッチテキスト、マークダウンテキストの両方でのコードブロックデザインのカスタマイズ方法について解説していこうと思います。
※はじめに述べておきますが、Contentfulでのブログ記事にはマークダウンの利用を強くお勧めします。理由は2点あり、まずはじめに、マークダウン記法にくらべ、導入難易度がかなり高いことです。というのも、contentfulのリッチテキストの仕様はかなり使い勝手が悪く、通常のフローでは必ずといっていいほどぶつかる壁が出てきます(参照)。こちらは書き出すと分量が多くなるので、また別の機会に記事にまとめさせていただこうと思います。もう一点はソースコードの記入を行う際のリッチテキストの貧弱さです。contentfulのリッチテキストでは、コードブロックは、html上でcodeブロックに内包してくれるのみで、qiitaやzennなどで適用されるようなコードシンタックスがデフォルトでは適用されません。またなにより、コードをリッチテキストの入力フォームにコピペする際、インデックスのフォーマットが自動で取り除かれるため、コピペ後、手動でコードのインデックスをと整えなければいけなく、非常に使い勝手が悪いです。また、文字の色の変更も整備されておらず、表なども組むことができません。上記などの理由から、管理コスト、導入コストの観点から、私はマークダウンの利用を強く勧めます。
リッチテキストでのコードシンタックスの適用
react-syntax-highlighterをインストール
yarn add react-syntax-highlighter # yarnでのインストール
npm install react-syntax-highlighter # npmでのインストール
blog記事を表示しているtemplateファイルの編集
- MARKSの定義
import { BLOCKS, MARKS } from "@contentful/rich-text-types"
- react-syntax-highlighterのimport + シンタックスハイライトスタイルの指定
import { Prism as SyntaxHighlighter } from "react-syntax-highlighter";
import { okaidia } from "react-syntax-highlighter/dist/cjs/styles/prism"; # ここではokaidiaを選択
- コードブロックをdivタグで囲われるよう設定を変更し、シンタックスハイライトのスタイルを適用する関数を作成する。
const options = {
renderNode: {
[BLOCKS.PARAGRAPH]: (node, children) => {
if (node.content.length === 1 && node.content[0].marks.find(x => x.type === 'code')) {
return <div>{children}</div>;
}
return <p>{children}</p>;
},
},
renderMark: {
[MARKS.CODE]: text => (
<SyntaxHighlighter language="javascript" style={okaidia} showLineNumbers>
{text}
</SyntaxHighlighter>
),
},
};
// コードブロックのシンタックスハイライト
function code(text) {
text.shift(); //不必要な部分を取り除く
const language = text.shift(); //言語指定部分の削除
text.shift(); ////不必要な部分を取り除く
const value = text.reduce((acc, cur) => {
if (typeof cur !== "string" && cur.type === "br") {
return acc + "\n";
}
return acc + cur;
}, "");
return (
<SyntaxHighlighter language={language} style={okaidia}>
{value}
</SyntaxHighlighter>
);
}
使用方法
以下のように、リッチテキストのcodeブロック一行目に使用する言語を明記する。 ※使用言語の箇所が上記で作成した関数内で取り除くため、実際に表示されることはありません。
javascript:title=test.js console.log(“test)
マークダウンでのコードシンタックスの適用
必要プラグイン(gatsby-transformer-remark, gatsby-remark-prismjs, prismjs, gatsby-remark-prismjs-title)のインストール
# yarnでのインストール
yarn add gatsby-transformer-remark gatsby-remark-prismjs prismjs
yarn add gatsby-remark-prismjs-title
# npmでのインストール
npm install gatsby-transformer-remark gatsby-remark-prismjs prismjs
npm install gatsby-remark-prismjs-title
configへの追記
plugins: [
(中略)
{
resolve: `gatsby-transformer-remark`,
options: {
plugins: [
`gatsby-remark-code-titles`, //ファイルのタイトルを表示
{
resolve: `gatsby-remark-prismjs`,
options: {
classPrefix: "language-",
inlineCodeMarker: null,
aliases: {},
showLineNumbers: false, //行数を出したい場合trueに。
noInlineHighlight: false,
},
},
],
},
}
]
Prismから適用するスタイルのCSSをダウンロード
- 以下のURLから適用したいスタイルを選択し、CSSファイル(prism.css)をダウンロードし、
/src/styles/prismjs
直下に配置する。
https://prismjs.com/
- コードのタイトルタブを表示できるようCSSファイルを作成する。
/src/styles/prismjs
直下にinit.cssを作成し以下の内容をコピペ。
.gatsby-code-title {
background: #0b293f; #好きな色を指定
color: #fff;
margin-bottom: -0em;
padding: 1rem 1rem;
font-size: 1em;
line-height: 0.2;
font-weight: 600;
border-radius: 8px 8px 0 0;
display: table;
position: relative;
top: 10px;
}
スタイルシートの読み込み
gatsby-browser.jsから、上記で作成したCSSファイルを読み込ませる。
import "./src/styles/prismjs/init.css"
import "./src/styles/prismjs/prism.css"
以上でコードシンタックスの適用ができたかと思います。 冒頭でも触れましたが、技術ブログをcontentfulで管理するのは非常に不向きだと思いますので、できるかぎりマークダウンでかけるようにするとよいと思います! 他の技術ブログプラットフォームにもスケールしやすいと思うのでお勧めです!