読み上げ(say)+字幕入りのLokkaのインストール方法のスクリーンキャストを作ってみました。

なんかウケる。

Lokkaでテーマ毎に多言語化ファイル(ja.ymlとか)を置けるようになるパッチを頂きました。

Commit a8a798ff13f1a1c8594c7eedd0027f0720b95543 to komagata/lokka - GitHub

また、テーマ毎に404ページを設定出来るようにしました。(public/theme/p0t/404.hamlとか)

Commit dbe91a0a4339bef57118f7073f66a2936fe67298 to komagata/lokka - GitHub

Hudson (JJUG CCCにて)

Hudson (JJUG CCCにて)

kohsukeさんのHudsonのスライドに影響受けてLokkaに一回でもcommitしていただいた方を全員コミッタに設定してみました。

Administration for komagata's lokka - GitHub

うぜえ!という方がいらっしゃったら言っていただければすぐ外します。逆にコミッタなりたいという方がいらっしゃったら一行pull requestいただければ簡単です。

Lokkathon #2が開催されました。

場所はFJORDのオフィス。参加者は@komagata, @machida, @kyanny, @junya, @mochizの5人。

努めてモクモクと作業。とてもはかどったし、皆さんとも話せてとても楽しかったです。

僕はGithubのIssuesを整理したり、Pull Requestを処理したり、バグを潰したりしていました。@machidaさんはデザイン系のIssueをやってくれました。@kyannyさんはAWS Elastic BeanstalkでLokkaを動かそうという作業。@mochizさんは会社のブログをLokkaにしようという作業。そして@junyaさんはLokkaにrspec2によるテストの環境をコミットしてくれました。

何か発表する勉強会や交流する懇親会もいいけどひたすらコードを書くHackathonも良いですね。皆さんのお陰で色んな方位に一気にLokkaの作業が進んだ気がします。ありがとうございました。

ゆるい会なので月1ぐらいでやっていきたいなと思います。

Lokkathon #2 - Lokka

日時:02月27日 10:00 - 19:00
参加費:無料
開催場所:FJORD, LLC
東京都渋谷区本町1−36−11 ドエルヤマト203

Lokkaの本体、テーマ、プラグインをもくもくと開発するイベントです。

最低でも@komagataはいて作業しています。

遅刻早退自由です。

飲み物食べ物持ち込み自由です。

同じrouteを2回定義する件。

routesも要はRegexpとブロックの配列。でも最初に定義した方が呼ばれるって何か変。こういうものって後に追加した方が呼ばれる設計にする方が自然な気がする。

そこでもしかして同じroutesとか関係なくて、単にファイル内で上から下に書いてく時の優先順位がそのまんまこの設計に反映されてる的な感じなんじゃないかと思ってpassしてみた。

# public/plugin/lokka-unk/lib/lokka/unk.rb:
module Lokka
  module Unk
    def self.registered(app)
      app.get '/' do
        puts 'unk'
        pass
      end
    end
  end
end
% bundle exec ruby lokka.rb
unk
localhost - - [17/Feb/2011:10:41:33 JST] "GET / HTTP/1.1" 200 38183
- -> /

普通にページは表示されつつ、標準出力にunk。予想通りだ。これは擬似beforeみたいにも使えそう。(普通にbefore '/' do ... endした方が良いが。)

sinatraはルールがシンプルだから自由度が高いなあ。

何だか感慨深い。Java(僕のJava知識はJ2SE1.4で止まってる)とかその他の大きめなフレームワークだとChain-of-responsibilityパターンとかいってFilterChainみたいな感じで実装すると思うんだよね。こういうの。

sinatraはちっちゃいからRegexpとブロックのオブジェクトを配列にもってるから単にナメればいいでしょ?みたいな雰囲気。

Filterクラスを継承したクラスを作るとか面倒。Objective-Cだとブロック対応してない環境のためにワザワザdelegate作るのでヘッダも必要だしとか・・・だるいよなあ(ただの愚痴です・・・)

Lokkaのデータ構造についてざっくりとした図。クラス図もER図も厳密過ぎちゃうので何となくの図です。

  • Post(投稿)
    • いわゆる普通のブログの投稿。
  • Page(ページ)
    • ブログの投稿の様に時系列に並べたりしないもの。(aboutとかprofileとかfaqとか) 
  • Entry(エントリー)
    • PostとPageのこと。
  • Category(カテゴリー)
    • エントリーをツリー状に分類するためのもの。親カテゴリーの概念が有る。1エントリーに複数カテゴリーはつかない。
  • Tag(タグ)
    • エントリーをフラットな構造に分類するもの。1エントリーに複数つけられる。 
  • Comment(コメント)
    • Entryにはコメントが付けられます。
  • User(ユーザー)
    • その名の通り。
  • Site(サイト)
    • サイト自体の情報。タイトルとかテーマとか。
  • Option(オプション)
    • 必須ではないサイトの情報。プラグインなどから勝手に項目を増やせる。
  • Snippet(スニペット)
    • テンプレートの切れ端。URLは持っていない。

これらは全て共通のAPIを持っています。(DataMapper)

*あとで書く* (datamapper.orgを見て・・・)

Entry(PostやPage)はCommentやCategoryやTagやUserと相互に紐づいています。

> Post('about').category.name
mac
> Comment(1).entry.user.name
komagata

分かりにくい部分

PostとPageはEntryのサブクラス。所謂単一テーブル継承ですが持っている機能が同じです。

# entry.rb
class Entry
  ...
end

class Post < Entry; end
class Page < Entry; end

「おやおやこれはおかしいぞ、機能が同じならなんで特化するんだい?」

「名前が違います。」

今後特化した機能ができるかもね!要はLokkaの"ブログ"の部分がPostで"CMS"の部分がPageです。

(WordPressのカスタムタクソノミーはキモイので同じの作るとしてもclass Foo < Entry; endを動的に増やすとかで対応しようと思っています。)

テーマ作成者にとっては結構違います。Postはそのテンプレートに合わせたPostをLokkaがあらかじめテンプレートに渡してくれます。Pageの方はLokkaは何もしてくれないので自分で取りに行かなければいけません。

# entries.erb
<% @posts.each do |post| %>
  <%= post.title %>
<% end %>
# entry.erb
<%= @post.title %>

テンプレートに応じたPostが@postsや@postに最初から入っています。これは下記と同じ意味です。

# entries.erb
<% @posts = Post.recent(10) %>
<% @posts.each do |post| %>
  <%= post.title %>
<% end %>
# entry.erb
<% @post = Post.get_by_id_or_slug(params[:id_or_slug])
<%= @post.title %>

@postが最初から設定されてると上記のように書かなくて済むから便利!

何故同じrouteを2回定義したときの動作が気になったかというと、@miminashiさんのtweetが気になったからです。

Twitter / @miminashi: @komagata プラグインに書いたdoブロックの ...

Lokkaではまずプラグインが読み込まれるのでこの動きは好都合。

# public/plugin/lokka-unk/lib/lokka/unk.rb:
module Lokka
  module Unk
    def self.registered(app)
      app.get '/' do
        'unk'
      end
    end
  end
end
% curl http://localhost:9646
unk

プラグインから簡単にトップページを横取りできた。これはいいフリーダム。

# public/plugin/lokka-unk/lib/lokka/shit.rb:
module Lokka
  module Shit
    def self.registered(app)
      app.get %r{^/([0-9a-zA-Z-]+)$} do |slug|
        slug
      end
    end
  end
end
% curl http://localhost:9646/1
1
% curl http://localhost:9646/hoge
hoge

個別ページはこんな感じ。選ばれない方のメソッドは単に実行されないので副作用はありません。

Mac版Lokkaの始め方。

前回最低限のテーマの作り方を紹介しました。今回は無くてもいいけど使うと便利なテンプレートタイプについて紹介します。

Lokkaにはデフォルトのentry, entries以外に様々なテンプレートタイプがあります。テンプレートは一覧、個別、その他のどれかに分類されます。

テンプレートタイプ

一覧

  • index --- トップページのテンプレート
  • category --- カテゴリー別の一覧ページのテンプレート
  • tag --- タグ別の一覧ページのテンプレート
  • yearly --- 年別の一覧ページのテンプレート
  • monthly --- 月別の一覧ページのテンプレート
  • search --- 検索結果の一覧ページのテンプレート
  • entries --- 一覧ページのテンプレート。上記のテンプレートが無い場合に使われる。

個別

  • post --- 投稿(Post)の個別ページのテンプレート
  • page --- ページ(Page)の個別ページのテンプレート
  • entry --- 個別ページのテンプレート

その他

  • partial --- テンプレートの一部分を共有するテンプレート
  • layout --- テンプレートの外枠を共有するテンプレート

一覧テンプレート

一覧はentries、個別はentryというテンプレートがありますが、例えば一覧で"検索結果だけに必要なもの"があった場合、entriesの中がごちゃごちゃしてしまうのでsearchという名前でテンプレートを作っておくと、検索結果の場合はそちらが優先して使われます。

個別テンプレート

同じようにentryとpostというテンプレートがあった場合投稿(Post)の場合はpostが優先的に表示されます。投稿とそれ以外で別の内容にしたい時に便利です。

どのテンプレートが選ばれるかはURLで決まります。実際には厳密なルールがありますが長くなるので代表的な例を紹介します。

  • index --- /
  • category --- /category/foo/
  • tag --- /tag/foo/
  • yearly --- /2011/
  • monthly --- /2011/01/
  • search --- /search/foo/
  • post --- /1
  • page --- /2

(postやpageやcategoryはIDの他にスラッグと呼ばれる自由なURLを持つことができます。そちらでもアクセスすることも可能です。)

上記以外に特殊なテンプレートタイプが存在します。それがpartialとlayoutです。

partialテンプレート

partialは複数のテンプレートで共通の部分等を別ファイルとして作成して共有するためのテンプレートです。好きな名前で作成することができます。

例えば、Copyright部分をpartialテンプレートとして下記のように作成し、別のテンプレートから読み込む事ができます。

copyright.erb:

<p>Copyright FJORD, LLC</p>

entries.erb:

(省略)
<%= partial 'copyright' %>

entry.erb:

(省略)
<%= partial 'copyright' %>

同じ内容が複数のテンプレートで出てくる場合にpartialを使うと楽でしょう。

layoutテンプレート

もう一つのlayoutテンプレートはpartialとは逆に、テンプレートの一部分を共有するのではなく、外枠の殆どを共有するイメージです。

layout.erb:

<h1 id="header">Title</h1>
<%= yield %>
<div id="footer">Powered by Lokka</div>

entry.erb:

<h2>Post Title 1</h2>
<div class="body">body ...</div>

yieldの部分にentryやentriesのテンプレートの結果が全部入るイメージです。layoutテンプレートはWordPressなどには無い機能なので多少取っ付きづらいですが、テンプレートの大部分を共有できる非常に便利な機能で、上手く使うとテーマコーディングが大幅に楽になります。数多くのフレームワークに採用されている機能なので是非とも活用してみてください。