WordPressをMarkdownで執筆、あるいはMarkdown→HTML変換とGitHub Pagesの自動更新

2021年06月22日 火曜日


【この記事を書いた人】
坂口 和也

システムクラウド本部所属。IaaSサービスの画面を作ったりOSイメージをメンテナンスしたりしています。ゲレンデかサウナにいます。

「WordPressをMarkdownで執筆、あるいはMarkdown→HTML変換とGitHub Pagesの自動更新」のイメージ

はじめましての方ははじめまして、2020年のアドベントカレンダーをご覧になってくださった方はお久しぶりです、クラウド本部の坂口です。
私は普段、クラウドサービスのフロントエンド開発からOSイメージのメンテナンス、サービスの運用などをメインに行っています。

2020年12月にアドベントカレンダーで投稿した 我らの時代のコンテナデプロイ – Nomad, Consul, Vault はお楽しみいただけたでしょうか。
実はこの記事を執筆する際、様々な趣向を凝らしていました。今回はそれをご紹介いたします。

MarkdownとWordPress

エンジニアたるもの文章はMarkdownで書き、Gitでバージョン管理したいですよね。

しかしWordPressでMarkdownを利用するには、WordPress5.0のGutenbergエディタを使うかプラグインを導入する必要があります。
Gutenbergエディタは入力したMarkdown記法をリアルタイムでHTMLに変換するものですし、プラグインを選定するのも面倒です。

そこで私は、Markdownで文章を書きGitでバージョン管理しつつもそのコンテンツをWordPressに載せやすい方法を模索しました。
その結果、「Markdownを社内のGitHub Enterpriseにpushすれば、HTMLに変換してGitHub Pagesに掲載される」という方式に至ったのです。

GitHub Pages

GitHubには標準でGitHub Pagesという機能が備わっています。
これは、GitHubの特定のbranchを指定し、HTMLやCSS等のファイルを取得して静的に表示できる機能です。

まずは執筆用のRepositoryにあらかじめgh-pagesブランチを生やしておきましょう。
そしてRepositoryのSettingsから”GitHub Pages”を探し、Sourceに”gh-pages”ブランチを指定します。

これによって、gh-pagesブランチにpushされた静的ファイルをGitHub Pagesに表示することができるようになりました。

Github Pagesの自動更新

pushされたらGitHub Pagesを自動更新したいですよね。

社内で用意されており、GitHub Enterpriseとも連携しているDroneというCI/CDシステムを利用して自動更新を実現します。

まずはGitHubのアカウント設定からGitHub APIのためのアクセストークンを発行しておきます。
Droneと目的のRepositoryを紐付けておき、Droneの秘密情報としてアクセストークンをgithub_passwordなどと名前をつけて格納します。
最後に以下のような内容で.drone.ymlをRepositoryに追加しましょう。

このままpushすれば、Repositoryのdocsディレクトリの中身をgh-pagesブランチに自動でpushしてくれます。

Markdown -> HTML 変換

ここからは目的のMarkdownからHTMLへの変換を行います。

今回は変換ツールとしてpandocを使用します。
pandocは様々なフォーマットに対応する文章変換ツールで、Dockerイメージも存在するのでdroneで指定すればすぐに動かすことができます。

.drone.ymlにこんな風に書いてみました。
push された index.md は pandoc により HTML に変換され、docs/index.html に出力されます。

上の設定でdocsディレクトリ配下は自動的にgh-pagesブランチにpushされるため、Markdownをpushすれば変換してGitHub Pagesで見れるようになりました。

Template編集

このままだと、GitHub Pagesのソースを見て、bodyタグ内をコピーしてWordPressに張り付けないといけません。
ページ下部に、bodyタグを抜き出してコピペをしやすくなるようなtextareaを設けたいと思います。

pandocはtemplateを読み込んでそれに従って変換を行ってくれるので、まずデフォルトのtemplateを出力します、
出力したtemplateはtemplate.htmlとでも名付けておきましょう。

次に、headタグ内に以下のようなscriptを追加します。
textareaタグを作成して、body.innerHTMLをvalueとしてbodyにappendChildするだけの単純なJavaScriptです。

ここまで出来たら、作成したtemplate.htmlと一緒に以下のように編集した.drone.ymlをpushしてしまいましょう。

commands部分を見るとわかる通り、今作ったtemplateを元にMarkdownからHTMLへの変換を行ってくれます。

GitHub Pagesを更新すれば、最下部にbodyタグ内を抜き出したtextareaが追加されると思います。

Lint

ここからは余談ですが、文章のチェックも行ってくれると嬉しいですよね。

textlintという文書校閲ツールを使ってこれを実現してみましょう。

npmでtextlintと、技術文書チェックのプリセットをインストールした上で、index.mdをチェックします。
これにより、以下のようにDrone上で文書チェックを行うことができます。

「branchで書き、Lintのチェックが通らないとMasterにMergeできないようにする」といった応用もできそうですね。

Lint高速化

毎度npm installを書けているとチェックにかかる時間が長くなってしまいます。

今回は、npm installの成果物であるnode_modulesをキャッシュしてしまいましょう。
社内にはS3互換ストレージがあるので、マウントしてnpm_modulesをまるごと置いてしまいます。

こんな風に.drone.ymlを書くことで、初回npm install完了後はnode_modulesをキャッシュ、再度npm installする場合は手元にnode_modulesが存在するためインストール時間がとても短くなります。

完成

無事、以下の要件を満たすことができました。

  • Markdownで執筆
  • Gitでバージョンを管理
  • pushしたらMarkdownを校閲、HTMLに変換
  • 変換したHTMLをGitHub Pagesに自動公開
  • 公開されたページ下部にソースを表示

あとは、textareaに表示されているHTMLをWordPress標準エディタのHTML編集モードで貼り付けるだけです。

まとめ

今回はバージョン管理にGitHub、HTMLへの変換はpandoc、CI/CDはDroneを利用し、Markdownによる技術文書執筆環境を整えてみました。

同じような境遇の方がいらっしゃいましたら、是非お試しください。

坂口 和也

2021年06月22日 火曜日

システムクラウド本部所属。IaaSサービスの画面を作ったりOSイメージをメンテナンスしたりしています。ゲレンデかサウナにいます。

Related
関連記事