Waves チュートリアル パート2

http://www.rubywaves.com/tutorial-2
パート1の翻訳はこちら
【2008-03-18更新】id:t-wadaさんのご指摘により誤訳を修正しました。

        • -

次にビューを作り,ブログエントリのリストを表示します。まずエントリ関連のテンプレートのディレクトリを作ります。unixならこんな感じ。

~/blog $ mkdir templates/entry

次に template/entry に list.mab というファイルを作ります。"mab" 拡張子は Markaby テンプレート用です(Markaby は ruby ライクな記法がそのまま使えるテンプレートエンジン)。Waves は Markaby と Erubis をサポートしています(そして追加も簡単です)が,ここでは Markaby を使います。

layout :default, :title => 'Blog Entries' do
  h1 'My Blog'
  @entries.each do |entry|
    view :entry, :summary, :entry => entry
  end
end

ここで使っているテクニックのポイントは以下の通り。

  • Markaby テンプレートは Ruby の文法を使います。実際 Ruby そのものです。メソッドは HTML タグに関連づけられています。ブロックタグはブロックを伴うメソッドです。詳しくはこちら
  • layout ヘルパーを使っています。これはコンテンツを "Blog Entries" というタイトルの「デフォルトの」レイアウトに埋め込みます。Waves では,レイアウトを(Railsのような)コントローラではなくテンプレートの中で指定します。
  • entriesインスタンス変数は自動的に定義されます。なぜならリストビューを使っているからです。あとでもう少し詳しく説明します。
  • view ヘルパーで別のビューを呼び出しています。これは再利用できるビューの作り方を示しています。再利用可能なビューが必要なら,このようにリファクタリングして view ヘルパーを使うだけです。表示すべきオブジェクトを格納している entry というインスタンス変数を渡します。

次に呼び出しているビューを定義しなければなりません。summary.mab を templates/entry に作ります。

h2 do
  a @entry.title, :href => "/entry/#{@entry.name}" 
end
textile @entry.summary
a 'Read more ...', :href => "/entry/#{@entry.name}" 

ここで内蔵の textile フォーマットを使いました。残りの部分は自明ですね。いくつか疑問もあるかもしれませんが,先に進んでアプリを起動し,新しいビューを見てみましょう。

~/blog $ waves-server
I, [2008-01-28T11:01:19.945459 #3755]  INFO -- : ** Waves Server Starting ...
I, [2008-01-28T11:01:20.059007 #3755]  INFO -- : ** Waves Server Running on 127.0.0.1:3000
I, [2008-01-28T11:01:20.059482 #3755]  INFO -- : Server started in 30 ms.

ブラウザを開き http://localhost:3000/entries にアクセスしてください。以下のような画面が見られるはずです。
http://www.rubywaves.com/images/our-first-view.png?size=small

エントリ全体を見るビューを追加します。これはエントリサマリとよく似ています。show.mabファイルを作成しましょう。

layout :default, :title => @entry.title do
  h1 @entry.title
  textile @entry.content
end

"Read more ..." をクリックして,どのように見えるか確認してください。
http://www.rubywaves.com/images/show-entry-view.png?size=small

できました! ここまでコントローラやモデルのコードを1行も書いていないことは強調しておいてもいいでしょう。いくつかの決まり事を守れば,Waves は我々が何をしたいのかを推論することができたのです。

  • 何かのリストの URL は /entries というようになる
  • 特定のインスタンスの URL は /entry/first-entry というようになる

こうした決まり事は簡単にカスタマイズできますが,ここでももう少し先に進みましょう。list テンプレートの先頭に簡単なフォームを追加します。こんな感じです。

layout :default, :title => 'Blog Entries' do
  h1 'My Blog'
  form :action => '/entries', :method => 'post' do
    label 'Name'
    input :type => :text, :name => 'entry.name'
    input :type => :submit, :value => 'Add'
  end
  @entries.each do |entry|
    view :entry, :summary, :entry => entry
  end
end

ここでは REST スタイルのインターフェースに従い,新しいエントリを追加する URL と,エントリ全体のリストを取得する URL を同じものにしています。違いはリクエストのメソッドだけです。エントリを追加するには POST を使います。これは /entries に新しいリソースを作るということですが,これがまさに行われることです。

作ったエントリを編集するための別のビューが必要です。簡単です。editor.mab を追加します。

layout :default, :title => 'Edit Entry' do
  form :action => "/entry/#{@entry.name}/", :method => 'POST' do
    label 'Title'; br
    input :type => :text, :value => @entry.title, :name => 'entry.title'; br
    label 'Summary'; br
    textarea @entry.summary, :name => 'entry.summary', :rows => 10, :cols => 80; br
    label 'Content'; br
    textarea @entry.content, :name => 'entry.content', :rows => 20, :cols => 80; br
    input :type => :submit, :value => 'Save'
  end
end

/entries ページのフォームを使ってエントリを追加し,編集してみましょう。この新しいエントリを 'second-entry' とします。
http://www.rubywaves.com/images/second-entry.png?size=medium

Save をクリックすると,新しいエントリがブラウザで見られるはずです。

今のところモデルもコントローラも作る必要がありません。入門パート3では,中で何が起きているかを見ることにします。