WordPressをMarkdownで執筆、あるいはMarkdown→HTML変換とGitHub Pagesの自動更新
2021年06月22日 火曜日
CONTENTS
はじめましての方ははじめまして、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に追加しましょう。
pipeline: deploy: image: plugins/gh-pages environment: - DRONE_NETRC_MACHINE={GitHub Enterpriseのドメイン名} secrets: [ github_password ] username: "user"
このままpushすれば、Repositoryのdocsディレクトリの中身をgh-pagesブランチに自動でpushしてくれます。
Markdown -> HTML 変換
ここからは目的のMarkdownからHTMLへの変換を行います。
今回は変換ツールとしてpandocを使用します。
pandocは様々なフォーマットに対応する文章変換ツールで、Dockerイメージも存在するのでdroneで指定すればすぐに動かすことができます。
pipeline: build: image: pandoc/core commands: - 'pandoc -s index.md -o docs/index.html
.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です。
<script type="text/javascript"> window.onload = onLoad; function onLoad() { var element = document.createElement("textarea"); element.value = document.body.innerHTML; element.style.width = '100%'; element.style.height = '30em'; document.body.appendChild(element); } </script>
ここまで出来たら、作成したtemplate.htmlと一緒に以下のように編集した.drone.ymlをpushしてしまいましょう。
pipeline: build: image: pandoc/core commands: - 'pandoc -s index.md -o docs/index.html --template template.html'
commands部分を見るとわかる通り、今作ったtemplateを元にMarkdownからHTMLへの変換を行ってくれます。
GitHub Pagesを更新すれば、最下部にbodyタグ内を抜き出したtextareaが追加されると思います。
Lint
ここからは余談ですが、文章のチェックも行ってくれると嬉しいですよね。
textlintという文書校閲ツールを使ってこれを実現してみましょう。
pipeline: lint: image: node commands: - npm install textlint - npm install textlint-rule-preset-ja-technical-writing - $(npm bin)/textlint --format pretty-error --preset ja-technical-writing index.md
npmでtextlintと、技術文書チェックのプリセットをインストールした上で、index.mdをチェックします。
これにより、以下のようにDrone上で文書チェックを行うことができます。
「branchで書き、Lintのチェックが通らないとMasterにMergeできないようにする」といった応用もできそうですね。
Lint高速化
毎度npm installを書けているとチェックにかかる時間が長くなってしまいます。
今回は、npm installの成果物であるnode_modulesをキャッシュしてしまいましょう。
社内にはS3互換ストレージがあるので、マウントしてnpm_modulesをまるごと置いてしまいます。
pipeline: restore-caches: image: plugins/s3-cache:1 endpoint: {S3ストレージのURL} access_key: {S3ストレージのアクセスキー} secret_key: {S3ストレージのシークレットキー} restore: true linter-build: image: node commands: - npm install textlint - npm install textlint-rule-preset-ja-technical-writing rebuild-cache: image: plugins/s3-cache:1 settings: endpoint: {S3ストレージのURL} access_key: {S3ストレージのアクセスキー} secret_key: {S3ストレージのシークレットキー} rebuild: true mount: - node_modules lint: image: node commands: - $(npm bin)/textlint --format pretty-error --preset ja-technical-writing index.md
こんな風に.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による技術文書執筆環境を整えてみました。
同じような境遇の方がいらっしゃいましたら、是非お試しください。