SlideShare uma empresa Scribd logo
1 de 62
Baixar para ler offline
RubyKaigi 2010




HTMLデザインを崩さない
テンプレートエンジンの作り方
                                                      makoto kuwata
                                          http://www.kuwata-lab.com/




     English ver: http://slidesha.re/a3s2ZZ

     copyright(c) 2010 kuwata-lab.com all rights reserved.
                                                                              1
はじめに

目的
       ✤   テンプレートエンジン利用者に、正しい
           知識を理解してもらう
       ✤   テンプレートエンジン設計者に、あるべ
           き姿を考えてもらう

動機     ✤   間違った説明が蔓延しており是正したい
       ✤   eRubyは決して理想解ではないことを
           知ってほしい

対象者    ✤   テンプレートエンジンの利用者と設計者


            copyright(c) 2010 kuwata-lab.com all rights reserved.
                                                                    2
お詫び
✤   今日話したかったこと
    ✤   テンプレートのデザインを崩さない方法について
    ✤   テンプレートエンジンの高速化について
    ✤   既存のテンプレートエンジンが抱える問題点について
    ✤   デザインを崩さず、高速で、どの言語でも比較的簡単に
        実装できるテンプレートエンジンの作り方について

✤   30分しかないので最初の項目だけ
    ✤   野心的すぎました、ごめんなさい

               copyright(c) 2010 kuwata-lab.com all rights reserved.
                                                                       3
参考文献
✤   Rubyist Magazine - テンプレートシステム入門
    ✤   http://jp.rubyist.net/magazine/?0024-TemplateSystem
    ✤   http://jp.rubyist.net/magazine/?0024-TemplateSystem2




                      copyright(c) 2010 kuwata-lab.com all rights reserved.
                                                                              4
アジェンダ
✤   基礎知識編
    ✤   ビジネス層とプレゼンテーション層
    ✤   現状の問題点とその原因
    ✤   プレゼンテーションロジック

✤   Kwartz編
    ✤   はじめてのKwartz入門
    ✤   プレゼンテーションパターン


                copyright(c) 2010 kuwata-lab.com all rights reserved.
                                                                        5
基礎知識編:
ビジネス層とプレゼンテーション層




         copyright(c) 2010 kuwata-lab.com all rights reserved.
                                                                 6
ビジネス層とプレゼンテーション層
✤   ビジネス層
    ✤   役割:「何を(what)表示するか?」を決定
    ✤   担当:メインプログラム

✤   プレゼンテーション層
    ✤   役割:「どのように(how)表示するか?」を決定
    ✤   担当:テンプレートファイルおよびエンジン




                copyright(c) 2010 kuwata-lab.com all rights reserved.
                                                                        7
データとロジック
✤   ビジネス層とプレゼンテーション層の両方に、
    データとロジックが存在
             ビジネス層                                   プレゼンテーション層
            (メインプログラム)                                (テンプレートエンジン)

                                                       プレゼンテーション
     データ    ビジネスデータ
                                                                     データ
                                                       プレゼンテーション
     ロジック   ビジネスロジック
                                                                     ロジック

            テンプレートエンジンはここを分離
             copyright(c) 2010 kuwata-lab.com all rights reserved.
                                                                            8
具体例
                                                         ビジネスデータ
✤   営業部員の売上成績から
                                                       ビジネスロジック
✤   上位 20 名を選出し、

✤   奇数行と偶数行で背景色を変えて
                                                                   プレゼンテー
✤   <table> タグで表示する                                                ションロジック

                         プレゼンテー
                         ションデータ


           copyright(c) 2010 kuwata-lab.com all rights reserved.
                                                                             9
よくある間違い(1)

(誤)   ✤   テンプレートエンジンは、ロジックと
          プレゼンテーションを分離する
      ✤   テンプレートエンジンは、ビジネス層
(正)
          とプレゼンテーション層を分離する
          ✤   プレゼンテーション層にもロジックがある




                                               自分も昔は間違ってました…
                copyright(c) 2010 kuwata-lab.com all rights reserved.
                                                                        10
よくある間違い(2)

(誤)   ✤   プレゼンテーション層にはロジックを
          含めるべきではない
      ✤   プレゼンテーション層はプレゼンテー
(正)
          ションロジックを含む
          ✤   「HTMLテンプレートにプレゼンテーション
              ロジックを含めない」ことと、「ビジネス層
              とプレゼンテーション層を分離する」こと
              は、別の話



                copyright(c) 2010 kuwata-lab.com all rights reserved.
                                                                        11
ここまでのまとめ
✤   ビジネス層
    ✤   何を(What)表示するか?
    ✤   メインプログラムが担当

✤   プレゼンテーション層
    ✤   どう(How)表示するか?
    ✤   テンプレートファイルが担当

✤   どちらにもデータとロジックが存在

                copyright(c) 2010 kuwata-lab.com all rights reserved.
                                                                        12
基礎知識編:
現状の問題点とその原因




         copyright(c) 2010 kuwata-lab.com all rights reserved.
                                                                 13
デザイナ泣かせの現状
       ProjectA: Rails
<table>                                                             ProjectC: PHP
<%	 @arr.each	 {	 %>                                         <table>
	 	 ....                                                     <?php	 foreach()	 {	 ?>
<%	 }	 %>                                                    	 	 ....
</table>                                                     <?php	 }	 ?>
                                                             </table>
            ProjectB: JSP
     <table>
     <forEach	 items="">                                         プログラマの都合を
     	 	 ....                                                    デザイナに押し付け
     </forEach>                                                  ているのが現状
     </table>
                 copyright(c) 2010 kuwata-lab.com all rights reserved.
                                                                                       14
共同作業での問題
        テンプレートファイル
        <table>
        <%	 @arr.each	 {	 %>
        	 	 ....
        <%	 }	 %>
        </table>
                       衝突!
                                                          プレゼンテーション
 HTMLを編集                                                  ロジックを編集


 デザイナ                                                              プログラマ

           copyright(c) 2010 kuwata-lab.com all rights reserved.
                                                                           15
問題の原因

✤   テンプレート中にプレ                                       テンプレートファイル
    ゼンテーションロジッ                               <table>
    クを埋め込んでいるこ                               <%	 i	 =	 0	 %>
                                             <%	 @arr.eachx	 do	 |x|	 %>
    とこそが、諸悪の根源
                                             <%	 	 	 i	 +=	 i	 %>
                                             <%	 	 	 c	 =	 i.odd	 ?	 	 %>
                                             <%	 	 	 	 	 	 	 'odd':'even'	 %>
    pure HTML テンプ                            	 	 <tr	 class="<%=c%>">
    レートが望ましい                                 	 	 	 	 <td><%=	 x	 %></td>
                                             	 	 </tr>
                                             <%	 end	 %>
                                             </table>

              copyright(c) 2010 kuwata-lab.com all rights reserved.
                                                                                16
pure HTML テンプレートの利点
              ✤   HTMLデザインが崩れない(表示確認できる)
デザイナ
        for


              ✤   テンプレート言語を学習しなくてよい
              ✤   HTML Validator でチェックできる
              ✤   好きなエディタ (Dreamweaverなど) が使える


                  同時編集による衝突を避けやすい
プログラマ
        for




              ✤


              ✤   空白除去による圧縮(転送量削減)がしやすい
              ✤   ケータイ用などに自動変換しやすい

                       copyright(c) 2010 kuwata-lab.com all rights reserved.
                                                                               17
Matzも悩んだ問題
✤   じゃあプレゼンテーションロジックは
    どこに書けばいいの?

    Matz日記 (2004-08-24)
    http://www.rubyist.net/ matz/20040824.html#p01

      (要約)
      ViewそのものにLogicが必要な場合、
      HTMLテンプレートでは記述できないし、
      どこに所属すべきだろうか?


                   copyright(c) 2010 kuwata-lab.com all rights reserved.
                                                                           18
ここまでのまとめ
✤   テンプレート中にプレゼンテーションロ
    ジックを埋め込むと、問題が多い
✤   pure HTMLテンプレートが望ましい
✤   プレゼンテーションロジックはどこに?




           copyright(c) 2010 kuwata-lab.com all rights reserved.
                                                                   19
基礎知識編:
プレゼンテーションロジック




         copyright(c) 2010 kuwata-lab.com all rights reserved.
                                                                 20
プレゼンテーションロジックをどこに?

A. テンプレートファイル中 (eRuby, JSP, Kid)
  プレゼンテーションロジック
                                                    ビジネスロジック&データ
  +プレゼンテーションデータ


B. メインプログラム中 (Amrita2, XMLC, HTML::Template)
                                                 プレゼンテーションロジック
   プレゼンテーションデータ
                                                 +ビジネスロジック&データ


C. 独立した別ファイル中 (Kwartz, Tapestry, Mayaa)
   プレゼンテーションロジック
                                                    ビジネスロジック&データ
   プレゼンテーションデータ

                                         テンプレート                      メインプログラム
             copyright(c) 2010 kuwata-lab.com all rights reserved.
                                                                                21
A. テンプレートファイル中に記述 (1)

 例: eRuby ファイル (Ruby)
 <table>
 <%	 odd	 =	 false	 %>
 <%	 for	 item	 in	 @list	 %>
 <%	 	 	 odd	 =	 !	 odd
 <%	 	 	 cls	 =	 odd	 ?	 'odd'	 :	 'even'	 %>
 	 	 <tr	 class="<%=	 cls	 %>">
 	 	 	 	 <td><%=h	 item	 %></td>
 	 	 </tr>
                                       •HTMLの中にHTML
 <%	 end	 %>
                                        でないものが混在
 </table>
                                                             →pure HTML でない


                 copyright(c) 2010 kuwata-lab.com all rights reserved.
                                                                              22
A. テンプレートファイル中に記述 (2)

 例: JSP ファイル (Java)
 <table>
 	 <c:forEach	 var="item"	 items="${list}"
 	 	 	 	 	 	 	 	 	 	 	 	 varStatus="loop">
 	 	 <c:set	 var="klass"
 	 	 	 	 	 value="${loop.count%2==0?'odd':'even'}"	 />
 	 	 <tr	 class="${klass}">
 	 	 	 	 <td><c:out	 value="${item}"	 /></td>
 	 	 </tr>
 	 </c:forEach>                •カスタムタグを使おうが、ロジックを
 </table>                       テンプレートファイル中に埋め込んで
                           いるという点ではeRubyと同じ

                copyright(c) 2010 kuwata-lab.com all rights reserved.
                                                                        23
A. テンプレートファイル中に記述 (3)

 例: Kid テンプレートファイル (Python)
 <table>
 	 	 <tr	 py:for="i,	 item	 in	 enumerate(items)"
 	 	 	 	 	 	 class="${i	 %	 2	 and	 'even'	 or	 'odd'}">
 	 	 	 	 <td	 py:content="item">dummy</td>
 	 	 </tr>
 </table>
                          •文書構造と属性を使うことで、
                           HTMLデザインを崩さないよう配慮
                          •ロジックをテンプレートファイル中に
                           埋め込んでいるという点では同じ


                   copyright(c) 2010 kuwata-lab.com all rights reserved.
                                                                           24
A. テンプレートファイル中に記述 (4)
        プレゼンテーション層(=テンプレート)が
利
    ✤

        ビジネス層から分離されている
点   ✤   使い方がわかりやすく、実装も簡単


        pure HTML でない(ことが多い)
欠
    ✤


    ✤   同時編集による衝突が発生しやすい
点   ✤   デザイナがプレゼンテーションロジックを
        誤って変更する可能性がある



            copyright(c) 2010 kuwata-lab.com all rights reserved.
                                                                    25
プレゼンテーションロジックをどこに?

A. テンプレートファイル中 (eRuby, JSP, Kid)
  プレゼンテーションロジック
                                                    ビジネスロジック&データ
  +プレゼンテーションデータ


B. メインプログラム中 (Amrita2, XMLC, HTML::Template)
                                                 プレゼンテーションロジック
   プレゼンテーションデータ
                                                 +ビジネスロジック&データ


C. 独立した別ファイル中 (Kwartz, Tapestry, Mayaa)
   プレゼンテーションロジック
                                                    ビジネスロジック&データ
   プレゼンテーションデータ

                                         テンプレート                      メインプログラム
             copyright(c) 2010 kuwata-lab.com all rights reserved.
                                                                                26
B. メインプログラム中に記述 (1)

 例: Amrita2 テンプレートファイル (Ruby)
 <table>
 	 	 <tr	 id="list"	 class="odd">
 	 	 	 	 <td	 id="item">dummy</td>
 	 	 </tr>
 </table>

            •書き換えたい場所に「目印」を書くだけ
             (Amrita2ならid属性をつけるだけ)
            •テンプレートが pure HTML (ロジック
             を埋め込まないため)



              copyright(c) 2010 kuwata-lab.com all rights reserved.
                                                                      27
B. メインプログラム中に記述 (2)
 例: Amrita2 メインプログラム (Ruby)
 ##	 表示したいビジネスデータ
 list	 =	 [	 'A',	 'B',	 'C'	 ]        •ビジネスデータをプレゼ
 ##	 プレゼンテーションロジック                       ンテーションロジックで
 list2	 =	 [];	 	 odd	 =	 false          加工する必要がある
 for	 x	 in	 list
 	 	 cls	 =	 (odd	 =	 !odd)	 ?	 'odd'	 :	 'even'
 	 	 item2	 =	 a(:class=>cls)	 {	 {:item=>x}	 }
 	 	 list2	 <<	 item2
 end
 context	 =	 {	 :list=>list2	 }
 ##	 テンプレートを読み込んで表示
 tmpl	 =	 Amrita2::TemplateFile.new('ex1.html')
 tmpl.expand(html='',	 context)
 print	 html
                copyright(c) 2010 kuwata-lab.com all rights reserved.
                                                                        28
B. メインプログラム中に記述 (3)
        テンプレートには目印を埋め込むだけ
利
    ✤



        pure HTML テンプレートを実現 (しやすい)
点
    ✤


    ✤   同じファイルを編集しないので衝突しない
    ✤   デザイナによるロジックの誤変更がない

        ビジネス層とプレゼンテーション層が分離で
欠
    ✤


        きてない(*注)
点   ✤   使い方にクセがある(ロジックをデータで表
        現する必要があるため)

             (*注) 工夫次第で回避可能(該当箇所を別クラスにする等)
            copyright(c) 2010 kuwata-lab.com all rights reserved.
                                                                    29
プレゼンテーションロジックをどこに?

A. テンプレートファイル中 (eRuby, JSP, Kid)
  プレゼンテーションロジック
                                                    ビジネスロジック&データ
  +プレゼンテーションデータ


B. メインプログラム中 (Amrita2, XMLC, HTML::Template)
                                                 プレゼンテーションロジック
   プレゼンテーションデータ
                                                 +ビジネスロジック&データ


C. 独立した別ファイル中 (Kwartz, Tapestry, Mayaa)
   プレゼンテーションロジック
                                                    ビジネスロジック&データ
   プレゼンテーションデータ

                                         テンプレート                      メインプログラム
             copyright(c) 2010 kuwata-lab.com all rights reserved.
                                                                                30
C. 独立した別ファイル中に記述 (1)

 例: Kwartz プレゼンテーションデータファイル (Ruby)
 <table>
 	 	 <tr	 id="mark:list"	 class="odd">
 	 	 	 	 <td	 id="mark:item">dummy</td>
 	 	 </tr>
 </table>
           •書き換えたい場所に「目印」を書くだけ
           (Kwartzならid属性をつけるだけ)




            copyright(c) 2010 kuwata-lab.com all rights reserved.
                                                                    31
C. 独立した別ファイル中に記述 (2)

 例: Kwartz プレゼンテーションロジックファイル (Ruby)
 #item	 {	 	 	 	 	 	 	 	 	 	 ##	 id="mark:item"	 は
 	 	 value:	 x;	 	 	 	 	 	 ##	 x	 の値を表示する
 }
 #list	 {	 	 	 	 	 	 	 	 	 	 ##	 id="mark:list"	 は
 	 	 logic:	 {	 	 	 	 	 	 	 ##	 要素全体をループする
 	 	 	 	 for	 x	 in	 @list
 	 	 	 	 	 	 _elem
 	 	 	 	 end
 	 	 }                         •あたかもCSSのようにプレゼンテー
 }                              ションロジックを記述する
                          •プレゼンテーションロジックがメイ
                             ンプログラム中に現れない!
               copyright(c) 2010 kuwata-lab.com all rights reserved.
                                                                       32
CSS
                   (Visual Design)




                           HTML
                         (Document
                         Structure)
 Kwartz                                                            JavaScript
(Presentation                                                           (Client-side
    Logic)                                                                 Logic)


                copyright(c) 2010 kuwata-lab.com all rights reserved.
                                                                                       33
C. 独立した別ファイル中に記述 (3)
    ✤   ビジネス層とプレゼンテーション層がきれい
利       に分離
点   ✤   プレゼンテーションデータ(HTML)とプレ
        ゼンテーションロジックもきれいに分離
    ✤   pure HTML テンプレートを実現
    ✤   編集するファイルが別なので衝突しない
    ✤   デザイナによるロジックの誤変更がない


欠   ✤   ファイル数が増える
点           copyright(c) 2010 kuwata-lab.com all rights reserved.
                                                                    34
大事なことと本当に大事なこと
✤   大事なこと
    ✤   テンプレートが pure HTML であること

✤   本当に大事なこと
    ✤   プレゼンテーションロジックを分離・独立させること
    ✤   (pure HTML はその副産物にすぎない)




                copyright(c) 2010 kuwata-lab.com all rights reserved.
                                                                        35
よくある間違い(1)

(誤)   ✤   テンプレートがpure HTMLなので、
          プレゼンテーション層を分離できてい
          ます!
      ✤   pure HTMLであることと、各層が分
(正)
          離できることは、別個のお話
          ✤   恐らく、HTMLファイル中にロジックが現れ
              ないことを「プレゼンテーション層の分離」
              と勘違いしている



                copyright(c) 2010 kuwata-lab.com all rights reserved.
                                                                        36
よくある間違い(2)

(誤)   ✤   生PHPだとデザイナが変なロジックを
          埋め込む可能性があるので、Smarty
          を導入しました!
      ✤   Smartyではデザイナによる誤変更は防
(正)
          止できない
          ✤   デザイナがプレゼンテーションロジックにア
              クセスできる時点で間違い
          ✤   根本的な解決法は、プレゼンテーションロ
              ジックを分離すること

                copyright(c) 2010 kuwata-lab.com all rights reserved.
                                                                        37
ここまでのまとめ
✤   プレゼンテーションロジックの記述場所
    ✤   テンプレートファイル中(デザイン崩れ、競合が発生)
    ✤   メインプログラム中(分離がいまいち)
    ✤   独立した別ファイル中(いちばん理想的)

✤   pure HTML テンプレートは重要
✤   プレゼンテーションロジックの分離・独立
    はもっと重要

               copyright(c) 2010 kuwata-lab.com all rights reserved.
                                                                       38
Kwartz編:
はじめてのKwartz入門




           copyright(c) 2010 kuwata-lab.com all rights reserved.
                                                                   39
Kwartz 概要
✤   Kwartzとは?
    ✤   プレゼンテーションデータ(HTML)と
        プレゼンテーションロジックを分離できるテンプレー
        トエンジン
    ✤   pure HTML テンプレート
    ✤   Ruby実装とPHP実装を用意
    ✤   http://www.kuwata-lab.com/kwartz/




                     copyright(c) 2010 kuwata-lab.com all rights reserved.
                                                                             40
サンプル: プレゼンテーションデータ

                              書き換えたい箇所に、目印
ex.html                       となるid属性をつける
 <table>
 	 	 <tr	 id="mark:list">
 	 	 	 	 <td	 id="mark:item">Foo</td>
 	 	 </tr>
 	 	 <tr	 id="dummy:d1">
 	 	 	 	 <td>Bar</td>
 	 	 </tr>
 </table>                  「id="dummy:xxx"」は
                                  ダミー要素を表す



                copyright(c) 2010 kuwata-lab.com all rights reserved.
                                                                        41
サンプル: プレゼンテーションロジック

ex.plogic                  id属性ごとにプレゼンテー
 #list	 {                  ションロジックを記述
 	 	 logic:	 {
 	 	 	 	 for	 x	 in	 @list
 	 	 	 	 	 	 _stag	 	 	 	 ##	 開始タグ
 	 	 	 	 	 	 _cont	 	 	 	 ##	 内容
 	 	 	 	 	 	 _etag	 	 	 	 ##	 終了タグ
 	 	 	 	 end
 	 	 }                   <tr>要素を繰り返し
 }
 #item	 {
 	 	 value:	 x;
 }                          <td>要素に値を出力
                copyright(c) 2010 kuwata-lab.com all rights reserved.
                                                                        42
サンプル: コンパイル

eRubyファイルへコンパイル
 $	 kwartz	 -l	 eruby	 -p	 ex.plogic	 ex.html	 >	 ex.rhtml

ex.rhtml (コンパイル結果)
 <table>
 <%	 	 	 	 	 for	 x	 in	 @list	 %>
 	 	 <tr>
 	 	 	 	 <td><%=	 x	 %></td>                        •属性「id="mark:xxx"」は
 	 	 </tr>                                             コンパイル時に削除される
 <%	 	 	 	 	 end	 %>                                   (id="xxx" なら削除されない)
 </table>                                           •「id="dummy:xxx"」は要素
                                                       そのものが削除される
                      copyright(c) 2010 kuwata-lab.com all rights reserved.
                                                                              43
サンプル: メインプログラム

メインプログラム
 ##	 表示したいビジネスデータ
 list	 =	 ['A',	 'B',	 'C']
 context	 =	 {	 :list	 =>	 list	 }

 ##	 テンプレートを読み込んで表示
 require	 'erubis'
 eruby	 =	 Erubis::Eruby.load_file('ex.rhtml')
 html	 =	 eruby.evaluate(context)
 print	 html
                                                       ふつうにeRubyファイ
                                                       ルとして実行するだけ

                   copyright(c) 2010 kuwata-lab.com all rights reserved.
                                                                           44
特長と欠点
✤   特長   ✤   pure HTML テンプレートである
         ✤   実行速度が高速
         ✤   eRuby, PHP, JSP 等もサポート
         ✤   HTML以外でも利用可能


✤   欠点   ✤   コンパイルが面倒(自動化は可能)
         ✤   実行時エラーで報告される行番号がコンパイ
             ル後のものであり、コンパイル前の行番号で
             はない(言語のサポートが必要)

                copyright(c) 2010 kuwata-lab.com all rights reserved.
                                                                        45
応用例(1)

 要素全体を繰り返す                                          内容だけを繰り返す
 #list	 {                                            #list	 {
 	 	 logic:	 {                                       	 	 logic:	 {
 	 	 	 	 for	 item	 in	 @list                        	 	 	 	 _stag
 	 	 	 	 	 	 _stag	 #	 開始タグ                          	 	 	 	 for	 item	 in	 @list
 	 	 	 	 	 	 _cont	 #	 内容                            	 	 	 	 	 	 _cont
 	 	 	 	 	 	 _etag	 #	 終了タグ                          	 	 	 	 end
 	 	 	 	 end                                         	 	 	 	 _etag
 	 	 }                                               	 	 }
 }                                                   }             <dt>と<dd>を繰り
                                                                             返したいときに有用



                     copyright(c) 2010 kuwata-lab.com all rights reserved.
                                                                                         46
応用例(2)

 条件を満たすときだけ出力                                       デフォルト値を出力
 #list	 {                                            #list	 {
 	 	 logic:	 {                                       	 	 logic:	 {
 	 	 	 	 if	 @list.size	 >	 0                        	 	 	 	 _stag
 	 	 	 	 	 	 _stag                                   	 	 	 	 if	 @name.blank?
 	 	 	 	 	 	 _cont                                   	 	 	 	 	 	 print('World')
 	 	 	 	 	 	 _etag                                   	 	 	 	 else
 	 	 	 	 end                                         	 	 	 	 	 	 _cont
 	 	 }                                               	 	 	 	 end
 }                                                   	 	 	 	 _etag
                                                     	 	 }
                                                     }

                     copyright(c) 2010 kuwata-lab.com all rights reserved.
                                                                                  47
応用例(3)

 ダミータグを削除                                       ダミー要素を削除
 #list	 {                                       #list	 {
 	 	 logic:	 {                                  	 	 logic:	 {
 	 	 	 	 #_stag                                 	 	 }
 	 	 	 	 _cont                                  }
 	 	 	 	 #_etag
 	 	 }                                           他の要素で置換
 }
                                                   #list	 {
                                                   	 	 logic:	 {
                                                   	 	 	 	 _element(list2)
                                                   	 	 }
                                                   }              同じ要素を
                                                                          再利用できる
                  copyright(c) 2010 kuwata-lab.com all rights reserved.
                                                                                   48
応用例(4)

 より複雑なプレゼンテーションロジック
 #list	 {
 	 	 attrs:	 "class"	 cls;	 	 #	 属性値を出力
 	 	 logic:	 {
 	 	 	 	 odd	 =	 false               プレゼンテーションロジックが
 	 	 	 	 for	 x	 in	 @list           HTMLから分離されている
 	 	 	 	 	 	 odd	 =	 !odd
 	 	 	 	 	 	 cls	 =	 odd	 ?	 'odd'	 :	 'even'
 	 	 	 	 	 	 _elem
 	 	 	 	 end                     プレゼンテーションロジックを変更
 	 	 }
                                 してもHTMLは変更する必要がない
 }

               copyright(c) 2010 kuwata-lab.com all rights reserved.
                                                                       49
ここまでのまとめ
✤   Kwartzテンプレートエンジン
    ✤   プレゼンテーションロジックをプレゼンテーション
        データ(=HTML)から分離


    ✤   pure HTML テンプレートを実現
    ✤   プレゼンテーションロジックを変更してもHTMLを変
        更する必要がない




                 copyright(c) 2010 kuwata-lab.com all rights reserved.
                                                                         50
Kwartz編:
プレゼンテーションパターン




           copyright(c) 2010 kuwata-lab.com all rights reserved.
                                                                   51
概要
✤   プレゼンテーションパターンとは?
    ✤   プレゼンテーション層に関するデザインパターン、ベス
        トプラクティス
    ✤   (オレオレ造語であり、一般的ではないことに注意)
    ✤   全然難しくないよ!
    ✤   http://www.kuwata-lab.com/kwartz/kwartz3ruby-
        pattern-catalog.html




                     copyright(c) 2010 kuwata-lab.com all rights reserved.
                                                                             52
パターン一覧
✤   Replacement                                      ✤    Iteration
    ✤   Replace Element with                               ✤    Iterate Element Pattern
        Value Pattern                                      ✤
                                                                Iterate Content Pattern
    ✤   Replace Content with
        Value Pattern                                ✤    Selection
    ✤   Default Content Pattern                            ✤    Select Element/Content
    ✤   Replace Element with                                    Pattern
        Element/Content Pattern                            ✤    Pick-up Element/Content
    ✤   Replace Content with                                    Pattern
        Element/Content Pattern                            ✤    Extract Element/Content
                                                                Pattern
✤   Deletion
    ✤   Delete Element Pattern                                                  今回はこちらを紹介
    ✤   Delete Tag Pattern
                        copyright(c) 2010 kuwata-lab.com all rights reserved.
                                                                                            53
Select Element パターン
✤   要求: 表示するデータを条件によって変えたい

    <div	 id="mark:message">                     #message	 {
    	 	 <div	 id="error">                        	 	 logic:	 {
    	 	 	 	 ERROR!                               	 	 	 	 if	 status	 ==	 'error'
    	 	 </div>                                   	 	 	 	 	 	 _element(error)
    	 	 <div	 id="warning">                      	 	 	 	 elsif	 status	 ==	 'warn'
    	 	 	 	 Warning:                             	 	 	 	 	 	 _element(warning)
    	 	 </div>                                   	 	 	 	 else
    	 	 <div	 id="noerror">                      	 	 	 	 	 	 _element(noerror)
    	 	 	 	 No	 error.                           	 	 	 	 end
    	 	 </dvi>                                   	 	 }           条件によって該当
                     要素ごとに
    </div>                                       }               する要素を選択
                別のidを付加
                     copyright(c) 2010 kuwata-lab.com all rights reserved.
                                                                                     54
Pick-up Element パターン
✤   要求: たくさんのダミー要素を含めたい(デザイン確認のため)

    <ol	 id="mark:list">                          #list	 {
    	 	 <li	 id="mark:item">                      	 	 logic:	 {
    	 	 	 	 Item1                                 	 	 	 	 _stag
    	 	 </li>      ダミーでない                         	 	 	 	 _element(item)
    	 	 <li>Item2</li>
                   要素にid属性                        	 	 	 	 _etag
    	 	 <li>Item3</li>
                   をつけるだけ                         	 	 }
    	 	 <li>Item4</li>                            }
    	 	 <li>Item5</li>                                          ダミーでない要素だけを
    	 	 <li>Item6</li>                                          取り出せば、ダミー要素
    </ol>                                                       はすべて削除される



                      copyright(c) 2010 kuwata-lab.com all rights reserved.
                                                                              55
Extract Element パターン
✤   要求: 文書全体からある特定の要素だけを取り出したい

    <html	 id="mark:whole">                     #whole	 {
    	 <body>                                    	 	 logic:	 {
    	 	 <form	 id="form">                       	 	 	 	 _element(form)
    	 	 	 <input	 ...	 />                       	 	 }
                                                              全体を特定の要素
    	 	 	 <input	 ...	 />                       }
                                                                            だけで置き換える
    	 	 	 <input	 ...	 />
    	 	 </form>                                 #DOCUMENT	 {
    	 </body> いちばん外側の                           	 	 logic:	 {
    </html>       要素である                         	 	 	 	 _element(form)
              <html>タグに
                                                	 	 }
                                                }         Kwartzではそのため
              id属性をつける                                          の特別なid名を提供
                    copyright(c) 2010 kuwata-lab.com all rights reserved.
                                                                                       56
ここまでのまとめ
✤   プレゼンテーションパターン
    ✤   プレゼンテーション層におけるベストプラクティス
    ✤   Select Element パターン:
          条件によって使う要素を変える
    ✤   Pick-up Element パターン:
           必要な要素だけを使い、残りはダミーとして捨てる
    ✤   Extract Element パターン:
          全体からある特定の要素だけを取り出す



                 copyright(c) 2010 kuwata-lab.com all rights reserved.
                                                                         57
まとめ




      copyright(c) 2010 kuwata-lab.com all rights reserved.
                                                              58
まとめ
✤   pure HTMLテンプレートが理想
✤   そのためにはプレゼンテーションロジック
    だけを分離・独立させることが重要
✤   Kwartzはそれを実現してるよ!




           copyright(c) 2010 kuwata-lab.com all rights reserved.
                                                                   59
謝辞
✤   RubyKaigi事務局の皆様
✤   マイナー番組ご視聴の皆様


      ありがとうございました




            copyright(c) 2010 kuwata-lab.com all rights reserved.
                                                                    60
questions?

  copyright(c) 2010 kuwata-lab.com all rights reserved.
                                                          61
thank you

  copyright(c) 2010 kuwata-lab.com all rights reserved.
                                                          62

Mais conteúdo relacionado

Mais procurados

社内Git勉強会向け資料
社内Git勉強会向け資料社内Git勉強会向け資料
社内Git勉強会向け資料Hiroki Saiki
 
Portacle : Common Lispのオールインワン開発環境
Portacle : Common Lispのオールインワン開発環境Portacle : Common Lispのオールインワン開発環境
Portacle : Common Lispのオールインワン開発環境Satoshi imai
 
STMとROSをシリアル通信させて移動ロボットを作る
STMとROSをシリアル通信させて移動ロボットを作るSTMとROSをシリアル通信させて移動ロボットを作る
STMとROSをシリアル通信させて移動ロボットを作るmozyanari
 
RSA暗号運用でやってはいけない n のこと #ssmjp
RSA暗号運用でやってはいけない n のこと #ssmjpRSA暗号運用でやってはいけない n のこと #ssmjp
RSA暗号運用でやってはいけない n のこと #ssmjpsonickun
 
Catalogo conversão de rolamentos
Catalogo conversão  de  rolamentosCatalogo conversão  de  rolamentos
Catalogo conversão de rolamentoscardans
 
談 Uber 從 PostgreSQL 轉用 MySQL 的技術爭議
談 Uber 從 PostgreSQL 轉用 MySQL 的技術爭議談 Uber 從 PostgreSQL 轉用 MySQL 的技術爭議
談 Uber 從 PostgreSQL 轉用 MySQL 的技術爭議Yi-Feng Tzeng
 
PPL 2022 招待講演: 静的型つき函数型組版処理システムSATySFiの紹介
PPL 2022 招待講演: 静的型つき函数型組版処理システムSATySFiの紹介PPL 2022 招待講演: 静的型つき函数型組版処理システムSATySFiの紹介
PPL 2022 招待講演: 静的型つき函数型組版処理システムSATySFiの紹介T. Suwa
 
Redmineチューニングの実際と限界(旧資料) - Redmine performance tuning(old), See Below.
Redmineチューニングの実際と限界(旧資料) - Redmine performance tuning(old), See Below.Redmineチューニングの実際と限界(旧資料) - Redmine performance tuning(old), See Below.
Redmineチューニングの実際と限界(旧資料) - Redmine performance tuning(old), See Below.Kuniharu(州晴) AKAHANE(赤羽根)
 
Plano de-leitura-da-biblia-em-um-ano
Plano de-leitura-da-biblia-em-um-anoPlano de-leitura-da-biblia-em-um-ano
Plano de-leitura-da-biblia-em-um-anoErick Marinho
 
許可を求めるな謝罪せよ?
許可を求めるな謝罪せよ?許可を求めるな謝罪せよ?
許可を求めるな謝罪せよ?Yuta Ohashi
 
Cvim saisentan 半精度浮動小数点数 half
Cvim saisentan 半精度浮動小数点数 halfCvim saisentan 半精度浮動小数点数 half
Cvim saisentan 半精度浮動小数点数 halftomoaki0705
 
【Visual Studio】開発効率を上げる25個の拡張機能
【Visual Studio】開発効率を上げる25個の拡張機能【Visual Studio】開発効率を上げる25個の拡張機能
【Visual Studio】開発効率を上げる25個の拡張機能Shota Baba
 
Zipf分布に従う乱数の生成方法
Zipf分布に従う乱数の生成方法Zipf分布に従う乱数の生成方法
Zipf分布に従う乱数の生成方法Maruyama Tetsutaro
 
ibus-skkをなんとかすっぺ会議
ibus-skkをなんとかすっぺ会議ibus-skkをなんとかすっぺ会議
ibus-skkをなんとかすっぺ会議emasaka
 
跟著Teddy讀Pattern
跟著Teddy讀Pattern跟著Teddy讀Pattern
跟著Teddy讀Patternteddysoft
 

Mais procurados (20)

社内Git勉強会向け資料
社内Git勉強会向け資料社内Git勉強会向け資料
社内Git勉強会向け資料
 
Rustを支える技術
Rustを支える技術Rustを支える技術
Rustを支える技術
 
Portacle : Common Lispのオールインワン開発環境
Portacle : Common Lispのオールインワン開発環境Portacle : Common Lispのオールインワン開発環境
Portacle : Common Lispのオールインワン開発環境
 
STMとROSをシリアル通信させて移動ロボットを作る
STMとROSをシリアル通信させて移動ロボットを作るSTMとROSをシリアル通信させて移動ロボットを作る
STMとROSをシリアル通信させて移動ロボットを作る
 
RSA暗号運用でやってはいけない n のこと #ssmjp
RSA暗号運用でやってはいけない n のこと #ssmjpRSA暗号運用でやってはいけない n のこと #ssmjp
RSA暗号運用でやってはいけない n のこと #ssmjp
 
Catalogo conversão de rolamentos
Catalogo conversão  de  rolamentosCatalogo conversão  de  rolamentos
Catalogo conversão de rolamentos
 
談 Uber 從 PostgreSQL 轉用 MySQL 的技術爭議
談 Uber 從 PostgreSQL 轉用 MySQL 的技術爭議談 Uber 從 PostgreSQL 轉用 MySQL 的技術爭議
談 Uber 從 PostgreSQL 轉用 MySQL 的技術爭議
 
PPL 2022 招待講演: 静的型つき函数型組版処理システムSATySFiの紹介
PPL 2022 招待講演: 静的型つき函数型組版処理システムSATySFiの紹介PPL 2022 招待講演: 静的型つき函数型組版処理システムSATySFiの紹介
PPL 2022 招待講演: 静的型つき函数型組版処理システムSATySFiの紹介
 
CPUから見たG1GC
CPUから見たG1GCCPUから見たG1GC
CPUから見たG1GC
 
Redmineチューニングの実際と限界(旧資料) - Redmine performance tuning(old), See Below.
Redmineチューニングの実際と限界(旧資料) - Redmine performance tuning(old), See Below.Redmineチューニングの実際と限界(旧資料) - Redmine performance tuning(old), See Below.
Redmineチューニングの実際と限界(旧資料) - Redmine performance tuning(old), See Below.
 
Tabela de-parafusos1
Tabela de-parafusos1Tabela de-parafusos1
Tabela de-parafusos1
 
LLVM最適化のこつ
LLVM最適化のこつLLVM最適化のこつ
LLVM最適化のこつ
 
Plano de-leitura-da-biblia-em-um-ano
Plano de-leitura-da-biblia-em-um-anoPlano de-leitura-da-biblia-em-um-ano
Plano de-leitura-da-biblia-em-um-ano
 
許可を求めるな謝罪せよ?
許可を求めるな謝罪せよ?許可を求めるな謝罪せよ?
許可を求めるな謝罪せよ?
 
Cvim saisentan 半精度浮動小数点数 half
Cvim saisentan 半精度浮動小数点数 halfCvim saisentan 半精度浮動小数点数 half
Cvim saisentan 半精度浮動小数点数 half
 
【Visual Studio】開発効率を上げる25個の拡張機能
【Visual Studio】開発効率を上げる25個の拡張機能【Visual Studio】開発効率を上げる25個の拡張機能
【Visual Studio】開発効率を上げる25個の拡張機能
 
Zipf分布に従う乱数の生成方法
Zipf分布に従う乱数の生成方法Zipf分布に従う乱数の生成方法
Zipf分布に従う乱数の生成方法
 
ibus-skkをなんとかすっぺ会議
ibus-skkをなんとかすっぺ会議ibus-skkをなんとかすっぺ会議
ibus-skkをなんとかすっぺ会議
 
跟著Teddy讀Pattern
跟著Teddy讀Pattern跟著Teddy讀Pattern
跟著Teddy讀Pattern
 
south african foundry market
south african foundry marketsouth african foundry market
south african foundry market
 

Semelhante a HTMLデザインを崩さないテンプレートエンジンの作り方

【17-C-4】「Axure RPによる画面プロトタイプを活用した要件定義の改善:野村総合研究所、NTTデータの事例紹介」松永充弘氏
【17-C-4】「Axure RPによる画面プロトタイプを活用した要件定義の改善:野村総合研究所、NTTデータの事例紹介」松永充弘氏【17-C-4】「Axure RPによる画面プロトタイプを活用した要件定義の改善:野村総合研究所、NTTデータの事例紹介」松永充弘氏
【17-C-4】「Axure RPによる画面プロトタイプを活用した要件定義の改善:野村総合研究所、NTTデータの事例紹介」松永充弘氏Developers Summit
 
R超入門機械学習をはじめよう
R超入門機械学習をはじめようR超入門機械学習をはじめよう
R超入門機械学習をはじめよう幹雄 小川
 
TokyoR24 - PerformanceRvsC#
TokyoR24 - PerformanceRvsC#TokyoR24 - PerformanceRvsC#
TokyoR24 - PerformanceRvsC#ta2c
 
リクルートを支える横断データ基盤と機械学習の適用事例
リクルートを支える横断データ基盤と機械学習の適用事例リクルートを支える横断データ基盤と機械学習の適用事例
リクルートを支える横断データ基盤と機械学習の適用事例Tetsutaro Watanabe
 
ディレクションのフロントエンド開発 @JSオジサン 12/17
ディレクションのフロントエンド開発 @JSオジサン 12/17ディレクションのフロントエンド開発 @JSオジサン 12/17
ディレクションのフロントエンド開発 @JSオジサン 12/17Yosuke Doke
 
アジャイル開発&TFS導入
アジャイル開発&TFS導入アジャイル開発&TFS導入
アジャイル開発&TFS導入You&I
 
パワポをよくしただけなのに〜デザインの力で会社に貢献するチームの紹介
パワポをよくしただけなのに〜デザインの力で会社に貢献するチームの紹介パワポをよくしただけなのに〜デザインの力で会社に貢献するチームの紹介
パワポをよくしただけなのに〜デザインの力で会社に貢献するチームの紹介Masataka Suzuki
 
MonotaRO のデータ活用と基盤の過去、現在、未来
MonotaRO のデータ活用と基盤の過去、現在、未来 MonotaRO のデータ活用と基盤の過去、現在、未来
MonotaRO のデータ活用と基盤の過去、現在、未来 株式会社MonotaRO Tech Team
 
SAP HANAは 単なるインメモリーデータベースじゃなくて (賢い)アプリの開発・実行プラットフォーム
SAP HANAは 単なるインメモリーデータベースじゃなくて (賢い)アプリの開発・実行プラットフォームSAP HANAは 単なるインメモリーデータベースじゃなくて (賢い)アプリの開発・実行プラットフォーム
SAP HANAは 単なるインメモリーデータベースじゃなくて (賢い)アプリの開発・実行プラットフォームMakoto Sugishita
 
Application Architecture for Enterprise Win Store Apps with DDD Pattern
Application Architecture for Enterprise Win Store Apps with DDD PatternApplication Architecture for Enterprise Win Store Apps with DDD Pattern
Application Architecture for Enterprise Win Store Apps with DDD PatternAtsushi Kambara
 
Tech summitの歩き方 開発者編
Tech summitの歩き方 開発者編Tech summitの歩き方 開発者編
Tech summitの歩き方 開発者編Tech Summit 2016
 
Tech summitの歩き方 開発者編
Tech summitの歩き方 開発者編Tech summitの歩き方 開発者編
Tech summitの歩き方 開発者編Tech Summit 2016
 
モデリングの彼方に未来を見た
モデリングの彼方に未来を見たモデリングの彼方に未来を見た
モデリングの彼方に未来を見たHagimoto Junzo
 
実演!要求開発の成果物をastah*でこう作れ
実演!要求開発の成果物をastah*でこう作れ実演!要求開発の成果物をastah*でこう作れ
実演!要求開発の成果物をastah*でこう作れKent Ishizawa
 
QualityとDeliveryを両立させるために僕らがやったこと
QualityとDeliveryを両立させるために僕らがやったことQualityとDeliveryを両立させるために僕らがやったこと
QualityとDeliveryを両立させるために僕らがやったことTakeshi Sekiguchi
 
ASP.NET シングル ページ アプリケーション (SPA) 詳説
ASP.NET シングル ページ アプリケーション (SPA) 詳説ASP.NET シングル ページ アプリケーション (SPA) 詳説
ASP.NET シングル ページ アプリケーション (SPA) 詳説Akira Inoue
 
A 1-1 tfs on azure で始めるイマドキのソフトウェア開発
A 1-1 tfs on azure で始めるイマドキのソフトウェア開発A 1-1 tfs on azure で始めるイマドキのソフトウェア開発
A 1-1 tfs on azure で始めるイマドキのソフトウェア開発GoAzure
 

Semelhante a HTMLデザインを崩さないテンプレートエンジンの作り方 (20)

【17-C-4】「Axure RPによる画面プロトタイプを活用した要件定義の改善:野村総合研究所、NTTデータの事例紹介」松永充弘氏
【17-C-4】「Axure RPによる画面プロトタイプを活用した要件定義の改善:野村総合研究所、NTTデータの事例紹介」松永充弘氏【17-C-4】「Axure RPによる画面プロトタイプを活用した要件定義の改善:野村総合研究所、NTTデータの事例紹介」松永充弘氏
【17-C-4】「Axure RPによる画面プロトタイプを活用した要件定義の改善:野村総合研究所、NTTデータの事例紹介」松永充弘氏
 
Mithril
MithrilMithril
Mithril
 
R超入門機械学習をはじめよう
R超入門機械学習をはじめようR超入門機械学習をはじめよう
R超入門機械学習をはじめよう
 
TokyoR24 - PerformanceRvsC#
TokyoR24 - PerformanceRvsC#TokyoR24 - PerformanceRvsC#
TokyoR24 - PerformanceRvsC#
 
リクルートを支える横断データ基盤と機械学習の適用事例
リクルートを支える横断データ基盤と機械学習の適用事例リクルートを支える横断データ基盤と機械学習の適用事例
リクルートを支える横断データ基盤と機械学習の適用事例
 
ディレクションのフロントエンド開発 @JSオジサン 12/17
ディレクションのフロントエンド開発 @JSオジサン 12/17ディレクションのフロントエンド開発 @JSオジサン 12/17
ディレクションのフロントエンド開発 @JSオジサン 12/17
 
アジャイル開発&TFS導入
アジャイル開発&TFS導入アジャイル開発&TFS導入
アジャイル開発&TFS導入
 
パワポをよくしただけなのに〜デザインの力で会社に貢献するチームの紹介
パワポをよくしただけなのに〜デザインの力で会社に貢献するチームの紹介パワポをよくしただけなのに〜デザインの力で会社に貢献するチームの紹介
パワポをよくしただけなのに〜デザインの力で会社に貢献するチームの紹介
 
MonotaRO のデータ活用と基盤の過去、現在、未来
MonotaRO のデータ活用と基盤の過去、現在、未来 MonotaRO のデータ活用と基盤の過去、現在、未来
MonotaRO のデータ活用と基盤の過去、現在、未来
 
SAP HANAは 単なるインメモリーデータベースじゃなくて (賢い)アプリの開発・実行プラットフォーム
SAP HANAは 単なるインメモリーデータベースじゃなくて (賢い)アプリの開発・実行プラットフォームSAP HANAは 単なるインメモリーデータベースじゃなくて (賢い)アプリの開発・実行プラットフォーム
SAP HANAは 単なるインメモリーデータベースじゃなくて (賢い)アプリの開発・実行プラットフォーム
 
Application Architecture for Enterprise Win Store Apps with DDD Pattern
Application Architecture for Enterprise Win Store Apps with DDD PatternApplication Architecture for Enterprise Win Store Apps with DDD Pattern
Application Architecture for Enterprise Win Store Apps with DDD Pattern
 
Tech summitの歩き方 開発者編
Tech summitの歩き方 開発者編Tech summitの歩き方 開発者編
Tech summitの歩き方 開発者編
 
Tech summitの歩き方 開発者編
Tech summitの歩き方 開発者編Tech summitの歩き方 開発者編
Tech summitの歩き方 開発者編
 
モデリングの彼方に未来を見た
モデリングの彼方に未来を見たモデリングの彼方に未来を見た
モデリングの彼方に未来を見た
 
実演!要求開発の成果物をastah*でこう作れ
実演!要求開発の成果物をastah*でこう作れ実演!要求開発の成果物をastah*でこう作れ
実演!要求開発の成果物をastah*でこう作れ
 
QualityとDeliveryを両立させるために僕らがやったこと
QualityとDeliveryを両立させるために僕らがやったことQualityとDeliveryを両立させるために僕らがやったこと
QualityとDeliveryを両立させるために僕らがやったこと
 
ASP.NET シングル ページ アプリケーション (SPA) 詳説
ASP.NET シングル ページ アプリケーション (SPA) 詳説ASP.NET シングル ページ アプリケーション (SPA) 詳説
ASP.NET シングル ページ アプリケーション (SPA) 詳説
 
SRE 1st steps
SRE 1st stepsSRE 1st steps
SRE 1st steps
 
A 1-1 tfs on azure で始めるイマドキのソフトウェア開発
A 1-1 tfs on azure で始めるイマドキのソフトウェア開発A 1-1 tfs on azure で始めるイマドキのソフトウェア開発
A 1-1 tfs on azure で始めるイマドキのソフトウェア開発
 
Go azure tfs_service
Go azure tfs_serviceGo azure tfs_service
Go azure tfs_service
 

Mais de kwatch

How to make the fastest Router in Python
How to make the fastest Router in PythonHow to make the fastest Router in Python
How to make the fastest Router in Pythonkwatch
 
Migr8.rb チュートリアル
Migr8.rb チュートリアルMigr8.rb チュートリアル
Migr8.rb チュートリアルkwatch
 
なんでもID
なんでもIDなんでもID
なんでもIDkwatch
 
Nippondanji氏に怒られても仕方ない、配列型とJSON型の使い方
Nippondanji氏に怒られても仕方ない、配列型とJSON型の使い方Nippondanji氏に怒られても仕方ない、配列型とJSON型の使い方
Nippondanji氏に怒られても仕方ない、配列型とJSON型の使い方kwatch
 
【SQLインジェクション対策】徳丸先生に怒られない、動的SQLの安全な組み立て方
【SQLインジェクション対策】徳丸先生に怒られない、動的SQLの安全な組み立て方【SQLインジェクション対策】徳丸先生に怒られない、動的SQLの安全な組み立て方
【SQLインジェクション対策】徳丸先生に怒られない、動的SQLの安全な組み立て方kwatch
 
O/Rマッパーによるトラブルを未然に防ぐ
O/Rマッパーによるトラブルを未然に防ぐO/Rマッパーによるトラブルを未然に防ぐ
O/Rマッパーによるトラブルを未然に防ぐkwatch
 
正規表現リテラルは本当に必要なのか?
正規表現リテラルは本当に必要なのか?正規表現リテラルは本当に必要なのか?
正規表現リテラルは本当に必要なのか?kwatch
 
【公開終了】Python4PHPer - PHPユーザのためのPython入門 (Python2.5)
【公開終了】Python4PHPer - PHPユーザのためのPython入門 (Python2.5)【公開終了】Python4PHPer - PHPユーザのためのPython入門 (Python2.5)
【公開終了】Python4PHPer - PHPユーザのためのPython入門 (Python2.5)kwatch
 
DBスキーマもバージョン管理したい!
DBスキーマもバージョン管理したい!DBスキーマもバージョン管理したい!
DBスキーマもバージョン管理したい!kwatch
 
PHPとJavaScriptにおけるオブジェクト指向を比較する
PHPとJavaScriptにおけるオブジェクト指向を比較するPHPとJavaScriptにおけるオブジェクト指向を比較する
PHPとJavaScriptにおけるオブジェクト指向を比較するkwatch
 
SQL上級者こそ知って欲しい、なぜO/Rマッパーが重要か?
SQL上級者こそ知って欲しい、なぜO/Rマッパーが重要か?SQL上級者こそ知って欲しい、なぜO/Rマッパーが重要か?
SQL上級者こそ知って欲しい、なぜO/Rマッパーが重要か?kwatch
 
Fantastic DSL in Python
Fantastic DSL in PythonFantastic DSL in Python
Fantastic DSL in Pythonkwatch
 
What is wrong on Test::More? / Test::Moreが抱える問題点とその解決策
What is wrong on Test::More? / Test::Moreが抱える問題点とその解決策What is wrong on Test::More? / Test::Moreが抱える問題点とその解決策
What is wrong on Test::More? / Test::Moreが抱える問題点とその解決策kwatch
 
PHP5.5新機能「ジェネレータ」初心者入門
PHP5.5新機能「ジェネレータ」初心者入門PHP5.5新機能「ジェネレータ」初心者入門
PHP5.5新機能「ジェネレータ」初心者入門kwatch
 
Pretty Good Branch Strategy for Git/Mercurial
Pretty Good Branch Strategy for Git/MercurialPretty Good Branch Strategy for Git/Mercurial
Pretty Good Branch Strategy for Git/Mercurialkwatch
 
Oktest - a new style testing library for Python -
Oktest - a new style testing library for Python -Oktest - a new style testing library for Python -
Oktest - a new style testing library for Python -kwatch
 
文字列結合のベンチマークをいろんな処理系でやってみた
文字列結合のベンチマークをいろんな処理系でやってみた文字列結合のベンチマークをいろんな処理系でやってみた
文字列結合のベンチマークをいろんな処理系でやってみたkwatch
 
I have something to say about the buzz word "From Java to Ruby"
I have something to say about the buzz word "From Java to Ruby"I have something to say about the buzz word "From Java to Ruby"
I have something to say about the buzz word "From Java to Ruby"kwatch
 
Cより速いRubyプログラム
Cより速いRubyプログラムCより速いRubyプログラム
Cより速いRubyプログラムkwatch
 
Javaより速いLL用テンプレートエンジン
Javaより速いLL用テンプレートエンジンJavaより速いLL用テンプレートエンジン
Javaより速いLL用テンプレートエンジンkwatch
 

Mais de kwatch (20)

How to make the fastest Router in Python
How to make the fastest Router in PythonHow to make the fastest Router in Python
How to make the fastest Router in Python
 
Migr8.rb チュートリアル
Migr8.rb チュートリアルMigr8.rb チュートリアル
Migr8.rb チュートリアル
 
なんでもID
なんでもIDなんでもID
なんでもID
 
Nippondanji氏に怒られても仕方ない、配列型とJSON型の使い方
Nippondanji氏に怒られても仕方ない、配列型とJSON型の使い方Nippondanji氏に怒られても仕方ない、配列型とJSON型の使い方
Nippondanji氏に怒られても仕方ない、配列型とJSON型の使い方
 
【SQLインジェクション対策】徳丸先生に怒られない、動的SQLの安全な組み立て方
【SQLインジェクション対策】徳丸先生に怒られない、動的SQLの安全な組み立て方【SQLインジェクション対策】徳丸先生に怒られない、動的SQLの安全な組み立て方
【SQLインジェクション対策】徳丸先生に怒られない、動的SQLの安全な組み立て方
 
O/Rマッパーによるトラブルを未然に防ぐ
O/Rマッパーによるトラブルを未然に防ぐO/Rマッパーによるトラブルを未然に防ぐ
O/Rマッパーによるトラブルを未然に防ぐ
 
正規表現リテラルは本当に必要なのか?
正規表現リテラルは本当に必要なのか?正規表現リテラルは本当に必要なのか?
正規表現リテラルは本当に必要なのか?
 
【公開終了】Python4PHPer - PHPユーザのためのPython入門 (Python2.5)
【公開終了】Python4PHPer - PHPユーザのためのPython入門 (Python2.5)【公開終了】Python4PHPer - PHPユーザのためのPython入門 (Python2.5)
【公開終了】Python4PHPer - PHPユーザのためのPython入門 (Python2.5)
 
DBスキーマもバージョン管理したい!
DBスキーマもバージョン管理したい!DBスキーマもバージョン管理したい!
DBスキーマもバージョン管理したい!
 
PHPとJavaScriptにおけるオブジェクト指向を比較する
PHPとJavaScriptにおけるオブジェクト指向を比較するPHPとJavaScriptにおけるオブジェクト指向を比較する
PHPとJavaScriptにおけるオブジェクト指向を比較する
 
SQL上級者こそ知って欲しい、なぜO/Rマッパーが重要か?
SQL上級者こそ知って欲しい、なぜO/Rマッパーが重要か?SQL上級者こそ知って欲しい、なぜO/Rマッパーが重要か?
SQL上級者こそ知って欲しい、なぜO/Rマッパーが重要か?
 
Fantastic DSL in Python
Fantastic DSL in PythonFantastic DSL in Python
Fantastic DSL in Python
 
What is wrong on Test::More? / Test::Moreが抱える問題点とその解決策
What is wrong on Test::More? / Test::Moreが抱える問題点とその解決策What is wrong on Test::More? / Test::Moreが抱える問題点とその解決策
What is wrong on Test::More? / Test::Moreが抱える問題点とその解決策
 
PHP5.5新機能「ジェネレータ」初心者入門
PHP5.5新機能「ジェネレータ」初心者入門PHP5.5新機能「ジェネレータ」初心者入門
PHP5.5新機能「ジェネレータ」初心者入門
 
Pretty Good Branch Strategy for Git/Mercurial
Pretty Good Branch Strategy for Git/MercurialPretty Good Branch Strategy for Git/Mercurial
Pretty Good Branch Strategy for Git/Mercurial
 
Oktest - a new style testing library for Python -
Oktest - a new style testing library for Python -Oktest - a new style testing library for Python -
Oktest - a new style testing library for Python -
 
文字列結合のベンチマークをいろんな処理系でやってみた
文字列結合のベンチマークをいろんな処理系でやってみた文字列結合のベンチマークをいろんな処理系でやってみた
文字列結合のベンチマークをいろんな処理系でやってみた
 
I have something to say about the buzz word "From Java to Ruby"
I have something to say about the buzz word "From Java to Ruby"I have something to say about the buzz word "From Java to Ruby"
I have something to say about the buzz word "From Java to Ruby"
 
Cより速いRubyプログラム
Cより速いRubyプログラムCより速いRubyプログラム
Cより速いRubyプログラム
 
Javaより速いLL用テンプレートエンジン
Javaより速いLL用テンプレートエンジンJavaより速いLL用テンプレートエンジン
Javaより速いLL用テンプレートエンジン
 

HTMLデザインを崩さないテンプレートエンジンの作り方

  • 1. RubyKaigi 2010 HTMLデザインを崩さない テンプレートエンジンの作り方 makoto kuwata http://www.kuwata-lab.com/ English ver: http://slidesha.re/a3s2ZZ copyright(c) 2010 kuwata-lab.com all rights reserved. 1
  • 2. はじめに 目的 ✤ テンプレートエンジン利用者に、正しい 知識を理解してもらう ✤ テンプレートエンジン設計者に、あるべ き姿を考えてもらう 動機 ✤ 間違った説明が蔓延しており是正したい ✤ eRubyは決して理想解ではないことを 知ってほしい 対象者 ✤ テンプレートエンジンの利用者と設計者 copyright(c) 2010 kuwata-lab.com all rights reserved. 2
  • 3. お詫び ✤ 今日話したかったこと ✤ テンプレートのデザインを崩さない方法について ✤ テンプレートエンジンの高速化について ✤ 既存のテンプレートエンジンが抱える問題点について ✤ デザインを崩さず、高速で、どの言語でも比較的簡単に 実装できるテンプレートエンジンの作り方について ✤ 30分しかないので最初の項目だけ ✤ 野心的すぎました、ごめんなさい copyright(c) 2010 kuwata-lab.com all rights reserved. 3
  • 4. 参考文献 ✤ Rubyist Magazine - テンプレートシステム入門 ✤ http://jp.rubyist.net/magazine/?0024-TemplateSystem ✤ http://jp.rubyist.net/magazine/?0024-TemplateSystem2 copyright(c) 2010 kuwata-lab.com all rights reserved. 4
  • 5. アジェンダ ✤ 基礎知識編 ✤ ビジネス層とプレゼンテーション層 ✤ 現状の問題点とその原因 ✤ プレゼンテーションロジック ✤ Kwartz編 ✤ はじめてのKwartz入門 ✤ プレゼンテーションパターン copyright(c) 2010 kuwata-lab.com all rights reserved. 5
  • 6. 基礎知識編: ビジネス層とプレゼンテーション層 copyright(c) 2010 kuwata-lab.com all rights reserved. 6
  • 7. ビジネス層とプレゼンテーション層 ✤ ビジネス層 ✤ 役割:「何を(what)表示するか?」を決定 ✤ 担当:メインプログラム ✤ プレゼンテーション層 ✤ 役割:「どのように(how)表示するか?」を決定 ✤ 担当:テンプレートファイルおよびエンジン copyright(c) 2010 kuwata-lab.com all rights reserved. 7
  • 8. データとロジック ✤ ビジネス層とプレゼンテーション層の両方に、 データとロジックが存在 ビジネス層 プレゼンテーション層 (メインプログラム) (テンプレートエンジン) プレゼンテーション データ ビジネスデータ データ プレゼンテーション ロジック ビジネスロジック ロジック テンプレートエンジンはここを分離 copyright(c) 2010 kuwata-lab.com all rights reserved. 8
  • 9. 具体例 ビジネスデータ ✤ 営業部員の売上成績から ビジネスロジック ✤ 上位 20 名を選出し、 ✤ 奇数行と偶数行で背景色を変えて プレゼンテー ✤ <table> タグで表示する ションロジック プレゼンテー ションデータ copyright(c) 2010 kuwata-lab.com all rights reserved. 9
  • 10. よくある間違い(1) (誤) ✤ テンプレートエンジンは、ロジックと プレゼンテーションを分離する ✤ テンプレートエンジンは、ビジネス層 (正) とプレゼンテーション層を分離する ✤ プレゼンテーション層にもロジックがある 自分も昔は間違ってました… copyright(c) 2010 kuwata-lab.com all rights reserved. 10
  • 11. よくある間違い(2) (誤) ✤ プレゼンテーション層にはロジックを 含めるべきではない ✤ プレゼンテーション層はプレゼンテー (正) ションロジックを含む ✤ 「HTMLテンプレートにプレゼンテーション ロジックを含めない」ことと、「ビジネス層 とプレゼンテーション層を分離する」こと は、別の話 copyright(c) 2010 kuwata-lab.com all rights reserved. 11
  • 12. ここまでのまとめ ✤ ビジネス層 ✤ 何を(What)表示するか? ✤ メインプログラムが担当 ✤ プレゼンテーション層 ✤ どう(How)表示するか? ✤ テンプレートファイルが担当 ✤ どちらにもデータとロジックが存在 copyright(c) 2010 kuwata-lab.com all rights reserved. 12
  • 13. 基礎知識編: 現状の問題点とその原因 copyright(c) 2010 kuwata-lab.com all rights reserved. 13
  • 14. デザイナ泣かせの現状 ProjectA: Rails <table> ProjectC: PHP <% @arr.each { %> <table> .... <?php foreach() { ?> <% } %> .... </table> <?php } ?> </table> ProjectB: JSP <table> <forEach items=""> プログラマの都合を .... デザイナに押し付け </forEach> ているのが現状 </table> copyright(c) 2010 kuwata-lab.com all rights reserved. 14
  • 15. 共同作業での問題 テンプレートファイル <table> <% @arr.each { %> .... <% } %> </table> 衝突! プレゼンテーション HTMLを編集 ロジックを編集 デザイナ プログラマ copyright(c) 2010 kuwata-lab.com all rights reserved. 15
  • 16. 問題の原因 ✤ テンプレート中にプレ テンプレートファイル ゼンテーションロジッ <table> クを埋め込んでいるこ <% i = 0 %> <% @arr.eachx do |x| %> とこそが、諸悪の根源 <% i += i %> <% c = i.odd ? %> <% 'odd':'even' %> pure HTML テンプ <tr class="<%=c%>"> レートが望ましい <td><%= x %></td> </tr> <% end %> </table> copyright(c) 2010 kuwata-lab.com all rights reserved. 16
  • 17. pure HTML テンプレートの利点 ✤ HTMLデザインが崩れない(表示確認できる) デザイナ for ✤ テンプレート言語を学習しなくてよい ✤ HTML Validator でチェックできる ✤ 好きなエディタ (Dreamweaverなど) が使える 同時編集による衝突を避けやすい プログラマ for ✤ ✤ 空白除去による圧縮(転送量削減)がしやすい ✤ ケータイ用などに自動変換しやすい copyright(c) 2010 kuwata-lab.com all rights reserved. 17
  • 18. Matzも悩んだ問題 ✤ じゃあプレゼンテーションロジックは どこに書けばいいの? Matz日記 (2004-08-24) http://www.rubyist.net/ matz/20040824.html#p01 (要約) ViewそのものにLogicが必要な場合、 HTMLテンプレートでは記述できないし、 どこに所属すべきだろうか? copyright(c) 2010 kuwata-lab.com all rights reserved. 18
  • 19. ここまでのまとめ ✤ テンプレート中にプレゼンテーションロ ジックを埋め込むと、問題が多い ✤ pure HTMLテンプレートが望ましい ✤ プレゼンテーションロジックはどこに? copyright(c) 2010 kuwata-lab.com all rights reserved. 19
  • 20. 基礎知識編: プレゼンテーションロジック copyright(c) 2010 kuwata-lab.com all rights reserved. 20
  • 21. プレゼンテーションロジックをどこに? A. テンプレートファイル中 (eRuby, JSP, Kid) プレゼンテーションロジック ビジネスロジック&データ +プレゼンテーションデータ B. メインプログラム中 (Amrita2, XMLC, HTML::Template) プレゼンテーションロジック プレゼンテーションデータ +ビジネスロジック&データ C. 独立した別ファイル中 (Kwartz, Tapestry, Mayaa) プレゼンテーションロジック ビジネスロジック&データ プレゼンテーションデータ テンプレート メインプログラム copyright(c) 2010 kuwata-lab.com all rights reserved. 21
  • 22. A. テンプレートファイル中に記述 (1) 例: eRuby ファイル (Ruby) <table> <% odd = false %> <% for item in @list %> <% odd = ! odd <% cls = odd ? 'odd' : 'even' %> <tr class="<%= cls %>"> <td><%=h item %></td> </tr> •HTMLの中にHTML <% end %> でないものが混在 </table> →pure HTML でない copyright(c) 2010 kuwata-lab.com all rights reserved. 22
  • 23. A. テンプレートファイル中に記述 (2) 例: JSP ファイル (Java) <table> <c:forEach var="item" items="${list}" varStatus="loop"> <c:set var="klass" value="${loop.count%2==0?'odd':'even'}" /> <tr class="${klass}"> <td><c:out value="${item}" /></td> </tr> </c:forEach> •カスタムタグを使おうが、ロジックを </table> テンプレートファイル中に埋め込んで いるという点ではeRubyと同じ copyright(c) 2010 kuwata-lab.com all rights reserved. 23
  • 24. A. テンプレートファイル中に記述 (3) 例: Kid テンプレートファイル (Python) <table> <tr py:for="i, item in enumerate(items)" class="${i % 2 and 'even' or 'odd'}"> <td py:content="item">dummy</td> </tr> </table> •文書構造と属性を使うことで、 HTMLデザインを崩さないよう配慮 •ロジックをテンプレートファイル中に 埋め込んでいるという点では同じ copyright(c) 2010 kuwata-lab.com all rights reserved. 24
  • 25. A. テンプレートファイル中に記述 (4) プレゼンテーション層(=テンプレート)が 利 ✤ ビジネス層から分離されている 点 ✤ 使い方がわかりやすく、実装も簡単 pure HTML でない(ことが多い) 欠 ✤ ✤ 同時編集による衝突が発生しやすい 点 ✤ デザイナがプレゼンテーションロジックを 誤って変更する可能性がある copyright(c) 2010 kuwata-lab.com all rights reserved. 25
  • 26. プレゼンテーションロジックをどこに? A. テンプレートファイル中 (eRuby, JSP, Kid) プレゼンテーションロジック ビジネスロジック&データ +プレゼンテーションデータ B. メインプログラム中 (Amrita2, XMLC, HTML::Template) プレゼンテーションロジック プレゼンテーションデータ +ビジネスロジック&データ C. 独立した別ファイル中 (Kwartz, Tapestry, Mayaa) プレゼンテーションロジック ビジネスロジック&データ プレゼンテーションデータ テンプレート メインプログラム copyright(c) 2010 kuwata-lab.com all rights reserved. 26
  • 27. B. メインプログラム中に記述 (1) 例: Amrita2 テンプレートファイル (Ruby) <table> <tr id="list" class="odd"> <td id="item">dummy</td> </tr> </table> •書き換えたい場所に「目印」を書くだけ (Amrita2ならid属性をつけるだけ) •テンプレートが pure HTML (ロジック を埋め込まないため) copyright(c) 2010 kuwata-lab.com all rights reserved. 27
  • 28. B. メインプログラム中に記述 (2) 例: Amrita2 メインプログラム (Ruby) ## 表示したいビジネスデータ list = [ 'A', 'B', 'C' ] •ビジネスデータをプレゼ ## プレゼンテーションロジック ンテーションロジックで list2 = []; odd = false 加工する必要がある for x in list cls = (odd = !odd) ? 'odd' : 'even' item2 = a(:class=>cls) { {:item=>x} } list2 << item2 end context = { :list=>list2 } ## テンプレートを読み込んで表示 tmpl = Amrita2::TemplateFile.new('ex1.html') tmpl.expand(html='', context) print html copyright(c) 2010 kuwata-lab.com all rights reserved. 28
  • 29. B. メインプログラム中に記述 (3) テンプレートには目印を埋め込むだけ 利 ✤ pure HTML テンプレートを実現 (しやすい) 点 ✤ ✤ 同じファイルを編集しないので衝突しない ✤ デザイナによるロジックの誤変更がない ビジネス層とプレゼンテーション層が分離で 欠 ✤ きてない(*注) 点 ✤ 使い方にクセがある(ロジックをデータで表 現する必要があるため) (*注) 工夫次第で回避可能(該当箇所を別クラスにする等) copyright(c) 2010 kuwata-lab.com all rights reserved. 29
  • 30. プレゼンテーションロジックをどこに? A. テンプレートファイル中 (eRuby, JSP, Kid) プレゼンテーションロジック ビジネスロジック&データ +プレゼンテーションデータ B. メインプログラム中 (Amrita2, XMLC, HTML::Template) プレゼンテーションロジック プレゼンテーションデータ +ビジネスロジック&データ C. 独立した別ファイル中 (Kwartz, Tapestry, Mayaa) プレゼンテーションロジック ビジネスロジック&データ プレゼンテーションデータ テンプレート メインプログラム copyright(c) 2010 kuwata-lab.com all rights reserved. 30
  • 31. C. 独立した別ファイル中に記述 (1) 例: Kwartz プレゼンテーションデータファイル (Ruby) <table> <tr id="mark:list" class="odd"> <td id="mark:item">dummy</td> </tr> </table> •書き換えたい場所に「目印」を書くだけ (Kwartzならid属性をつけるだけ) copyright(c) 2010 kuwata-lab.com all rights reserved. 31
  • 32. C. 独立した別ファイル中に記述 (2) 例: Kwartz プレゼンテーションロジックファイル (Ruby) #item { ## id="mark:item" は value: x; ## x の値を表示する } #list { ## id="mark:list" は logic: { ## 要素全体をループする for x in @list _elem end } •あたかもCSSのようにプレゼンテー } ションロジックを記述する •プレゼンテーションロジックがメイ ンプログラム中に現れない! copyright(c) 2010 kuwata-lab.com all rights reserved. 32
  • 33. CSS (Visual Design) HTML (Document Structure) Kwartz JavaScript (Presentation (Client-side Logic) Logic) copyright(c) 2010 kuwata-lab.com all rights reserved. 33
  • 34. C. 独立した別ファイル中に記述 (3) ✤ ビジネス層とプレゼンテーション層がきれい 利 に分離 点 ✤ プレゼンテーションデータ(HTML)とプレ ゼンテーションロジックもきれいに分離 ✤ pure HTML テンプレートを実現 ✤ 編集するファイルが別なので衝突しない ✤ デザイナによるロジックの誤変更がない 欠 ✤ ファイル数が増える 点 copyright(c) 2010 kuwata-lab.com all rights reserved. 34
  • 35. 大事なことと本当に大事なこと ✤ 大事なこと ✤ テンプレートが pure HTML であること ✤ 本当に大事なこと ✤ プレゼンテーションロジックを分離・独立させること ✤ (pure HTML はその副産物にすぎない) copyright(c) 2010 kuwata-lab.com all rights reserved. 35
  • 36. よくある間違い(1) (誤) ✤ テンプレートがpure HTMLなので、 プレゼンテーション層を分離できてい ます! ✤ pure HTMLであることと、各層が分 (正) 離できることは、別個のお話 ✤ 恐らく、HTMLファイル中にロジックが現れ ないことを「プレゼンテーション層の分離」 と勘違いしている copyright(c) 2010 kuwata-lab.com all rights reserved. 36
  • 37. よくある間違い(2) (誤) ✤ 生PHPだとデザイナが変なロジックを 埋め込む可能性があるので、Smarty を導入しました! ✤ Smartyではデザイナによる誤変更は防 (正) 止できない ✤ デザイナがプレゼンテーションロジックにア クセスできる時点で間違い ✤ 根本的な解決法は、プレゼンテーションロ ジックを分離すること copyright(c) 2010 kuwata-lab.com all rights reserved. 37
  • 38. ここまでのまとめ ✤ プレゼンテーションロジックの記述場所 ✤ テンプレートファイル中(デザイン崩れ、競合が発生) ✤ メインプログラム中(分離がいまいち) ✤ 独立した別ファイル中(いちばん理想的) ✤ pure HTML テンプレートは重要 ✤ プレゼンテーションロジックの分離・独立 はもっと重要 copyright(c) 2010 kuwata-lab.com all rights reserved. 38
  • 39. Kwartz編: はじめてのKwartz入門 copyright(c) 2010 kuwata-lab.com all rights reserved. 39
  • 40. Kwartz 概要 ✤ Kwartzとは? ✤ プレゼンテーションデータ(HTML)と プレゼンテーションロジックを分離できるテンプレー トエンジン ✤ pure HTML テンプレート ✤ Ruby実装とPHP実装を用意 ✤ http://www.kuwata-lab.com/kwartz/ copyright(c) 2010 kuwata-lab.com all rights reserved. 40
  • 41. サンプル: プレゼンテーションデータ 書き換えたい箇所に、目印 ex.html となるid属性をつける <table> <tr id="mark:list"> <td id="mark:item">Foo</td> </tr> <tr id="dummy:d1"> <td>Bar</td> </tr> </table> 「id="dummy:xxx"」は ダミー要素を表す copyright(c) 2010 kuwata-lab.com all rights reserved. 41
  • 42. サンプル: プレゼンテーションロジック ex.plogic id属性ごとにプレゼンテー #list { ションロジックを記述 logic: { for x in @list _stag ## 開始タグ _cont ## 内容 _etag ## 終了タグ end } <tr>要素を繰り返し } #item { value: x; } <td>要素に値を出力 copyright(c) 2010 kuwata-lab.com all rights reserved. 42
  • 43. サンプル: コンパイル eRubyファイルへコンパイル $ kwartz -l eruby -p ex.plogic ex.html > ex.rhtml ex.rhtml (コンパイル結果) <table> <% for x in @list %> <tr> <td><%= x %></td> •属性「id="mark:xxx"」は </tr> コンパイル時に削除される <% end %> (id="xxx" なら削除されない) </table> •「id="dummy:xxx"」は要素 そのものが削除される copyright(c) 2010 kuwata-lab.com all rights reserved. 43
  • 44. サンプル: メインプログラム メインプログラム ## 表示したいビジネスデータ list = ['A', 'B', 'C'] context = { :list => list } ## テンプレートを読み込んで表示 require 'erubis' eruby = Erubis::Eruby.load_file('ex.rhtml') html = eruby.evaluate(context) print html ふつうにeRubyファイ ルとして実行するだけ copyright(c) 2010 kuwata-lab.com all rights reserved. 44
  • 45. 特長と欠点 ✤ 特長 ✤ pure HTML テンプレートである ✤ 実行速度が高速 ✤ eRuby, PHP, JSP 等もサポート ✤ HTML以外でも利用可能 ✤ 欠点 ✤ コンパイルが面倒(自動化は可能) ✤ 実行時エラーで報告される行番号がコンパイ ル後のものであり、コンパイル前の行番号で はない(言語のサポートが必要) copyright(c) 2010 kuwata-lab.com all rights reserved. 45
  • 46. 応用例(1) 要素全体を繰り返す 内容だけを繰り返す #list { #list { logic: { logic: { for item in @list _stag _stag # 開始タグ for item in @list _cont # 内容 _cont _etag # 終了タグ end end _etag } } } } <dt>と<dd>を繰り 返したいときに有用 copyright(c) 2010 kuwata-lab.com all rights reserved. 46
  • 47. 応用例(2) 条件を満たすときだけ出力 デフォルト値を出力 #list { #list { logic: { logic: { if @list.size > 0 _stag _stag if @name.blank? _cont print('World') _etag else end _cont } end } _etag } } copyright(c) 2010 kuwata-lab.com all rights reserved. 47
  • 48. 応用例(3) ダミータグを削除 ダミー要素を削除 #list { #list { logic: { logic: { #_stag } _cont } #_etag } 他の要素で置換 } #list { logic: { _element(list2) } } 同じ要素を 再利用できる copyright(c) 2010 kuwata-lab.com all rights reserved. 48
  • 49. 応用例(4) より複雑なプレゼンテーションロジック #list { attrs: "class" cls; # 属性値を出力 logic: { odd = false プレゼンテーションロジックが for x in @list HTMLから分離されている odd = !odd cls = odd ? 'odd' : 'even' _elem end プレゼンテーションロジックを変更 } してもHTMLは変更する必要がない } copyright(c) 2010 kuwata-lab.com all rights reserved. 49
  • 50. ここまでのまとめ ✤ Kwartzテンプレートエンジン ✤ プレゼンテーションロジックをプレゼンテーション データ(=HTML)から分離 ✤ pure HTML テンプレートを実現 ✤ プレゼンテーションロジックを変更してもHTMLを変 更する必要がない copyright(c) 2010 kuwata-lab.com all rights reserved. 50
  • 51. Kwartz編: プレゼンテーションパターン copyright(c) 2010 kuwata-lab.com all rights reserved. 51
  • 52. 概要 ✤ プレゼンテーションパターンとは? ✤ プレゼンテーション層に関するデザインパターン、ベス トプラクティス ✤ (オレオレ造語であり、一般的ではないことに注意) ✤ 全然難しくないよ! ✤ http://www.kuwata-lab.com/kwartz/kwartz3ruby- pattern-catalog.html copyright(c) 2010 kuwata-lab.com all rights reserved. 52
  • 53. パターン一覧 ✤ Replacement ✤ Iteration ✤ Replace Element with ✤ Iterate Element Pattern Value Pattern ✤ Iterate Content Pattern ✤ Replace Content with Value Pattern ✤ Selection ✤ Default Content Pattern ✤ Select Element/Content ✤ Replace Element with Pattern Element/Content Pattern ✤ Pick-up Element/Content ✤ Replace Content with Pattern Element/Content Pattern ✤ Extract Element/Content Pattern ✤ Deletion ✤ Delete Element Pattern 今回はこちらを紹介 ✤ Delete Tag Pattern copyright(c) 2010 kuwata-lab.com all rights reserved. 53
  • 54. Select Element パターン ✤ 要求: 表示するデータを条件によって変えたい <div id="mark:message"> #message { <div id="error"> logic: { ERROR! if status == 'error' </div> _element(error) <div id="warning"> elsif status == 'warn' Warning: _element(warning) </div> else <div id="noerror"> _element(noerror) No error. end </dvi> } 条件によって該当 要素ごとに </div> } する要素を選択 別のidを付加 copyright(c) 2010 kuwata-lab.com all rights reserved. 54
  • 55. Pick-up Element パターン ✤ 要求: たくさんのダミー要素を含めたい(デザイン確認のため) <ol id="mark:list"> #list { <li id="mark:item"> logic: { Item1 _stag </li> ダミーでない _element(item) <li>Item2</li> 要素にid属性 _etag <li>Item3</li> をつけるだけ } <li>Item4</li> } <li>Item5</li> ダミーでない要素だけを <li>Item6</li> 取り出せば、ダミー要素 </ol> はすべて削除される copyright(c) 2010 kuwata-lab.com all rights reserved. 55
  • 56. Extract Element パターン ✤ 要求: 文書全体からある特定の要素だけを取り出したい <html id="mark:whole"> #whole { <body> logic: { <form id="form"> _element(form) <input ... /> } 全体を特定の要素 <input ... /> } だけで置き換える <input ... /> </form> #DOCUMENT { </body> いちばん外側の logic: { </html> 要素である _element(form) <html>タグに } } Kwartzではそのため id属性をつける の特別なid名を提供 copyright(c) 2010 kuwata-lab.com all rights reserved. 56
  • 57. ここまでのまとめ ✤ プレゼンテーションパターン ✤ プレゼンテーション層におけるベストプラクティス ✤ Select Element パターン: 条件によって使う要素を変える ✤ Pick-up Element パターン: 必要な要素だけを使い、残りはダミーとして捨てる ✤ Extract Element パターン: 全体からある特定の要素だけを取り出す copyright(c) 2010 kuwata-lab.com all rights reserved. 57
  • 58. まとめ copyright(c) 2010 kuwata-lab.com all rights reserved. 58
  • 59. まとめ ✤ pure HTMLテンプレートが理想 ✤ そのためにはプレゼンテーションロジック だけを分離・独立させることが重要 ✤ Kwartzはそれを実現してるよ! copyright(c) 2010 kuwata-lab.com all rights reserved. 59
  • 60. 謝辞 ✤ RubyKaigi事務局の皆様 ✤ マイナー番組ご視聴の皆様 ありがとうございました copyright(c) 2010 kuwata-lab.com all rights reserved. 60
  • 61. questions? copyright(c) 2010 kuwata-lab.com all rights reserved. 61
  • 62. thank you copyright(c) 2010 kuwata-lab.com all rights reserved. 62