Welcome to Jekyll!

Jekyllにした。

Jykyll+Bootstrapでサイトリニューアルに触発されたのが発端。この記事を読んだときはなるほどと思ったものの、すぐに手を動かすところまではいかなかった。その後、仕事が忙しくなるとともに、つつつと手が。こういうのって部屋の掃除や模様変えと同じだね。

前回のサイト更新でOctopressにしていたので、OctopressがベースにしているJekyllにするのは楽なものだろうと思っていた。

いや、そもそも、放置していたこのサイトを更新するにあたって、ほげめも方式を適用しようとしのが始まり。Octopressも新しくなっているだろうとの予想も含んでいたのだが、そうなってはいなかった。github上では活発なようだけどもウォッチしているわけではないので手を出し難く、それならいっそOctopressを止めることにした。

Octopress独自のプラグインなどを外したり、コピペしたり、あとは多少の書き換えでいけるだろうと。そんな軽い気持ちだった。実際にやってみると、たしかに大枠では同じなのだが予想していたよりもOctopress独自の仕様が多い。これにはベースとするJekyllのバージョンが大きく異なるところも関係するのだろう。なにせ0.11.0から1.3.1へのバージョンアップである。

ともあれ、まずはOctopressで運用していた記事とテンプレートをコピーして、jekyll buildできるところまで持っていくことにした。

基本となるJekyll環境は、ほげめもの組み合わせを参考にして、jekyll-assetsでasset pipelineを有効にし、さらにjekyll-hamlでhaml記法を使えるようにした。最初のGemfileは残していないのだが、たしかこんな内容だったと思う。

source 'https://rubygems.org'
gem 'rake'
gem 'jekyll', '~> 1.3.1'
gem 'jekyll-assets'
gem 'jekyll-haml'
gem 'haml'
gem 'sass'

プラグインが足りなくてbuildできない記事がいくつかあったため、プラグインを使わなくてすむように記事の書き方を変えたり、あるいはプラグインをコピーしてきたり、ついでに新しめの同等のプラグインを探してきたりして対処した。そうして、ひと通りbuildできるようになったら、レイアウトをなんとかする作業に取り掛かる。ここからズルズルと浅い深みはまったいった。

古いJekyllをベースにしているOctopressのコードをできるだけ残したくなかったため、プラグインもテンプレートも持ち込まない状態から作業を始めた。いくつかのプラグインは必要なため改めて持ち込んだが、テンプレートは自分で書いてみることにした。ちょっとだけBootstrapを使ってみたいという考えていたからだった。

どうにもデザイン向きのことにはあまり関わってこなかったこともあり、どちらかというと苦手な分野の作業だが、自分としては目新しいこともいくつかあってトライ&エラーをそれなりに楽しんでいた。だが、そうこうとしているうちにjekyll-hamlによるhamlサポートとJekyllがもともと採用しているLiquidテンプレートとの相性の悪さにうんざりしてきた。

hamlはインデントを使って記述するので、空白の扱いにはちょっとだけうるさい。これに対してLiquidは最終的なHTML出力には関係ないでしょと言わんばかりに無頓着。両者をなんとかすり合わせるわけだが、これが実に読みにくい。たとえばこのように。

%ul.pager
  {% if paginator.previous_page %}
  %li.previous
    %a(href="{{ paginator.previous_page_path }}") « Newer
  {% else %}
  %li.previous.disabled
  {% endif %}

Jekyllから渡される情報をhamlで参照すればよいではないかとコードを読み始める。そうすると、実はjekyll-hamlにはそれほどボリュームがない。hamlからhtmlに変換するためのコンバータクラスを定義し、テンプレートが読み込まれた直後にhtmlに変換してしまうというもの。だが、この実装方針が問題となる。

jekyll-haml方式ではhaml変換時点でJekyllからの与えることができる情報は限られる。せいぜいサイト全体の設定くらいのもの。記事ごとの情報を与えることはできないから、たとえばhamlレベルで記事のタイトルを知ることはできない。もちがん記事の日付けなど、その他の情報についても変わりない。もともとのJekyllの構造では、読み込んだ記事の一つ一つに対してまずLiquidテンプレートの展開を行う。その後にコンバータ(新常はmarkdown)による書式変換を行う。jekyll-hamlとは書式変換のタイミングが異なる上に順番も逆になる。

jekyll-hamlの他の実装もいくつか見付かるが、どれも同じようなやり方をしている。これにはJekyllの構造が関係しているのだと思う。そもそもJekyllは、Liquid以外のテンプレートエンジンを想定していないようだ。Liquidの機能が単なる文字列置換程度のものではないためでもあるかもしれないが、テンプレート中で参照できる情報は、Liquidテンプレートの展開の直前に生成されることが多い。さらにはLiquid展開の直後に書式変換が行われる。このため、これらの変換動作を、外部から、機能的に同等に違い状態で差し替えるのが難しい。

事情はコードを追っていくちにだんだんと分かってきた。でも、そうはいっても、なんかイヤなのだ。

そうやってうだうだやっているとき、ちょっとひどいかもしれないやり方を思い付いた。ちょっとこれはないかなーという気もしたが、Jekyll自身にあまり手を入れずにうまくやる方法を他には思い付かなかったこともあり、仕事が忙しかったこともあり、気付いたらその思い付きを実装し始めてしまっていた。だいたいこのあたりで四、五日はすぎている。

小さくひっかかるのはいくつもあったが、少し大きめのひっかかりが次に起きたのはBootstrapのフォントファイルを使うときだった。

jekyll-assetsではasset pipelineを使えるようにしいる。各種ファイルは必要に応じてassetsディレクトリにコピーされ、その際にはファイル名が変換される。Bootstrapでは$icon-font-path$icon-font-nameによってフォントファイルをカスタマイズできる。

@font-face {
  font-family: 'Glyphicons Halflings';
  src: url('#{$icon-font-path}#{$icon-font-name}.eot');
  src: url('#{$icon-font-path}#{$icon-font-name}.eot?#iefix') format('embedded-opentype'),
       url('#{$icon-font-path}#{$icon-font-name}.woff') format('woff'),
       url('#{$icon-font-path}#{$icon-font-name}.ttf') format('truetype'),
       url('#{$icon-font-path}#{$icon-font-name}.svg#glyphicons_halflingsregular') format('svg');
}

しかしこの変数の使い方が具合いが悪い。asset pipelineではfoo.eotfoo-[MD5].eotに変換するため、これらの変数の書き換えでは対応できない。

次のような記述をapp.scssなどに加えておくと、なんとかフォントファイルにアクセスできるようになるのは確認できた。ただ、それは、もともとのフォントへのアクセスを止めるものではなく、いくつかの404レスポンスが返った上でのことであるのも確認できた。

@font-face {
  font-family: 'Glyphicons Halflings';
  src: url(asset_path('glyphicons-halflings-regular.eot'));
  src: url(asset_path('glyphicons-halflings-regular.eot?#iefix')) format('embedded-opentype'),
       url(asset_path('glyphicons-halflings-regular.woff')) format('woff'),
       url(asset_path('glyphicons-halflings-regular.ttf')) format('truetype'),
       url(asset_path('glyphicons-halflings-regular.svg#glyphicons_halflingsregular')) format('svg');
}

どうにかならないかとsass/scssの機能を調べたり、改めてCSSの記法を確認し直したりした。しかしうまいやり方を見付けられない。これはいよいよBootstrapというかsass-bootstrapに手を加えるしかないのかなと思い始めたとき、Sprocketsでなんとかできないだろうかというところに思いが致った。

Sprocketsはasset pipelineの実体である。もちろんscssからCSSを生成するのも、と言えば語弊があるかもしれないが、そのあたりをコントロールしているのはSprocketsである。そう思って軽くあたってみたところ意外なほど簡単にヒントが見付かった。Sprocketsにはファイル単位での書式変換の前後に適用するフィルタと、ファイル群を統合した後に適用するフィルタがある。このうちの最後のものを使って、フォントまわりの不都合をやや強引にだが解消できた。

とまあ、そういうあれやこれやがありながら、ようやく今の状態にまですることができたころには二週間くらいが過ぎていた。

実のところ、自分で見ても以前のOctopressのテンプレートを使っていたときのほうが全体的に整っていると思う。たが、まあ、いっか、ということにした。そのうち、また気が向いたときに直していこうと思う。