岩本隆史の日記帳(アーカイブ)

はてなダイアリーのサービス終了をうけて移行したものです。更新はしません。

Pinto公開に向けて #6 ― テンプレートにuriメソッドを追加した

あらすじ

いじり始めたばかりのRubyで、Pintoというソーシャルブックマークサービスを作っている最中です。前回は、ビュー周りを実装しました。今回は、gettextを触る予定でしたが、後回しにして(えー)、テンプレートにuriメソッドを追加しました。その際に考えたことを書きます。

uriメソッドとは?

RailsActionView::Helpers::UrlHelper.url_forのようなURI構築メソッドがテンプレートから呼び出せると便利だと思い、実装したものです。

<%== uri('index', 'lang' => 'en') %>

第1引数はコントローラ名、第2引数はパラメータハッシュ(後述)です。テンプレートの全体はview/top.erbをご参照ください。

ヘルパーモジュールの作成

独自のコンテキストオブジェクトを渡すことでテンプレートからのメソッド呼び出しを実装していましたが、なんだか格好悪いので、ヘルパーモジュール化しました。

Pinto::View::XHTML.evaluateで、Erubis::Contextにextendさせています。

def evaluate(param)
  context = Erubis::Context.new(param)
  context.extend Pinto::View::Helper::HTML
  context.extend Pinto::View::Helper::URI
  super context
end

こういうことが簡単にできるのがうれしいですねー。Ruby++

なお、前回まで Pinto::View::XHTML は Pinto::View::Engine::XHTML でしたが、階層が深すぎる気がしたので、1つ上げました。

uriメソッドの中身

uriメソッドの中では、Addressable::URI.expand_templateを呼び出しています。

def uri(controller, param)
  uri_templates = Pinto::Config.load('uri_templates')
  return Addressable::URI.expand_template(uri_templates[controller],
                                          param,
                                          Pinto::URI::ExpandProcessor)
end

第1引数はURIテンプレート、第2引数はさきほどのパラメータハッシュ、第3引数はexpand用のプロセッサです。プロセッサのtransformメソッドによって、langの頭にドットが付加されます。

def self.transform(name, value)
  return '.' + value if name == 'lang'
  return value
end

実例に即していうと

http://pinto.jp/index{lang}

というテンプレートURI

{'lang' => 'en'}

というハッシュをぶつけて

http://pinto.jp/index.en

というURIを得ているわけです。

configファイルを外出しに

ちなみに、Pinto::View::Helper::URIからしれっとPinto::Config.loadを呼び出していますが、URIテンプレートの定義を複数の箇所(もう1箇所はPinto::Dispatcher)に書くのはDRYじゃないので、定義ファイル+モジュール化しました。

Pinto::Config.load で定義ファイル(config/config.yml)を読み込んでいます。YAMLを選んだのは、特にこだわりがあるわけではなく、なんとなくです(えー)。

次のアクション

  • view/top.erb の変更(選択可能な言語をベタ書きせずにループする)
  • view/index.erb を簡単に書き、gettextを使って多言語対応する