Jekyll

Jekyllをブログじゃないっぽくする設定

Github Pagesでドキュメントを公開したい

以前書きましたが、静的サイトジェネレータを使ってドキュメントを公開するサービスとしては、Github Pagesが適していると思われます。

改めてまとめますと、いわゆるブログじゃなくドキュメントを公開する上でのGithub Pagesの優位性は、なんといってもGithub自体が持つバージョン管理サービスとしての側面です。

また、ホスティングサービスとしての安定性が高い……アクセス溢れたとか追加料金寄越せとか基本言われないというのも、長期的に公開するコンテンツをホストする上では魅力的です。

そこで、せっかくだからサーバサイドで動かしてくれるJekyllを利用しようかと思うのですが、Jekyllを素で使うと微妙にブログっぽいのです。

Jekyllがブログっぽいとは

とりあえず、jekyll newで自動生成される環境を例に取りましょう。

生成される記事のURLは、以下のようになります。

http://exmaple.com/jekyll/update/2014/09/22/welcome-to-jekyll.html

URLに日付が含まれています。

また、各記事のファイル名は、2014-09-21-welcome-to-jekyll.markdownといった形で、必ず先頭に日付を含める必要があります。

さらに、インデックスページでは、記事が更新日時順に一覧表示されます。

なんかブログっぽい! そうじゃない!

パーマリンクを変更してみる

Jekyllの各記事のURLは、上記ページで解説されているように、基本的に変数で指定されます。

プリセットとして用意されているスタイルはdate,pretty,noneの3種類であり、無指定の場合はdateが適用されるようです。また、変数を自由に組み合わせて指定することもできます。

パーマリンクの規則は、_config.ymlまたは各記事ファイルのYAML Front Matterにおいて行います。例えば、以下のような形です。

1
permalink: :title/

この場合、URLは以下のようになります。

http://exmaple.com/welcome-to-jekyll/

いい感じですね。

さらに、各記事ファイルで、直接にURLを記述することもできます。

1
permalink: /hogehoge/

この場合、ファイル名はURLと関係ないので、日本語を含めて(日付を先頭につける以外は)自由に決めることができます。

さらに、インデックスページの内容を書き換えれば、自分で好きなように各記事へのリンクを記述することも当然可能です。

具体的には、index.html内の以下の部分を置き換えます。

<ul class="post-list">
  {% for post in site.posts %}
    <li>
      <span class="post-meta">{{ post.date | date: "%b %-d, %Y" }}</span>
       <h2>
        <a class="post-link" href="{{ post.url | prepend: site.baseurl }}">{{ post.title }}</a>
      </h2>
    </li>
  {% endfor %}
</ul>

Pageとして作成してみる

Jekyllで生成されるコンテンツには、PostとPageがあります。Postとして作成する場合、記事ファイルは(変更可能な)指定のフォルダ以下に格納し、日付を先頭につける必要があります。

Pageとして作成する場合、そのような制限はありません。プロジェクトフォルダ内の任意の階層に、任意のファイル名で作成することができます。

この場合、パーマリンクは_config.ymlで指定することができないため、ファイルパス(フォルダパス+ファイル名)またはファイルごとにFront Matterで指定されたパーマリンクが適用されます。

テンプレートを利用する場合の注意点

こうすると、Pageとして作成するのがよさそうに思われますが、PostとPageそれぞれが、テンプレートによってリストされうることに注意する必要があります。つまり、{% for post in site.posts %}あるいは{% for page in site.pages %}といった記述です。

すなわち、「記事」をPageとして作成した場合、その他の固定的なPage(例えばabout)との区別ができなくなります。

これは、特にフィードを配信する場合に問題になり得ます。デフォルトのfeed.xmlには{% for post in site.posts limit:10 %}という記述が含まれており、すなわちPostを最大10件で抽出してフィードとして配信しています。ここを書き換えればPageを配信することも可能ですが、するとJekyllで生成される全てのコンテンツがフィードに含まれてしまいかねません。

まとめ

サイト全体を雑多なドキュメントの集合として構成したい場合は、各ドキュメントはPostとして作成するのが良いでしょう。

サイト全体をひとつのドキュメントして構成したい場合、あるいはプロモーション用ウェブサイト的な構成を行う場合などは、Pageの集合として構成するのがよさそうです。

サーバサイドJekyllでシンプルなウェブサイト管理

Github PagesではサーバーサイドJekyllが使える

以下のページに詳しいですが、Github PagesではサーバサイドでJekyllを利用することができます。

Jekyllとは、簡単にいえば本文さえ与えればいい感じのウェブページに整形してくれるヤツです。通常はローカルPCで整形してからアップロードするのですが、Github Pagesではサーバ側で整形してもらうこともできます。

使い方

簡単すぎてちょっと戸惑いましたが、既存のテーマなり、jekyll new なんとかかんとかで生成される雛形なりに、原稿ファイルを加えてGithub Pages用のリモートリポジトリ(の適切なブランチ)に送るだけです。もちろん自分で雛形を書いてもいいです。

サーバサイドJekyllにはどんなメリットがあるのか?

自分でビルドする手間が省ける

当たり前ですがこれが第一。

Jekyllは通常ターミナル(Windowsならコマンドプロンプト)からしか実行できないので、自分でJekyllしなくていいということは、ターミナルを使う必要がなくなるということでもあります。

Githubにシンクするだけなら、Github Pagesのデスクトップアプリとかでもできるので。

「完成品」を管理する必要がない

以前も書きましたが、サーバサイドJekyllを利用する場合、手元(リモートリポジトリも含む)には、実際にウェブページとして公開されるHTMLファイルは残りません。

Jekyllで生成されるHTMLファイルは、それ自体を編集したりするものではないので、雛形を組み終わってしまえば扱う必要はありません。うっかり書き換えたり削除したりしないよう神経を使うこともなく、やってしまえば非常に楽です。

シンプルなウェブサイト管理

当初はびっくりしましたが、原稿と雛形だけ管理すればいいというのは気に入りました。

ただし、サーバサイドJekyllを利用する場合、Jekyllのプラグインが利用できません。気になるプラグインもあるので、そのうちローカル生成に切り替えるかもしれません。

Github PagesをサーバーサイドJekyllに切り替えました

表題の通り。

いくつか未解決の問題があるのですが、とりあえずやってみました。

未解決問題

  • White PaperテーマでのTOCへのCSS指定
    • ul#markdown-tocじゃあかんのかい
  • layout:post限定でのヘッダー項目挿入
    • layout基準でのifの書き方がわからん
    • まあindex.htmlにヘッダーいらないからpost.html自体に書いてもいいんだけどさ……
  • pagenationが1ページに収まらないとき限定のprevious/next表示
    • なんで最初からこうなってないんだろ

Jekyllでサイトを構築する最短手順

Jekyllを用いて、ウェブサイトをできるだけ簡単に構築したい。

とりあえずJekyllはインストールできてるものとする。

必要ファイルを生成してもらう

とりあえず、ターミナル(Winならコマンドプロンプト)を起動して、

cd うんちゃらかんちゃら

で、生成するファイルを置いておきたい(というか置いてもいい)フォルダに移動する。

ここでおもむろにJekyll公式サイトを見る。

~ $ gem install jekyll
~ $ jekyll new my-awesome-site
~ $ cd my-awesome-site
~/my-awesome-site $ jekyll serve
# => Now browse to http://localhost:4000

こんなことが書いてある。それぞれの意味合いは、

  1. Jekyllのインストール
  2. 新規サイト(の構成ファイル)を作成
  3. 作成したフォルダに移動
  4. プレビューを起動
  5. ブラウザでhttp://localhost:4000ここ見れ

ということ。

やってみた。こんな実行ログが出る。

Configuration file: /Users/user/GitHub/SandBox/my-awesome-site/_config.yml
            Source: /Users/user/GitHub/SandBox/my-awesome-site
       Destination: /Users/user/GitHub/SandBox/my-awesome-site/_site
      Generating... 
                    done.

トップページ

こんなんできた。

Welcome to Jekyll!をクリックする。

個別記事ページ

aboutをクリックする。

aboutページ

なお、プレビュー時にはJekyllがローカルサーバーを起動しており、この動作はターミナルでctrl-cを入力することで停止できる。

生成されたファイル群

jekyll new my-awesome-siteで生成されたファイルのリストは以下。

.
├── _config.yml
├── _includes
│   ├── footer.html
│   ├── head.html
│   └── header.html
├── _layouts
│   ├── default.html
│   ├── page.html
│   └── post.html
├── _posts
│   └── 2014-08-10-welcome-to-jekyll.markdown
├── about.md
├── css
│   └── main.css
├── feed.xml
└── index.html

それぞれの意味合いは以下の通り。

  • css/

    普通にCSS

  • _includes/

    layoutから呼び出されるパーツ置き場

  • _layouts/

    ページごとに指定する「型」置き場

  • _posts/

    ページのソースファイル=「本文」置き場

  • .gitignore

    Github Pagesに上げるときの無視リスト

  • about.md

    ソースファイルのひとつ

  • feed.xml

    RSSフィードファイル

  • index.html

    普通にトップのHTML

  • _config.yml

    サイトの設定情報

これらはJekyllによる処理が行われる前のファイル群であり、公開されるものではない。

ソース→コンテンツ変換によって生成されたファイル群

プレビュー時に、公開用のファイルも生成されており、それは_siteフォルダに収められている。そのファイルリストは以下の通り。

.
├── about
│   └── index.html
├── css
│   └── main.css
├── feed.xml
├── index.html
└── jekyll
    └── update
        └── 2014
            └── 08
                └── 11
                    └── welcome-to-jekyll
                        └── index.html

注目に値するのは以下の点。

  • トップレベルに置かれていたabout.mdは、専用のフォルダが生成されている
  • _postsフォルダに置かれていたソースファイルは、jekyll/updateにコンテンツが生成され、日付によってフォルダ分けされている

変換に影響する各ファイルの内容

ここで、_config.ymlの内容を確認してみよう。

# Site settings
title: Your awesome title
email: your-email@domain.com
description: "Write an awesome description for your new site here. You can edit this line in _config.yml. It will appear in your document head meta (for Google search results) and in your feed.xml site description."
baseurl: ""
url: "http://yourdomain.com"
twitter_username: jekyllrb
github_username:  jekyll

# Build settings
markdown: kramdown
permalink: pretty

titleの内容がHTMLのtitle要素になっている。

また、permalink要素は変換後のフォルダ構成などを決定している。

では、ソースファイルである_posts/2014-08-08-welcome-to-jekyll.markdownを見てみよう。

---
layout: post
title:  "Welcome to Jekyll!"
date:   2014-08-08 20:26:36
categories: jekyll update
---

You'll find this post in (以下略。本文に該当)

重要なのは冒頭のマイナスで囲まれた部分、YAML Front Matterである。

ここの記述によって、個々のページをコントロールすることができる。

それぞれの意味合いは以下の通り。

  • layout: post
    postレイアウトファイルを適用
  • title: “Welcome to Jekyll!”
    ページのタイトルを指定
  • date: 2014-08-08 20:26:36
    投稿日時を指定
  • categories: jekyll update
    カテゴリを指定。この場合、jekyllカテゴリ内のupdateサブカテゴリということになる。生成されるファイルのフォルダ構成に影響しているのが分かる。

では、about.mdのフロントマターも見てみよう。

---
layout: page
title: About
permalink: /about/
---

先ほどとは異なるレイアウトが指定されている。また、パーマリンクが指定されており、その通りにフォルダが構成されているのが分かる。

記事を追加してみる

_postsフォルダにソースファイルを入れればいいことは分かったので、適当なソースを追加してみた。

ファイル名は2014-08-09-mypost.markdown

---
layout: post
title:  "自分で書いてみたよ!"
date:   2014-08-08 22:28
categories: blog test
---

ほんぶん!!!

もう一度jekyll serveしてみる。

_site/blog/test/2014/08/08/mypost/index.htmlが生成された。

こんなふうに表示される。

トップページ

新しいリンクができている。

記事ページ

これで、サイト名等の個別情報を書き換えれば、すぐにでも記事を生成していける。そして、FTPなりGithubなりでホストすればすぐ公開できる。

しかし、ファイル構成とかもっとブログじゃないっぽくしたい。続きは次回。

Mac OS XでJekyllがインストールできない問題とその対策

正直理屈はよく分かっていないのだが、日本語でまとまった記事が見当たらないのでまとめておく。

Jekyllの必要環境

JekyllはRuby製のフレームワークであるから、実行のためにはPCにRubyがインストールされていなければならない。

また、Jekyllはrubygemとして配布されているので、インストールするにはまずrubygemをインストールする必要がある。

これらの導入方法は省くとして、Mac OS Xでの環境確認は以下の通り。

ターミナルで以下コマンドを実行。だいたいソフトウェア名に-vオプション付ければ、バージョンが表示されてインストール済みであることが確認できる。

ruby -v

例えばこんな結果ならOKのはず。

ruby 2.0.0p451 (2014-02-24 revision 45167) [universal.x86_64-darwin13]

rubygemならこう。

gem -v

結果はこう。

2.0.14

というわけで、必要環境は揃っているはずなのだが、インストール先のフォルダへの書き込み権限がねーぞ的なエラーが出た。

ログを取るのを忘れたが、以下ページにあるのと(rubygemのバージョン以外)同じだと思う。

こんなエラー。

ERROR:  While executing gem ... (Gem::FilePermissionError)
You don't have write permissions into the /Library/Ruby/Gems/1.8 directory.

また、たぶん公式のトラブルシューティングにも載っている。

原因はなんなのか?

正味よく分からんのだが、Xcode入れてると何かあるようだ。昔なにかに使ったのでたしかにXcodeはインストールしてある。

Xcodeをアンインストールすればいいような気もするが、とりあえずまっとうに回避してみる。

解決方法

概ね、以下の二つがあるようだった。

書き込み権限がないならあるところに入れようJekyll

以下のコマンドを用いる。

gem install jekyll --user-install

rubygemのinstallサブコマンドに--user-installオプションを付ける。

Command Reference - RubyGems Guidesによると、

Install in user’s home directory instead of GEM_HOME.

ということで、rubygemホームディレクトリのかわりに、ユーザーホームディレクトリにインストールするという。そこには書き込み権限があるから大丈夫という理屈だ。

しかし、インストール先が変わることで、あとで面倒があったらいやなので、この方法はとらなかった。

書き込み権限がなければ与えればいいじゃない

以下のコマンドを用いる。

sudo gem install jekyll

sudoコマンドを用いることで、rubygemにスーパーユーザ権限を与える。書き込みもなんでもござれというわけだ。

この上記のコマンドラインを実行した場合、Mac OS Xに設定したユーザパスワードの入力を求められた。入力すると、あっさりとインストールが開始された。

おまけ:Jekyll実行時の謎通知

無事に、Jekyllをインストールすることができたのだが、

sa-b:~ user$ jekyll -v
Notice: for 10x faster LSI support, please install http://rb-gsl.rubyforge.org/
jekyll 2.2.0

2行目に謎の通知が。

これについては、JekyllのGithubリポジトリ内Issueに言及があった。

昔はclassifier gemというのがあってそれをインストールするとJekyllによかったのだが、現在は公開されていないので諦めろといった話のようだ。

Github PagesにおけるサーバサイドJekyllの注意点

修正あり

最初、サーバサイドJekyllで_postsフォルダが使えないと勘違いしていた。

Jekyllの基本

Jekyllとは、簡単に静的ウェブサイト(HTMLファイル)を生成することができるソフトウェアである。「本文」と「レイアウト」を組み合わせることで、本文を記述した原稿ファイルに対して、自動的にウェブサイトとしての体裁を整えることができる。

基本的にはPCにインストールして、ターミナル(Winだとコマンドプロンプト)から利用する。

Github PagesではサーバーにJekyllがインストールされており、Jekyllで自動生成を行うために必要なファイル群が揃っていれば、ファイルを送信した時にJekyllによる変換をかけてくれる。

Github Pages特有の条件

設定の上書き

Github Pagesは、_config.ymlの一部情報を上書きする。

上記ページより、上書きされる項目・内容は以下の通り。

safe: true
lsi: false
source: your top-level directory

source指定が不可能であることにより、全てのソースファイルをトップレベルディレクトリに配置しなければならない

Keep in mind that if you change the source setting, your pages may not build correctly. GitHub Pages only considers source files in the top-level directory of a repository.

ただしこれは、Jekyllを実行する基準がリモートリポジトリのトップレベルディレクトリだということであって、各記事の「本文」となるMarkdownまたはTextileファイル(原稿ファイル)をルートフォルダに置かねばならないという意味ではない。

そもそも、Jekyllにおいて、通常原稿ファイルを配置すべきは_postsフォルダだし、そうしたファイル構造は当然Github PagesのサーバーサイドJekyllでも有効である。

また、Jekyllは、ソースフォルダのサブフォルダを再帰的に参照する。(ただし無視するフォルダもある。_draftsとか)
すなわち、ファイル自体が条件を満たしていれば、「原稿ファイル」がどんな深い階層にあろうとも、必ず見つけ出して変換してくれる。

言い換えれば、gh-pagesブランチに置かれたファイルは全部ウェブサイトとして公開されますよということであって、Github Pages専用のリポジトリではあまり関係のないことだ。

それよりも、safe: trueにより、任意にプラグインを追加できないことが、実際的な問題としてあるだろう。

Github PagesにおけるJekyllの駆動タイミング

単純に、ソースファイルをGithub Pages用リポジトリに送信したタイミングで駆動するようだ。

ファイルを配置した後、改めてJekyllを走らせるために何かする必要はないし、逆に言えば、任意のタイミングで走らせることはできない。

変換されたファイルはリポジトリに表示されない

ビックリカンカンである。このことに触れているウェブ上の記事を全く見つけられなかったが、事実のようだ。

例えば、フロントマターでpermalink:example.htmlと指定したとする。

この場合、(ベースURL)/example.htmlで生成されたコンテンツにアクセスできるわけだが、example.htmlというファイル自体は存在しない。というか、ブラウザアクセスできる以上は存在しているわけだが、リモートリポジトリ上には表示されないため、ユーザーが取り扱うことはできない。

また、permalink:blog/example.htmlとした場合、URLは(ベースURL)/blog/example.htmlとなるわけだが、同様にblogというフォルダも、ユーザーが取り扱える範囲内には存在しない。

Github PagesでJekyllを使ってtitle付きのページを生成したかった

TOC付きのページを簡単に公開したい

なんか最近ずっとこればっかり言ってますが、したいのです。もっともっと簡単にしたいのです。

現在は、Sublime TextのMarkdown Previewパッケージを利用して、TOC付きのHTMLファイルを生成してからGithub Pagesにプッシュしています。

しかし、titleが全然生成されなくてファイル名そのまんまにしかならないので、なんとかしたいと思っていました。

これが、Github Pagesを使うと簡単にできそうなので、やり方を調べてみます。

用語について整理しよう

Githubとは?

ソフトウェア開発などで、バージョン管理を行うためのサービスです。

Githubは、バージョン差分データと、ファイルそのものを保持してくれます。従って、ある種のレンタルサーバーであるとも言えます。

Github Pagesとは?

Githubの機能のひとつで、まさにレンタルサーバーのように、GithubにアップロードしたHTMLファイルにURLを与えてウェブ公開してくれるサービスです。

Jekyllとは?

静的サイトジェネレータと言われるソフトウェアの一種です。

原稿データテンプレートを与えることで、自動的に(静的な)HTMLファイルを生成してくれます。

これ自体は、ドキュメントを変換するエンジンであり、ファイルを公開する機能は持ちません。

Github PagesにおけるJekyllとは?

Jekyllは基本的にはローカルで動かすエンジンですが、Github Pagesはサーバー側でJekyllを動かすことができ、原稿データとテンプレートをアップロードすると自動変換してくれます。

Octopressってやつとどう違う?

Github PagesでBlogやろう的な記事を読むとよく出てくるOctopressですが、これはJekyllを利用する静的サイトジェネレータです。

それらしいウェブサイト(Blog)を構築するためのCSSなどがパッケージ化されており、Jekyllを用いて、簡単に整ったウェブサイトを構築することができます。

なぜJekyllを使うのか?

Jekyllにはより高度なコンテンツ生成のための拡張機能が存在しますが、その中にTOCを生成するものがあります。titleも生成できます。

これは、Github PagesにホストされているJekyllでも利用することができます。今回はこれを利用したい。

ローカルでJekyll走らせてもええんちゃう?

まあそれでもいいのですが、アップロードしただけでJekyllやってくれるならそのほうが楽だし。

私はギーク度が低いので、できるだけ黒い画面を見たくないのです。

どうやってGithub PagesでJekyllを走らせるのか?

Automatic page generator

Githubのリモートリポジトリを見ると、そんなメニューが用意されています。

GithubリモートリポジトリのSettingから

試してみたのですが、これは環境を構築してくれるわけでもたくさんページを作れるわけでもなく、index.htmlを生成する機能です。

実行する際には、入力したMarkdownテキストをサーバサイドJekyllで変換していると思われますが、これだけでずっと記事を生成していくわけにはいきません。

じゃあどうやるの?

結論から言うと、というかすでにそういう書き方をしましたが、原稿データとテンプレートをアップロードするだけでよいようです。

ちゃんとした用語で言い換えると、ローカルリポジトリに原稿となるMarkdownファイルとJekyllテーマファイル群を用意し、コミット&シンクしてリモートリポジトリにプッシュされると、サーバサイドで自動的にJekyllが走って変換してくれるみたいです。

試しに適当なJekyllテーマをダウンロードして、_congig.ymlを編集してプッシュしてみました。使用したテーマはこちらです。

しかし、なんか_congig.ymlの内容がアカンかったようでこんなエラーメールが来ました。

[catfist.github.io] Page build failure

The page build failed with the following error:

You have an error on line 28 of your _config.yml file. For more information, see https://help.github.com/articles/page-build-failed-config-file-error.

If you have any questions please contact us at https://github.com/contact.

該当箇所は以下の部分でした。

google_analytics:(ここにGoogle アナリティクスのアナリティクスID入れてた)

で、IDを削除してシンクしたら同じエラーが出ました。空でもあかんのかい……

ムカついたので関連しそうなところを全部コメントアウトしてシンクしてみました。

がっ……ダメ!

続く次回!

おまけ:ブランチ初めて分けたよ

今回の実験では、大量の新規ファイルをコミットすることになるため、初めて新規ブランチを作成しました。

これでいつでも原状復帰できるはず……ですが、完全に流れで記録もとらずにやったので、元に戻せるのかどうかよく分かりません。次回以降戻し方も書くかもしれません。