LoginSignup
13

More than 5 years have passed since last update.

静的サイトをMetalsmithでビルドし、Github Pagesにwerckerでデプロイする

Last updated at Posted at 2015-09-21

Metalsmithはやりたいことをプラグインで導入していくスタイルなので、若干のとっつきにくさはあるかもしれません。ただ、だいたいの仕組みとよく使うプラグインを把握してしまえばあとは自由にサイトを作ることができるようになってくるので、Node製でそういったものを求めているのであればMetalsmithが最良の選択になりそう。自分が使っているプラグインの可能性もあるけれども、ビルドは他のジェネレータと比較して、それほど早いといった感じはないなので記事数が膨大の場合には微妙なのかもしれない。

自分のサイトも今のところMetalsmithで作成しています。

インストール

まずはMetalsmithをインストール。

CLIを使う場合にはグローバルにインストールするのが普通なんだろうけど、CLIは使わないので普通にインストールしていきます。

npm init
npm install metalsmith --save

これだけではほとんど何もすることができません。必要なプラグインを自分でインストールしていきましょう。

プラグイン

よく使うプラグインをリストアップしておきます。

  • metalsmith-branch: 指定されたパターンで分岐処理
  • metalsmith-collections: ファイルのコレクションを生成
  • metalsmith-permalinks: 出力ファイルのディレクトリを\*.htmlから*/index.htmlに変更
  • metalsmith-copy: ファイルのコピー、もしくは移動。リネームも可能
  • metalsmith-layouts: テンプレートの処理
  • metalsmith-tags: カテゴリ、タグページの出力
  • metalsmith-markdown: Markdownの変換
  • metalsmith-asciidoc: AsciiDocの変換
  • metalsmith-filemetadata: 指定されたパターンにマッチするファイルにメタデータを追加
  • metalsmith-except: メタデータの除外
  • metalsmith-paths: メタデータに自身のパス情報を追加
  • metalsmith-replace: メタデータの置き換え
  • metalsmith-define: 使用するモジュールを一括で指定
  • metalsmith-draft: draftをbuildから除外
  • metalsmith-autotoc: ToC生成
  • metalsmith-highlight: コードのハイライト

ブログ程度のものであれば必要なプラグインはだいたい揃っているので、プラグインを自作しないといけないようなことにはならないとおもう。

metalsmith-collections

ブログをつくる目的であればかなりの重要なプラグインなんだけど、いきなりMetalsmithを理解しないまま使おうとすると、何をするためにつかうプラグインなのかがわかりにくいとおもう。

metalsmith
  .use(asciidoc())
  .use(collections({
    posts: {
      pattern: '_posts/**.html',
      sortBy: 'date',
      reverse: true
    }
  }))
  .use(templates())

こうするとテンプレート側でcollections.postsを指定したとき、patternにマッチしたファイルのデータを呼び出すことができます。

ol
  each item in collections.posts
    li: a(href=item.path)= item.title

これは_posts/**.htmlのファイルをメタデータのdateで日付の新しい順にソートしたもので、一般的なブログのArchivesのページを想像するとわかりやすい。

nextprevにはソート順で前後にあるファイルのデータが含まれていて、よくあるブログの前後ナビゲーションはこのプラグインでつくることができます。

metalsmith-collectionsがあればmetalsmith-feedやmetalsmith-sitemapのようなプラグインを使わなくてもRSSのようなフィードやsitemap.xmlをつくることはそれほど難しいことではありません。

うっかりやりそうなミスとしてはcollectionを作るタイミングがはやすぎて、必要なmetadataをもっていない状態のcollectionをつくってしまうこと。

metalsmith
  .use(asciidoc())
  .use(collections({
    posts: {
      pattern: '_posts/*.html',
      sortBy: 'date',
      reverse: true
    }
  }))
  .use(branch('_posts/*.html')
    .use(fileMetadata([
      {
        pattern: '_posts/*.html',
        metadata: {
          template: 'posts/blog.jade',
          autotoc: true
        }
      }
    ]))
  )
  .use(templates())

サンプルだから処理そのものはちょっと不自然になっているけれども、このサンプルのようにfileMetadataでmetadataを追加するタイミングがcollectionを作成した後になっていると、このcollectionにはfileMetadataで追加されたmetadataは含まれていないことになります。

metalsmith-layouts, metalsmith-filemetadata

Wordpressからの移行で、JekyllやOctopressのような静的ジェネレータを一切使ったことがない場合にはちょっとわかりにくいのかもしれません。

---
title: テスト投稿
date: 2015-06-12
tags: test
layout: post.jade
---

[[test]]
== テスト
これはテスト投稿です。

このAsciiDocの上部にある---で囲まれている部分がYAML front-matterになります。テンプレートを使う場合にはここのメタデータにtemplateを追加して、テンプレートに使うファイルを指定するだけです。

ただブログの記事のようにそのフォルダ内すべてでかならず共通になるメタデータをすべてのファイルに記述するのは面倒なので、metalsmith-collectionsを使わないときにはmetalsmith-filemetadataをつかうのがおすすめ。

metalsmith
  .use(asciidoc())
  .use(fileMetadata([
    {
      pattern: '_posts/*.html',
      metadata: {
        layout: 'post.jade'
      }
    }
  ]))

これで_posts直下にあるすべてのHTMLファイルのメタデータにtemplate: post.jadeが追加されます。

metalsmith-highlight

コードのハイライトにはすでにmetalsmith-metallicmetalsmith-code-highlightがあったのですが、自分はAsciiDocを使っていたのでMarkdown限定のmetalsmith-metallicは使えず、metalsmith-code-highlightはコードの推論がいらなかったことと、classの言語のプレフィックスがlang-である必要があったためmetalsmith-highlightというプラグインを作りました。

metalsmith-code-highlightはハイライトにhiglight.jsを使っていますが、metalsmith-highlightはPrismを使っています。

metalsmith
  .use(highlight())

オプションの設定項目はありません。それとPrismでは言語の指定で短縮表記を使えないようだったので、いくつかの言語にエイリアスをつくってあります。

gulpからMetalsmithでサイトを生成する

Metalsmithで使うJavaScriptやCSSはgulpでビルドしたいので、Metalsmithのビルドでもgulpから実行したくなります。

gulpからMetalsmith、もしくはその逆を扱うためにgulpsmithというプラグインがあるのですが、デフォルトではYAML front matterを読み込めないため使うには面倒な記述が必要になるのでgulpからコマンドを実行することにしました。

var gulp = require('gulp');
var exec = require('child_process').exec;

gulp.task('build:metalsmith', function() {
  exec('node metalsmith/build.js', function (err, stdout, stderr) {
    console.log(stdout);
    console.log(stderr);
    cb(err);
  });
});

GitHub Pagesで公開する

作成したサイトをGitHub Pagesで公開します。masterブランチにコードと変換前のデータ、gh-pagesブランチに公開データをプッシュします。gh-pagesブランチを事前に作成する必要はありません。

git add . -A
git commit -m "message"
git push -u origin master
git subtree push --prefix public origin gh-pages

このとき最終的にビルドしたサイトをpublicフォルダとすると、そのpublicフォルダのビルド結果をmasterブランチに含めなければいけません。また毎回ローカルで出力結果をビルドする必要があるので少し面倒な方法です。

werckerでビルドしてgh-pagesにプッシュする

サイトのビルドからgh-pagesブランチへのプッシュするまでの流れはwerckerで自動化すると便利です。

まずプロジェクトのルートにwercker.ymlを作成します。

box: nodesource/trusty

build:
    steps:
        - npm-install
        - script:
            name: build
            code: npm run build

deploy:
    steps:
        - lukevivier/gh-pages:
            token: $GITHUB_TOKEN
            domain: 4uing.net
            basedir: public

検索でかかる情報の中には古い情報もあって、古い情報のwercker.ymlを使うとおそらく動きません。自分はまずboxの指定から間違えていてかなりハマりました。

werckerでの設定はとくに難しいところはありません。

Createからリポジトリを選択して指示通りにアプリケーションを作成、Deploy targetsのDeploy target nameにgh-pages
Auto deployにmasterを指定します。Deploy pipelineにwercker.ymlで使用するGITHUB_TOKENを作成して終了です。

その他の静的サイトジェネレータ

Node.js製の静的サイトジェネレータにはMetalsmith以外にもいくつかあるので、Metalsmithの前に使ったことのあるジェネレータの簡単な紹介をしておきます。

Hexo

Node.js製のジェネレータの中ではGitHubのStar数が最上位なので、Node.js製という条件内であれば今のところ一番人気といっていいんじゃないかとおもう。

初期状態のCSSプリプロセッサがstylusになっていたり、デフォルトテーマのEJSがまるでWordpressのテンプレートをみているような記述になってるので、これだけでHexoが嫌いになりそうになったんだけども、このへんはすべて差し替え可能なので問題になることはありません。

<% if (theme.sidebar === 'bottom'){ %>
  <%- partial('_partial/sidebar') %>
<% } %>

こういう記述はJadeに置き換えることができるので、以下のように記述することができます。

if theme.sidebar === 'bottom'
  != partial('_partial/sidebar')

ドキュメントがわかりやすいので、テーマの作成で困ることはないとおもう。コードのシンタックスハイライトにはhighlight.jsが使われているんだけども、Jekyllからの移植用のためなのかクラス名はPygmentsに準じたものになっていたりと、Jekyllからのテーマの移植もしやすいようになっているのかもしれません。

ヘルパーも結構便利でToCみたいなものから、記述が面倒になりがちなリンクや日付関連のものだったり色々と揃ってるのでテンプレートを自作するときにはまず一通り確認するとよさそう。

HubPress

静的サイトジェネレータでも、さまざまな環境から手軽にアップデートができるのがHubPress。記事の作成や更新はもちろんブログの作成からすべてをGitHubのページ上で行うことができます。

記事をMarkdownではなくAsciiDocで書くというのがわりと新鮮。AsciiDocの存在自体、HubPressで知ったんだけれども技術系のブログ記事であればAsciiDocのほうが書きやすいはず。ただこのAsciiDocが合わなかった場合、Markdownに変更するといったようなテンプレートエンジンの変更もできないので選択肢から除外されることになります。

ただそれよりも現状の移行における大きな問題は生成したHTMLファイルの出力先のフォルダを指定できないことで、これはつまり過去の記事はこれまでのURLとは異なるものにならざるをえないことを意味しています。ブログの移行ですべての記事のURLが変わることを許容することは難しいので、メインのブログからの移行はまだ現実的ではなさそう。

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
13