レヴュー: MasterView - Part 3 MasterViewの欠点

MasterViewは素晴らしいプラグインなのですが、イマイチ広まらない原因と思われることを挙げてみます。

テストへの対応が不十分

functionalテストの中には当然テンプレートをレンダリングするものもありますが、そういうテストを実行したとき、テンプレートがMasterViewのXHTMLだとActionController::MissingTemplateというエラーになります。このエラーを回避するには、MasterView付属のrakeタスクを使って、XHTMLファイルからERBのテンプレートを生成する必要があります。テンプレートが多くなってくるとこのタスクに時間がかかります(全てのXHTMLファイルをパースするため)。これにはちょっとイラつきます。

mv:rebuild_allがテンプレートを破壊する

前回のMasterViewにおけるテンプレートの再利用のしくみの中で、mv:rebuild_allでテンプレートをコピーすることを説明しました。しかし、そのコピー処理が未熟で、様々な破壊をもたらします。たとえば:

  • DOCTYPE宣言が消える
  • 属性値を囲んでいたシングルクォートがダブルクォートになる(値の中にダブルクォートがあったら一巻の終わり)
  • mv:import_renderで指定したコレクションの値が保持されない。mv:gen_partialで指定したコレクションに置き換わってしまう

最後の項目がわかりにくいと思うので説明します。パーシャルを使ってコレクションをレンダリングする場合ですが、次のような定義になっていたとします。

<li mv:gen_partial=":partial => 'articles/article', :collection => @foo_articles">
  <span mv:content="article.name">Article Name</span>
</li>

これを別の場所で次のように使うとします。

<li mv:import_render=":partial => 'articles/article', :collection => @bar_articles">
</li>

上では@foo_articlesを使い、下では@bar_articlesを使っています。

これでmv:rebuild_allすれば、<span>の部分がコピーされて下のようになる気がしますが

<li mv:import_render=":partial => 'articles/article', :collection => @bar_articles">
  <span mv:content="article.name">Article Name</span>
</li>

実際には@bar_articlesではなく@foo_articlesになってしまいます。

<li mv:import_render=":partial => 'articles/article', :collection => @foo_articles">
  <span mv:content="article.name">Article Name</span>
</li>

このように完全にテンプレートが破壊されてしまうため、mv:rebuild_allは使用できません。

gettextとの相性が悪い

ご存知の通り、gettextで置換したい文字列は_()で囲みますが、この_()Rubyで評価される必要がありますよね?ERBでは評価して欲しいものをどこでも<%= %>で囲めば済みますが、XHTMLだと評価してもらえる場所は限られます。例えば

<p><%= _('Hello') %></p>

<p mv:content="_('Hello')">Hello</p>

と書かなければなりません。実は<%= %>と互換の{{{= }}}という記法があるのですが、

<p>{{{= _('Hello') }}}</p>

と書けばブラウザには

{{{= _('Hello') }}}

と表示されるので、WYSIWYGではなくなってしまいます。

MasterViewを使う意味はあるのか?

以上のように優れた機能を持ちながら完成度が”うーん”なMasterViewですが、使う価値はあるのでしょうか。私は使っていますし、これからも使うつもりです。理由はといえば、”ブラウザで見られるテンプレートが好きだから”としか言いようがありません。3エントリも使ってしょうもないオチですいません。気が向いたらパッチを書きます。