Jekyll 2.0 の新機能を触ってみた

Jekyll 2.0 が正式リリースされたので触ってみた。特に気になった機能3つについてざっくりと。以下 2.0.2 で確認。

  1. Collections
  2. Sass/SCSS と CoffeeScript サポート
  3. 追加フィルター where/group_by

Collections

従来の postpage に加え、文書タイプをユーザが定義できるようになった。例として clip という文書を定義してみる。

_config.yml

collections:
  clip:
    output: true
    example: This is an example!!

_config.yml で設定したデータは site.collections.clip から、YAML front-matterの情報は従来通り page から利用できる。

_clip/new-clip.md

---
title: 今日のクリップ
date: 2014-05-07 20:00
---

## {{ page.title }}({{ page.date }})

* [Jekyll turns 2.0.0](http://jekyllrb.com/news/2014/05/06/jekyll-turns-2-0-0/)
* {{ site.collections.clip.example }}

関係するファイルの部分的なツリー。

jekyll_project
├── _clip
│   └── new-clip.md
└── _config.yml

この例では _config.ymloutput: true と設定したので _site/clip/new-clip.html として出力される。

output: false(デフォルト)の場合、ページは生成されない。他のページの部品として使うことを想定しているのだろう。複数の著者がいるサイトで各著者の紹介文を Collection として作っておき、ポストのメタデータで対応させて取り込むようなケースなど。

なお Collections は実験的機能で、今後 API 変更の可能性があるそうなので注意。

参照 http://jekyllrb.com/docs/collections/

Sass/SCSS サポート

Sass/SCSS のビルドがサポートされた。例えば css/main.scss というファイルを作ると jekyll build の際に _site/css/main.css に自動変換される。ただし *.scss には空の YAML front-matter (ハイフン*3を2行)を入れる必要がある。

今のところ通常ディレクトリでは *.sass (インデント記法で書けるもの)が CSSレンダリングされない(そのままコピーされてしまう。後述の _sass/ 配下では使える)。

css/main.scss

---
---

body {
  background: hsla(0, 50%, 50%, 1);
}

これとは別に _sass/part.sass を作成すると、さきほどの main.scss からインポートできるようになる。こちらに ハイフンのヘッダを書くとエラーになる

_sass/part.sass

p
  color: red

css/main.scss

---
---

@import "part"

body {
  background: hsla(0, 50%, 50%, 1);
}

_config.yml で sass オプションを指定できる。 sass_dir でインポート用のファイルを置くディレクトリ名を指定(デフォルトは _sass)、style で出力スタイル指定など。

sass:
  sass_dir: _your_sass_dir
  style: compressed

関係するファイルの部分的なツリー。

jekyll_project
├── _sass
│   └── part.sass
└── css
    └── main.scss

参照 http://jekyllrb.com/docs/assets/

CoffeeScript サポート

CoffeeScript のビルドもサポートされた。こちらもハイフンのヘッダを入れる必要がある。

js/main.coffee

---
---

main = ->
  console.log 'ready.'

main()

Liquid フィルター wheregroup_by

Liquid 出力タグ(Output tags)のフィルターとして wheregroup_by が追加された。site を Root とするツリーオブジェクトのメンバーをフィルタするもの。

まず where から。例えば {{ site.posts | where:"author":"cu39" }} とすると、YAML front-matter に author: cu39 と書いてあるポストだけを抽出できる。

ただしこの例は Jekyll::Post オブジェクトの配列が返ってくることになる。これを自前のフィルタでさらに加工する。

_plugins/my_filter.rb

module Jekyll
  module MyFilter
    def list_titles(posts)
      posts.map do |post|
        %(<li><a href="#{post.url}">#{post.title}</a></li>\n)
      end
    end
  end
end

Liquid::Template.register_filter(Jekyll::MyFilter)

そして、特定の著者の記事だけを並べるページ cu39.html を用意したりして

<h3>cu39 が書いた記事</h3>
<ul>
{{ site.posts | where:"author":"cu39" | list_titles }}
</ul>

みたいな使い方ができそう。

group_by のほうは、{{ site.posts | group_by:"author" }} とすると以下のような構造が返ってくる。

[
  { "author" => "cu39", "items" => [...] },
  { "author" => "someone", "items" => [...] }
]

こちらは1枚のページに著者ごとにポストを並べるような用途に使えそう。

Liquid をあまり使いこんでないので、もっといい使いどころがあったら教えてください。

参照 http://jekyllrb.com/docs/templates/

Webアプリのモックアップ作業土台を作る その3 Sass Source Map

その1その2 Sprockets の続きです。が、今回の作業は その1 の途中からブランチしてます。

Google Chrome の Dev Tools は Sass/SCSS の Source Map に対応しているので利用できるようにしてみます。が、Source Map は仕様も実装も流動的な状態で、環境によって動作しない可能性も大ありなので、あくまで参考まで。

リポジトリ上では Sprockets も Bootstrap も Compass も導入する前の段階からブランチを生やしました。

新仕様と旧仕様

CSS リクエストへのレスポンスでブラウザに Source Map の位置(パス)を知らせる必要があり、その方法は2種類あります。

  1. レスポンスの HTTP ヘッダで渡す
  2. ボディ内のコメントで渡す
続きを読む

Webアプリのモックアップ作業土台を作る その2 Sprockets

前回のつづき。

前回作った作業台に Sprockets を導入して assets 提供を分離します。といっても Sprockets 使っていくかどうか自分でも確信持ててないのでリポジトリではブランチにしておきました。

Sprockets を導入するメリットとしては、このままデプロイするケースを視野に入れたときに圧縮機能を追加しやすかったりプリコンパイルできたりするところでしょうか(どちらも今回はやってません)。

というわけで、まずは Gemfilesprockets 関連の gem を追加して bundle

gem 'sprockets'
gem 'sprockets-helpers'
gem 'sprockets-sass'
続きを読む

Webアプリのモックアップ作業土台を作る その1

Slim, Sass/SCSS, CoffeeScript が使えて Livereload してくれるフロント周辺の作業環境がほしいと思いながらも自分にしっくりくる構成ができなかったんですが、最近 rack-livereload を見つけてピースが埋まった感じがしたのでまとめます。

記事を書くにあたり naoya さんのひな型に大いに影響されてますが、ここでは npm でインストールするのは bower だけにして基本的には Sinatra と Guard に任せています。

Sinatra, Slim, Sass, CoffeeScript

土台の土台としてシンプルな Sinatra アプリから。Gemfile を書いて bundle

Gemfile

source 'https://rubygems.org'

gem 'sinatra'
gem 'sinatra-contrib'
gem 'sass'
gem 'slim'
gem 'coffee-script'

group :develoopment do
  gem 'shotgun'
  gem 'thin'
end

workbench.rb

require 'sinatra/base'
require 'sinatra/reloader'
require 'slim'
require 'sass'
require 'coffee-script'

class Workbench < Sinatra::Base
  configure :development do
    register Sinatra::Reloader
  end

  get '/' do
    @title = 'Index'
    slim :index
  end

  get '/css/application.css' do
    sass :application
  end

  get '/js/application.js' do
    coffee :application
  end
end

views/layout.slim

doctype html
html
  head
    title= @title + ' | Site Workbench'
    link href="/css/application.css" rel="stylesheet"
  body
    == yield
    script src="/js/application.js"

views/index.slim

h1 Workbench
p Workbench for my site.

views/application.sass

body
  background: hsl(0, 0%, 90%)

views/application.coffee

() ->
  'Hoge'

config.ru

require 'bundler'
Bundler.setup
require File.expand_path(File.join('..','workbench'), __FILE__)
run Workbench

これで bundle exec shotgun --server=thin --port=3000 するとサーバーが立って、とりあえずプレビューできます。コマンド名が気持ちいい shotgun

Guard, guard-livereload, rack-livereload

Livereload 環境にするため guard, guard-livereload, rack-livereload を導入。rack-livereload があればブラウザ拡張は必要ありません。

続きを読む

CentOS 5.7 + Passenger

CentOS 5.7 に Passenger を入れて Rack アプリを動かしたメモ。

開発元が用意するリポジトリから mod_passenger と rubygem-passenger を入れる。

参考:Phusion Passenger native packages for RedHat/Fedora/CentOS – Phusion Corporate Blog

# rpm -Uvh http://passenger.stealthymonkeys.com/rhel/5/passenger-release.noarch.rpm
# yum install mod_passenger rubygem-passenger
# rpm -qa \*passenger                  
mod_passenger-3.0.11-9.el5.centos
rubygem-passenger-3.0.11-9.el5.centos

Apache モジュールをインストール。

# passenger-install-apache2-module

手元の環境ではここで curl-devel と ruby-devel が足りないよと言われたので、手動で入れてやりなおし。

# yum install curl-devel.x86_64 ruby-devel.x86_64
# passenger-install-apache2-module

途中で表示されたバーチャルホストの設定例をメモ( /etc/httpd/conf.d/passenger.conf 内でも確認できる)。

<VirtualHost *:80>
  ServerName www.yourhost.com
  DocumentRoot /somewhere/public   # <-- be sure to point to 'public'!
  <Directory /somewhere/public>
    AllowOverride all              # <-- relax Apache security settings
    Options -MultiViews            # <-- MultiViews must be turned off
  </Directory>
</VirtualHost>

どうやら以下のようなディレクトリ構成にすると勝手に動いてくれるらしい。

参考:PassengerでRackアプリを動かす - As Sloth As Possible

/path/to/example.jp/rackhello/
    +- hello.rb
    +- config.ru
    +- public/     <- ここを DocumentRoot にする。空でもOK。

vhost を設定する前に Hello World を用意。

参考:Route 477 - Rack日本語リファレンス

$ mkdir -pv /path/to/example.jp/rackhello/public
$ vi /path/to/example.jp/rackhello/hello.rb
require 'rubygems'
require 'rack'
class HelloApp
  def call(env)
    [200, {"Content-Type" => "text/plain"}, ["Hello, Rack"]]
  end
end
$ vi /path/to/example.jp/rackhello/config.ru
require './hello.rb'

run HelloApp.new

Apache を設定。

$ su -
# vi /etc/httpd/conf.d/vhost.jp.example.conf
<VirtualHost *:80>

ServerName example.jp
DocumentRoot /path/to/example.jp/rackhello/public

ErrorLog logs/example.jp-error_log
CustomLog logs/example.jp-access_log common

ServerAdmin webmaster@example.jp

</VirtualHost>
# /etc/init.d/httpd configtest
Syntax OK
# /etc/init.d/httpd reload
Reloading httpd:                   [  OK  ]

楽だー。