読者です 読者をやめる 読者になる 読者になる

Jekyll は軽快なブログソフトなので乗り換えてみた

EY-Office Ruby

今まで EY-Officeホームページ・ブログRadiant を使って作成していたが、Jekyll に変更しました。

Radiantは高機能なのですが、Webアプリのため原稿を書き確認するというサイクルが遅いとか、文章を入力するtextareaは貧弱などの問題がありました。
また、EY-Officeホームページ・ブログはradiantからスタティックなページを作成し、サーバーに転送していましたが、これも一手間でした。

Jekyll とは?

Jekyll は ローカル(自分のMac,PC)で動くプログラマー向けのCMS、Blog作成ソフトです。

  • ページの原稿は Mac上のエディターで書きファイルに保存します
  • jekyllコマンドは、原稿からスタティックな html ファイルが生成します
  • また、jekyll コマンドは確認用サーバーにもなり、Mac上で生成されたページが確認できます
  • 原稿用のマークアップ言語としては標準で Markdown, Textile, html が使えます
  • 一般的なCMS、Blogソフト同様にレイアウト(テーマ)や生成されるページの共通部分をまとめる機能があります
  • ページ生成に便利なLiquidテンプレート言語が使えます
  • ブログ用の機能も持っています
  • 原稿が変更されると、確認サーバーは自動的に html ファイルを更新します(設定によっては)
  • 原稿ファイルの管理は git 、コマンドの自動化は rake などの既存ツールを使います
  • http://pages.github.com/ で使われます

Jekyll の使い方

インストール

既にRubyがインストールされていれば

% gem install jekyll
% gem install RedCloth

だけです。 マークアップに Markdown を使うなら gem install RedCloth は不要です

Jekyll のドキュメント

Jekyllのドキュメントは https://github.com/mojombo/jekyll/wiki にありますが、構成が良くなく以前みたドキュメントが探せなくて困ったので一覧にしておきました。

作業環境(ディレクトリー)の作成

https://github.com/mojombo/jekyll/wiki/usage にあるようなディレクトリーを準備します。_ から始まるディレクトリー、ファイルが Jekyll 用です。
画像やCSS用ディレクトリーは適当つくれば良いです。
https://github.com/mojombo/jekyll/wiki/sites に Jekyll を使ってるサイトとそのソース(たいていgithub)が公開されているので、いくつかの ソースを clone/ダウンロードして眺めてみるとをお勧めします。

私の環境は以下のようになってます

ekyll-ey-office/
├── Gemfile
├── _config.yml   ← 設定ファイル
├── _includes     ← 共通ファイル
│   ├── footer.html
│   ├── google_analytics.html
│   ├── header.html
│   └── menu_bar.html
├── _layouts       ← レイアウトファイル
│   ├── blog.html
│   ├── default.html
│   └── home.html
├── _plugins       ← 独自プラグイン
│   └── menu_image.rb
├── _posts         ← ブログ原稿ファイル
│   ├── 2009-08-31-type-of-cloud.html.textile
         ...
│   ├── 2012-06-11-is-mac-expensive.html.textile
│   └── 2012-06-18-paas-service.textile
├── _site          ← 生成されたhtml(css,image)が入るディレクトリー
│   └──
├── atom.xml         ↓ ここからは原稿ファイル
├── blog.textile
├── blog_archive
│   └── index.textile
├── company.textile
├── company_development.textile
├── css
│   └── base.css
├── education.textile
     ....
├── images
│   ├── ey_logo3.jpg
│   ├── flower2.jpg
        ....
│   └── xcode.png
├── index.textile
├── news
│   ├── index.textile
         ...
│   └── news-2009.textile
└── robots.txt
コマンドの起動

設定ファイルを書き、原稿を準備し(次のセクションで説明します) jekyll を実行すると

% jekyll 
Configuration from /Users/yy/Documents/jekyll-ey-office/_config.yml
Auto-regenerating enabled: /Users/yy/Documents/jekyll-ey-office -> /Users/yy/Documents/jekyll-ey-office/_site
[2012-06-20 17:04:20] regeneration: 91 files changed
[2012-06-20 17:04:20] INFO  WEBrick 1.3.1
[2012-06-20 17:04:20] INFO  ruby 1.9.3 (2012-04-20) [x86_64-darwin11.3.0]
[2012-06-20 17:04:20] INFO  WEBrick::HTTPServer#start: pid=2698 port=4000
[2012-06-20 17:04:47] regeneration: 1 files changed

のように、原稿からhtmlへの変換され、確認用サーバーが起動されます。自動更新にしておくと原稿が変更されると自動的にhtmlに変換されるので ブラウザーをリロードするだけで、最新のコンテンツを確認できます。

確認サーバーの終了は ^C 等で行ってください。

EY-Officeホームページ・ブログの設定例

設定ファイル _config.yml

server: true でjekyll コマンド実行後、http://localhost:4000 に確認用サーバーが立ち上がります。また auto: true なので原稿が更新されると対応するhtmlが自動的に更新されます。
設定ファイルに書かれた内容でテンプレートから参照出来るので、ここに書いておいきレイアウトファイル等では {{ site.author.name }} のように参照すると良いと思います。

permalink: /blog_archive/:year/:month/:day/:title   ← ブログのURL(ディレクトリー)構造

exclude: [".rvmrc", "Gemfile", "Rakefile", ".gitignore"]  ← 公開しないファイル

sitename:  EY-Office                                         ← レイアウト、RSS等で使う設定値
production_url : http://www.ey-office.com
title : EY-Office
author :
  name : Yuumi Yoshida
  email : yy@ey-office.coms

auto: true             ←  自動更新
pygments: false    ← コードハイライト
server: true           ← 確認用サーバー起動
server_port: 4000 ← 確認用サーバーのポート番号

詳細は https://github.com/mojombo/jekyll/wiki/configuration

原稿ファイル index.textile

原稿は TextileやMarkdown のようなマークアップ言語で書きますが、htmlを書く事も出来ます。マークアップ言語の区別は拡張子で行っているようで Textileは .textile、Markdownは .md です。
先頭の --- に挟まれた部分はレイアウトの選択やカテゴリーなどを指定します。この情報もレイアウトファイル等から参照できます。( 詳細は https://github.com/mojombo/jekyll/wiki/yaml-front-matter )
また、レイアウトのところで説明する、 Liquidテンプレート言語も使えます。

---
layout: home
---
h1. お知らせ

* ブログを更新しました "(detail_link){{ site.posts.first.title }}":{{ site.posts.first.url }}
* Facbookページを始めました "http://www.facebook.com/ey.office.jp":http://www.facebook.com/ey.office.jp です。

h2. 企業向けソフト開発のプライベートレッスン

EY-Officeの教育は画一的な集合教育ではなく、御社の開発プランや開発者のスキルに合わせた教育を御社に出向き実施します。 "(detail_link)詳細はこちら":/education.html

!/images/edu_flow.jpg(EY-Officeの教育)!
     ...
ブログ原稿ファイル 2012-06-11-is-mac-expensive.html.textile

ブログ原稿はブログ独自の処理が加わるので _post ディレクトリーに置きます。
ブログの原稿はファイル名に日付やURLになるファイル名を付けます (詳細は https://github.com/mojombo/jekyll/wiki/permalinks )
また先頭部分の title: にタイトルを書きます。

---
layout: blog
title:  Macは本当に高いのか?
---
iPhone(iOS)アプリの開発にはMacが必要になります、Ruby on Railsの開発にもMacは最適です。しかし世の中ではMacは高いというイメージがあり導入をためらっている方もいるかと思います。今回は本当にMacはWindowsPCより高いの検証してみたいと思います。

h3. 同じスペックのマシンで比較してみよう

本日(2012年6月10日)の時点で Apple Storeを見てみると MacbookAirの一番安い機種は¥84,000です。DELLのホームページを見ると一番安いノートPCは ¥44,980 です。

Macは高い・・・?  
    ….
レイアウト default.html

レイアウトは html で書きます。 {{ … }} や {% … %} の部分は Liquid というテンプレート言語で、値の埋め込み、ファイルインクルード、判断、繰り返しなが出来ます。(Liquidの詳細は https://github.com/shopify/liquid/wiki/liquid-for-designers 、参照出来る値は https://github.com/mojombo/jekyll/wiki/template-data )
{{ content }} の部分に原稿がhtmlに変換された内容が入ります。

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
{% include header.html %}
<body>
  <div class="all_area">
    <div class="header">
      {% include menu_bar.html %}
    </div>
    <div class="main_area">
      <div class="side">
        <img src="/images/ey_logo3.jpg" alt="EY-Office">
        {% if page.left_link != '' %}
        <div class="links">
          {{ page.left_link }}
        </div>        
        {% endif %}
      </div>
      <div class="contents">
        {{ content }}
      </div>
    </div>
    {% include footer.html %}
  </div>
  {% include google_analytics.html %}
</body>
</html>
共通ファイル header.html

複数のレイアウト等の共通部分をここに置き、インクルードして使います。このファイルでも Liquidテンプレート言語が使えます。

<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8">
<meta name="description" content="EY-Officeの教育は画一的な集合教育ではなく、御社の開発プランや開発者のスキルに合わせた教育を御社に出向き実施します。">
<meta name="keyword" content="iPhone,アプリ内課金, In App Purchase, ソフトウェア,教育,講習,トレーニング,OJT,Ruby,Ruby on Rails,Rails,Lisp,scheme,アジャイル">
<meta http-equiv="Content-Style-Type" content="text/css">
<meta http-equiv="Content-Script-Type" content="text/javascript">

{% if page.layout == 'blog' %}
<meta property="og:title" content="{{ page.title }}" />
<meta property="og:type" content="blog" />
<meta property="og:url" content="{{ site.production_url }}{{ page.url }}" />
<meta property="og:site_name" content="EY-Office homepage" />
<meta property="fb:app_id" content="133002700083354" />
{% endif %}

<title>企業向けiPhone、Ruby on Rails開発のプライベートレッスンならEY-Office</title>
<link href="/css/base.css" rel="stylesheet" type="text/css">
<link href="/rss" rel="alternate" title="EY-Office RSSフィード" type="application/rss+xml">
<link href="http://feeds.feedburner.com/ey-office" rel="alternate" title="EY-Office ブログ" type="application/atom+xml" />

</head>
Liquid 応用編

下はブログの一覧表示ページの原稿です。 site.posts に全てのブログエントリーが入っていますので、 Liquidテンプレート言語を使い、そこから最新10件を取り出して、タイトル、リンクと記事の先頭160文字を付けた一覧を生成します。

---
layout: default
---
h1. EY-Office ブログ 

<div class="essay">

div(header). EY-Office取締役 吉田裕美が、まだ Ruby on RailsやiPhone開発を行ってない技術者や技術系マネージャー向けに、技術や教育に付いて書いています。

h1. ブログ一覧

{% for post in site.posts limit:10 %}

  <div class="blog_list">
  	<h4><span class="date">{{ post.date | date: "%Y-%m-%d" }}</span> <a href="{{ post.url }}">{{ post.title }}</a></h4>
  	<div>{{ post.content | strip_html | strip_newlines | truncate: 160 }} </div>
  </div>

{% endfor %}
</div>
プラグイン menu_image.rb

Liquidテンプレート言語である程度の処理は書けますが、出来ないこともたくさんあります、そんな時はプラグインを作ります。詳細は https://github.com/mojombo/jekyll/wiki/Plugins に書かれていますが、プラグインには

  1. Generators: 原稿からhtmlに変換するさいにページの自動生成などを行う
  2. Converters: Markdown,Textile に代わるようなマークアップ言語を組み込む
  3. Tags: Liquidテンプレート言語に独自のタグを追加する
  4. Liquid filters: Liquidテンプレート言語に独自のフィルター(関数)を追加する

などが容易されています。プラグインのコードは _plugins ディレクトリーに置くだけで動きます (確認用サーバーは再起動の必要があります)

EY-Officeのホームページでは 以下の画像のように選択されてるタブのマーク画像が変わりますが、その切り替えを行う Tags を書きました。


module Jekyll
  class MenuImageTag < Liquid::Tag
    Syntax = /(.*)\s*,\s*(.*)\s*/o
  
    def initialize(tag_name, markup, tokens)          
      if markup =~ Syntax
        @regexp = Regexp.new($1)
        @url = Liquid::Variable.new($2)
      else
        raise SyntaxError.new("Syntax Error in 'menu_image' - Valid syntax: menu_image [regexp], [url]")
      end
      super      
    end
  
    def render(context)
      if @regexp =~ @url.render(context)
        '<img src="/images/menu_sel.gif" alt="*">'
      else
       	'<img src="/images/menu_unsel.gif" alt="*">'
      end
    end 
  end
end

Liquid::Template.register_tag('menu_image', Jekyll::MenuImageTag)
  • 呼び出し側
<table class="menubar">
  <tr>
    <td>
      {% menu_image ^/index.html, page.url %}
      <a href="/">Home</a>
    </td>
    <td>
      {% menu_image ^/news, page.url %}
      <a href="/news/">ニュース</a>
    </td>
    <td>
      {% menu_image ^/company, page.url %}
      <a href="/company.html">会社案内</a>
    </td>
    <td>
    ....

独自タグの作り方の詳細のドキュメントはありませんので、Liquid テンプレート コード https://github.com/Shopify/liquid を読んで学んで下さい ^^)


6/21日 Jekill を使う人に見つかるように、タイトルを換えました。


今日の結論: Jekyll は便利。ドキュメントが無くてもコードを読めばわかる