2012年11月24日土曜日

入力フォームの設定化

現在開発しているプロジェクトでは、入力フォームの設定を外部化している。

例えばhamlで入力フォームを書くと大体以下のようになるはずだ。
  = f.text_field :name, :class => "Name"

  = f.text_field :price, :class => "Price"
  = f.date_select :created_on

こう書く代わりに、hamlには
  - input :name
  - input :price
  - input :created_on
とだけ記述するようにしておき、

別ファイルのCSVに
name,text
price,money
created_on,calendar
のように書く。この組み合わせによって入力フォームが生成される。
実際には CSV には 他にもタグの属性を追記できたりするが、そういう細かい話はおいておく。

ここで大事なことは haml はあくまでも要素のレイアウト(配置)を定義するファイルであり、個々のファイルがどのような見た目、動きになるか、というのはCSVで管理する、ということだ。また、アプリケーション共通で担保すべき動きは helper に記述され、CSVで記述されるのはそのフォーム固有の設定のみとなる。

Struts の時代に戻ったのか、と思ってしまうかもしれない。このやり方が理想的なやり方だと主張するつもりは無いが、ある程度の旨みは感じている。もともと以下のようなことを考えてこの仕組みに決めた。大体目的は達成できている。
  • haml は出来る限り構造を捉えやすい状態に保ちたい。入力フォームの詳細が入ってくるのは好ましくない。erb ではどうでもいい html タグの海の中に入力フォームタグが点在している状況で、タグの親子関係がどうなっているのか調べるのが意外と大変だった。(特に一画面では収まらないような div など)
  • text_field などのhtmlタグにほぼ対応した"物理"タグ生成メソッドはできる限り使わずに、もっと高機能な"論理"タグを出力するhelperメソッドを定義して使うようにしたい。例えば日付の入力フォームはアプリ全体を通して同じ見た目、動きをするのが自然である。また、datepicker などの機能も何も考えずに設定されている状態にしたい。したがって text_field を直接呼び出すのではなく calendar というメソッドを作ってこれのみ使うようにする。
  • フォームの動きを修正するという作業と、フォームのレイアウトを修正するという作業が同時に発生することはない。したがって両者は分離されてそれぞれコンパクトに表現されている方が好ましい。
  • 上記のような高機能な論理タグを定義することで、設定ファイルも簡素化できる。物理タグを使っていたのでは設定ファイルも煩雑になって旨みが薄れる。
  • フォームの動きに関する情報が設定ファイルにコンパクトにまとまっているため、フォームの動きを修正するという作業が高速に行える。過去erbに物理タグを直接書いていた時代は膨大なタグの海から修正箇所をエディタの検索で探しだすという作業に神経をすり減らしていた。構造を捉えることの難しいファイルの修正は絶えずウォーリーを探し続けるようなもので、ただただ疲れる。
  • レイアウトに関する情報は haml にまとまっているので、配置の変更などもスムーズに行える。<tr> から </tr> まで範囲指定でカットして、目的の tr の挿入位置をエディタの検索で探しだして。。。という事がなくなる。html を中途半端にコピーしてしまって崩れるということも起こりづらい。
  • 各パーツの標準的な動きが論理タグとして helper にまとまっているため、カレンダーの動きが使いづらい、という場合に一箇所を修正すれば全体の動きを変えることができる。ユーザにとってフォームの動きが場所によって違うというのは結構なストレスになるのでこの点はとても重要だった。
以上。