• 検索結果がありません。

#7 ビュー(View) 山田さん GCRアーカイブ main

N/A
N/A
Protected

Academic year: 2018

シェア "#7 ビュー(View) 山田さん GCRアーカイブ main"

Copied!
4
0
0

読み込み中.... (全文を見る)

全文

(1)

ビュー

出典: AgileKnowledge

grailsのビュー (ここでのビューとはMVCのV, Webプレゼンテーション層) の仕組みを見 てみます.

目次

1 grailsのビュー 1.1 grails tagとは?

1.2 JSP tagとどこが違うのか? 2 grails tagの定義

2.1 Dynamic Tag Library 2.2 artefactとしてのTagLib 2.3 Syntax Tag

3 GSPパーサ

3.1 GSP中のgrails tag 3.2 GSPの他の構文要素

grailsのビュー

grailsのビューはおもに, GSPとgrails tagを使って実現されています. GSP (groovy server pages) はその名前の通り, JSP (Java Server Pages) によく似た技術です. grails tagは同じようにJSPで使われているtaglibに相当します (grailsでもtaglibと呼ばれていま す. JSPのtaglibと区別するためにgrails tagと呼ぶことにします). grails tagはおおざっぱ に言えば, groovyコードを呼び出すHTML用のマクロですね.

grails tagとは?

例えばscaffoldに使われるテンプレート

(http://svn.grails.codehaus.org/browse/grails/trunk/grails/src/grails/templates/scaffolding を見てみましょう (テンプレートのマクロとGSPのマクロが混在しているので分かりにく

いかもしれませんが...). ここにはscaffoldで生成されるWebページのテンプレート ({create,edit,list,show}.gsp) があります.

この中で<g:...> ... </g:...>がgrails tagを使っている部分です.

JSP tagとどこが違うのか?

grails tagとJSP tagがどこがどう違うのでしょう. grails.org―Tag+Library+Reference (http://grails.org/Tag+Library+Reference) によれば, 例えば次のような違いがありま す.

パラメータの${...}の中はgroovyコード (JSPではJSTL式言語) カスタム・タグを書くのが簡単 (JSP tagは手間が多くて, 非直感的) GStringが使える (JSP tagでは<c:out value=... />)

上原さんの日記d.hatena.ne.jp―20071226 (http://d.hatena.ne.jp/uehaj/20071226) も参考になるでしょう.

要は, JSP tagに較べてgrails tagは「読みやすく, 書きやすい」と言っていいと思います. ただし基本的な考え方は似ており, JSPに較べて画期的なビュー技術だとまでは言えない, ということがこのページを読めば分かるでしょう.

grails tagの定義

grails tagは以下の場所で実装されています. org.codehaus.groovy.grails.web.taglib

(http://svn.grails.codehaus.org/browse/grails/trunk/grails/src/web/org/codehaus/groovy/grails/web/taglib 1.

org.codehaus.groovy.grails.plugins.web.taglib

(http://svn.grails.codehaus.org/browse/grails/trunk/grails/src/groovy/org/codehaus/groovy/grails/plugins/web/taglib 2.

org.codehaus.groovy.grails.web.taglib.jsp

(http://svn.grails.codehaus.org/browse/grails/trunk/grails/src/web/org/codehaus/groovy/grails/web/taglib/jsp 3.

またユーザが定義したカスタム・タグXXXは, XXXTagLib.groovyとして<grails-app> /grails-app/taglibに置きます.

Dynamic Tag Library

まずはユーザがgroovyで書いて追加する, カスタム・タグ (カスタム・タグの集まりは dynamic tag libraryと呼ばれる) から見てみることにしましょう (カスタム・タグの書き 方はGrails - Dynamic Tag Libraries (http://grails.org/Dynamic+Tag+Libraries) にあ ります).

カスタム・タグと同じ構造を持つ, 組込みのgrails tagはgrails tagの定義(2)の場所で定義 されています. 例えばFormatTagLibを見てみましょう.

!!"#$%&'!(#)$*)+*$"+&%,!-..

!!!+/!0001"#$%&'+$221*$"&%,13..4$"5%,0"#..67

(2)

要素を持たないタグは一引数のクロージャとして表されています. 要素を持たないタグとは

のように使われるタグです. 例えば次のように定義します.

クロージャ名がタグ名を表しています. 唯一の引数, attributesはタグ属性の詰まったMap です.

クロージャ内に上記のようなコードがあります. ここでは...の部分が「そのまま」(評価さ れて) GSP中のタグ部分に置き換わります.

さて, ここで (grailsに付きものの) 謎がひとつあります. outはどこから来たのでしょう? その他にも見慣れない何かが漂っていますね:-) それについては後で見ることにしましょう. 一方, 要素を持つタグは二引数のクロージャとして表されています. 要素を持つタグとは

のように使われるタグです. 例えば次のように定義します.

ここで, bodyは要素を処理するクロージャです (今の例だったら<baz>...</baz>の部分を処 理してくれます). body()として呼び出せば, 要素を評価した文字列が返されることになり ます. またbodyに渡された引数はGSP上のタグ中では${it}として参照できます.

タグを定義するクロージャ (例えば上記のfoo) はそのままGSP上のタグ中でメソッドとし て, "${foo()}"のように呼び出すこともできます.

このように, GSP上でのDynamic Tag Libraryは, groovyのクロージャを活かした, 非常 に単純かつ強力なメカニズムです.

artefactとしてのTagLib

上のようにして定義するTagLibはartefactの一種です.

artefactとは何だったでしょう? 前のpluginのときの話を思い出してみて下さい. artefact

8"9-..!2$#$:;<=,$#=!2$#$:><=,$?=!1/

@)-!-..!<!A!$**#%,B*)'!+/!000!C

.B*!88!=000=

8"9-..!2$#$:;<=,$#=/

!!!!!!!!8,$?/!000!81,$?/ 81"9-../

@)-!-..!<!A!$**#%,B*)'D!,.@7!+/!000!C

とはgrailsが作って (create-xxx) 管理する特別な種類のオブジェクトのことです. domain class, controller, serviceなどみんなartefactの例です.

artefactとしてのTagLibは以下の場所で定義されています. org.codehaus.groovy.grails.commons

(http://svn.grails.codehaus.org/browse/grails/trunk/grails/src/commons/org/codehaus/groovy/grails/commons TagLibArtefactHandler

GrailsTagLibClass DefaultGrailsTagLibClass

XXXTagLibクラス中に, 上で述べたoutのようなものを実際にinjectしているのは ControllersGrailsPlugin

(http://fisheye.codehaus.org/browse/grails/trunk/grails/src/groovy/org/codehaus/groovy/grails/plugins/web/ControllersGrailsPlugin.groovy

#doWithDynamicMethodsです. 今のところtaglibはcontrollerと切り離せないみたいで すね.

Syntax Tag

Javaで書かれた組込みのタグも見てみることにしましょう. これらはdef, if, whileなどお もに構文的な面を定義しているタグなのでまとめてSyntax Tagとも呼ばれています. Syntax Tagはgrails tagの定義(1)の場所で定義されています. Syntax Tagは, ひとつのタ グごとにGrailsTagインタフェースをimplementsしたJavaクラスで書かれています. GrailsTagインタフェースで定義されているメソッドは以下の通りです. つまり, 各タグは 以下のメソッドを定義しなければなりません. でも各メソッドの意味はほとんど自明です ね.

6.%@!%E%*FG$2!*$"H.E*)I*J 6.%@!')*K#%*)#FK#%*)#!LJ

6.%@!')*M**#%,B*)'FG$2!$**#%,B*)'J

6.%@!')*M**#%,B*)FN*#%E"!E$:)D!O,P)(*!6$&B)J 6.%@[email protected]*$#*4$"FJ

6.%@[email protected]@4$"FJ N*#%E"!")*R$:)FJ

例えば<g:if>を定義しているクラスを見てみましょう (他のSyntax Tagである, (.&&)(*,

@)-, )$(S, LS%&), %-1)&')1)&')%-, -%E@M&&, "#)2もみな同じです).

これに対応するタグはGSP中では以下のように使われます.

(&$''!T#..67U-4$"!)I*)E@'!T#..67N7E*$I4$"!A!000!C

(3)

これが以下のように展開されるはずです (GSP中にgroovyコードとして埋め込まれる).

ちなみにここにある他のクラスは以下のようなものです.

GroovyInputTag extends RequestContextTag (renderInput) これは今は使われていない (2006年秋 deprecated) GroovyPageTagBody

XXXTagLibで使われるbodyクロージャを表すクラス GrailsTagRegistry

定義されているタグの格納庫

GSPパーサ

さて, タグはおもにDynamic TagとSyntax Tagがあり, それぞれどのようにして定義され ているか, どのように定義すればいいかが分かったとして, ではいったい誰がこれらのクラ スを呼んでいるのでしょう?

それがGSPパーサ (org.codehaus.groovy.grails.web.pages.Parse

(http://svn.grails.codehaus.org/browse/grails/trunk/grails/src/web/org/codehaus/groovy/grails/web/pages/Parse.java ) です. 少し見てみましょう.

ParseはTokensインタフェースをimplementしています. Tokensインタフェースでは以 下のようなトークンを定義しているだけです. つまりGSPはこういう構文要素を持ってい ると考えてよさそうです.

'*$*%(!-%E$&!%E*!QO3!<!+;V '*$*%(!-%E$&!%E*!W4G5!<!XV

'*$*%(!-%E$&!%E*!YQZ[\!<!;V!11!8!<!000!!/ '*$*%(!-%E$&!%E*!YNH\U[4!<!>V!11!8!!0000!!/ '*$*%(!-%E$&!%E*!Y]U\QH4!<!^V!11!8!_!000!!/ '*$*%(!-%E$&!%E*!Y]QH5M\!<!`V!11!8!a!000!!/ '*$*%(!-%E$&!%E*!TQZ[\!<!;;V!11!bA!000!C '*$*%(!-%E$&!%E*!TNH\U[4!<!;>V!11!!A!000!C! '*$*%(!-%E$&!%E*!T]U\QH4!<!;^V!11!_A!000!C '*$*%(!-%E$&!%E*!T]QH5M\!<!;`V!11!aA!000!Ca '*$*%(!-%E$&!%E*!TN4M\4c4MT!<!;dV!11!8"900/

8"9%-!*)'*<=000=!)E6<=000=/

!!!!000 81"9%-/

%-FFT#$%&'e*%&0)E6%#.E:)E*!<<!)E6J!ff!F*)'*JJ!A!000!C

'*$*%(!-%E$&!%E*!TQR]c4MT!<!;gV!11!81"900/ '*$*%(!-%E$&!%E*!T4MTcQZ[\!<!;hV!11!bA00C

GSP中のgrails tag

さて, Parse#page()を見てみると, <g:...>, </g:...>に対応してそれぞれstartTag(), endTag ()を呼んでいます. Syntax Tagの場合にはGrailsTag#doStartTag(), doEndTag()を呼び 出しています. 一方そうでないタグ (Dynamic Tag) の場合には, 次のような文字列を吐き 出しています.

ここでinvokeTagはorg.codehaus.groovy.grails.web.pages.GroovyPage

(http://svn.grails.codehaus.org/browse/grails/trunk/grails/src/web/org/codehaus/groovy/grails/web/pages/GroovyPage.java のメソッドです.

パーサParse.javaをもっとよく見てみます. まずコンストラクタがあります. パーサとして の入り口はparse()のようです. 中を読むとどうやら, parse()はGSPページをgroovyコー ドに変換するらしい (この辺はJSPと同じですね).

では, どんなコードに変換されているか, 実際に見てみることにしましょう. 簡単なgrailsア プリケーションを作り, log4jの設定を変えます.

次に適当なドメイン・クラスを作って, ")E)#$*)+$&&して, #BE+$22すると, コンソールに以 下のようなコードが流れるはずです.

都合によりお見せできません. 自分でやってみて下さい.

つまり, JSPと同じく, GSPはGSPページをまずは対応するgroovyコードに変換し, GSP ページ中に埋め込まれたgroovyコード断片を正当なクラスとして構成し, それをコンパイ ルして走らせると, 埋め込まれたgroovyコードも含めて展開 (評価) されたHTMLが文字列 として返される, という仕組みなのですね.

.B*02#%E*&EF=,.@7=i*$"UE@)Ii=!<!E)L!T#..67[$")4$"j.@7F*S%'D,%E@%E"0L),\)kB)'*J!A=!JV .B*02#%E*&EF=C=JV

%-F*:0S$'M**#%,B*)'J!A

!!!!.B*02#%E*&EF=%E6.l)4$"Fm=i*$"R$:)i=mDm=iE'i=mD$**#'=i*$"UE@)Ii=D,.@7=i*$"UE@)Ii=J=JV C!)&')!A

!!!!.B*02#%E*&EF=%E6.l)4$"Fm=i*$"R$:)i=mDm=iE'i=mDn9oD,.@7=i*$"UE@)Ii=J=JV C

8"#$%&'!$22/1"#$%&'+$221(.E-1H.E-%"0"#..67

!!!000

!!!&."`P!A

!!!!!!!000

!!!!!!!.#"!A

!!!!!!!!!!!000

!!!!!!!!!!!(.@)S$B'0"#..670"#$%&'0L),02$")'<=@),B"=!11!!TN[

!!!!!!!!!!!000

!!!!!!!C

!!!!!!!000

!!!C

!!!000

(4)

ここでGroovyPage#invokeTag() (org.codehaus.groovy.grails.web.pages. GroovyPage

(http://svn.grails.codehaus.org/browse/grails/trunk/grails/src/web/org/codehaus/groovy/grails/web/pages/GroovyPage.java ) は以下のようなことをやっているようです.

引数はタグ名, タグの名前空間名, 属性のMap, bodyクロージャ artefactとしてのTagLibを探してきて, 呼び出す

面倒くさくなってきましたが, 更にもう少し遡ってみるとこんな感じです. GroovyPagesServlet

(org.codehaus.groovy.grails.web.pages.GroovyPagesServlet

(http://svn.grails.codehaus.org/browse/grails/trunk/grails/src/web/org/codehaus/groovy/grails/web/pages/GroovyPagesServlet.java )

servletの受け口

doGet()/doPost() -> doPage() -> renderPageWithEngine() -> GroovyPagesTemplageEngine()#createTemplate()

GroovyPagesTemplateEngine

(org.codehaus.groovy.grails.web.pages.GroovyPagesTemplateEngine

(http://svn.grails.codehaus.org/browse/grails/trunk/grails/src/web/org/codehaus/groovy/grails/web/pages/GroovyPagesTemplateEngine.java )

GroovyPageMetaInfoを作って (buildPageMetaInfo()), new GroovyPageTemplateを返す

buildPageMetaInfo()では, パースして (前述), パースしたものをコンパイルして (前述), それらを元にGroovyPageMetaInfoを作り, pageCacheに入れる reloadableでない場合 (かつ変更がない場合) にはこのキャッシュを利用している GroovyPageTemplate (org.codehaus.groovy.grails.web.pages.

GroovyPageTemplate

(http://svn.grails.codehaus.org/browse/grails/trunk/grails/src/web/org/codehaus/groovy/grails/web/pages/GroovyPageTemplate.java )

中身は大してない. 後はresponseとして返すだけ.

GroovyPageMetaInfo (org.codehaus.groovy.grails.web.pages. GroovyPageMetaInfo

(http://svn.grails.codehaus.org/browse/grails/trunk/grails/src/web/org/codehaus/groovy/grails/web/pages/GroovyPageMetaInfo.java )

ページに対応したgroovyコード (前述) とそのメタ情報を持っている

GSPの他の構文要素

grails tag以外のGSPの構文要素についてもざっと眺めておきましょう.

8!<!000!!/はJSPのスクリプトレットと同じで, ...の部分を文字列として, groovyページ (というか, GSPページをgroovyクラスに変換したもの) に埋め込みます. 8!!000!!/, 8!a! 000!!/もJSP由来のもので, 中身も同じようなものです.

8!_!000!!/, _A000C はJSPでいうpage directiveを表しています. とりあえず有効なディレ クティブは, %:2.#*, (.E*)E*472), @)-$B&*H.@)(の三つのようです.

bA000C, !A000C, aA000CはGroovy ScriptletでJSPのスクリプトレットとほぼ同じです. 以上が, grailsのビュー周り, Webプレゼンテーションのレイヤの概要です. ただし, grails でアプリケーションを作る場合には必ずしもGSPを使わなければならないと言うことはあ りません. Wicket (http://grails.org/Wicket+Plugin) やOpenLaszlo

(http://grails.org/OpenLaszlo+plugin) を使うプラグインも提供されています (完成度は おいておいて).

"http://wiki.metabolics.co.jp/index.php/%E3%83%93%E3%83%A5%E3%83%BC" より作成

最終更新 18:25, 2008年1月26日 (日)。

コンテンツはAttribution-NonCommercial-ShareAlike 2.1 Japan Licenseのライセンスで利用することができます。

参照

関連したドキュメント

のようにすべきだと考えていますか。 やっと開通します。長野、太田地区方面  

本装置は OS のブート方法として、Secure Boot をサポートしています。 Secure Boot とは、UEFI Boot

春から初夏に多く見られます。クマは餌がたくさんあ

点から見たときに、 債務者に、 複数債権者の有する債権額を考慮することなく弁済することを可能にしているものとしては、

手動のレバーを押して津波がどのようにして起きるかを観察 することができます。シミュレーターの前には、 「地図で見る日本

基準の電力は,原則として次のいずれかを基準として決定するも

・私は小さい頃は人見知りの激しい子どもでした。しかし、当時の担任の先生が遊びを

下山にはいり、ABさんの名案でロープでつ ながれた子供たちには笑ってしまいました。つ