メソッドの名前と引数の名前に使用できる名前には制限があります。詳しくは下記を参照してください。
5章 テンプレート - 6. テンプレートの展開
テンプレートにはメソッドを定義することができます。メソッドは、展開と同じように作成できるものですが、メソッド名を付けることができ、関数のように呼び出すことができます。また、引数をとることができます。
メソッドを作成するときには、メソッド画面で「追加」ボタンをクリックします。
メソッドを作成すると下図のような画面が表示されます。この画面を使ってメソッドを定義して行きます。
① 左下のエリアにはメソッド一覧が表示されます。メソッド名をクリックするとそのメソッドの定義を編集できるようになります。
② メソッドを作成した直後は、メソッドの名前は untitled() となっています。 まず、この名前を、好きな名前に付け替えてください。メソッド名は、そのメソッドの内容がよくわかる名前にするとよいでしょう。
③ メソッド名の右側に「Private」というチェックボックスがあります。このチェックを ON にすると、そのメソッドは、そのテンプレートまたはコンポーネント外からは呼び出すことができない、テンプレートまたはコンポーネント内でのみ利用できるプライベートなメソッドとして定義されます。メソッドをプライベートにしておくことで、そのメソッドを将来メンテナンスする際に、そのメンテナンスの影響範囲をそのメソッドが定義されているテンプレートやコンポーネント内に限定して考えることができるようになります。外部から呼び出されることを前提としていないメソッドには Private の指定をしておくと良いでしょう。
④ メソッドには、引数を持たせることができます。引数の個数は任意個ですが、可変個数の引数をとる(いわゆる varargs の)メソッドは定義できません。例えばメソッドに三つの引数を持たせた場合、そのメソッドを呼び出す時には必ず三つのパラメタを与えなければなりません。
ひとつのテンプレート中にメソッドはいくつでも定義することができます。メソッド名は互いに衝突しないようにしてください。異なるテンプレートが同じ名前のメソッドを持っていてもかまいませんが、ひとつのテンプレート中に同じ名前のメソッドが複数定義されていると、メソッドが呼び出せなくなります。 パラメタの個数が異なっていても、同じ名前のメソッドを同じテンプレート内に複数定義することはできません。
ここでは drawImage(img, alt) というメソッドを定義してみましょう。このメソッドは、イメージと ALT 属性から対応する img タグを生成する簡単なメソッドです。
① メソッド名の欄でメソッドの名前と引数を指定します。
drawImage(img, alt)
② テキストエリアにこのメソッドの展開を記述します。メソッドの展開部分の記述方法はテンプレートの展開の記述方法と同じです。
<img src="%img% alt="%alt%" style="width: %width(img)%px; height: %height(img)%px;">
ご覧のとおり、このメソッドの本体は1行しかありません。与えられた引数を使って img タグを生成しています。メソッドの展開の中では、引数を変数として参照可能です。引数の参照方法は、要素参照と同じです。
③ 定義を作成したら画面右上の「保存」ボタンをクリックします。
今度は、このメソッドを展開の中から呼び出してみましょう。展開中から同じテンプレート中にあるメソッドを呼び出す時には、あたかもそれが関数であるかのように呼び出します。
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=%encoding()%">
<title>%pageTitle()%</title>
</head>
<body>
<wr-for list="pictures" variable="x">
%drawImage(x.img, x.alt)%
</wr-for>
</body>
</html>
このテンプレートを使ってページを作成し、1枚だけ画像を設定した状態で生成される展開結果は、例えば下記のようになります。
<!doctype html>
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<title>無題</title>
</head>
<body>
<img src="..........jpg" alt="栗の写真" style="width: 960px; height: 540px;">
</body></html>
ここでもうひとつメソッドを定義してみます。メソッド名は drawImage2(img) としてみました。今度は、パラメタをひとつにし、そこにグループ項目「pictures」をそのまま渡しています。メソッドへの引数には任意のオブジェクトを渡すことができます。
drawImage2(picture)
<img src="%picture.img%" alt="%picture.alt%" style="width: %width(picture.img)%px; height: %height(picture.img)%px;">
この場合、展開中でのメソッド呼び出しは、下記のようになります。
<html>
<body>
<wr-for list="pictures" variable="x">
%drawImage2(x)%
</wr-for>
</body>
</html>
今度は、目次を経由して他のページのメソッドを呼び出してみましょう。「記事一覧」というテンプレートで作成された記事一覧を表示するページに「ニュースリリース」というテンプレートで作成されたページ群と「ニュース」というテンプレートで作成されたページ群の一覧を表示してみましょう。
① まず「ニュースリリース」という名前のテンプレートを作成します。
② このテンプレートには「概要」という名前の要素が定義されています。記事の概要がこの要素に入力されます。
③ この「ニュースリリース」テンプレートには summary() というメソッドを定義してあります。このメソッドは、呼び出されると「概要」の内容を展開結果に書き込むようになっています。
%概要%
もうひとつテンプレートを使います。
① もうひとつ「ニュース」という名前のテンプレートを作成します。
② このテンプレートには「リード文」という名前の要素が定義されています。記事の概要がこの要素に入力されます。
③ この「ニュース」テンプレートにも summary() というメソッドが定義してあります。このメソッドは、呼び出されると「リード文」の内容を展開結果に書き込むようになっています。
%リード文%
最後にもうひとつ「記事一覧」というテンプレートを作成します。このテンプレートは「ニュース」または「ニュースリリース」のいずれかのテンプレートで作成されたページの一覧を表示します。
このテンプレートには「index」という名前の目次型の要素が定義されています。この目次の掲載対象に、先の「ニュース」と「ニュースリリース」が指定されています。
このテンプレートの展開は下記のように書くことができます。
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=%encoding()%">
<title>%pageTitle()%</title>
</head>
<body>
<wr-for list='index' variable='aPage'>
<a href="%aPage%">%aPage.summary()%</a><br>
</wr-for>
</body>
</html>
aPage が指し示すページは「ニュース」で作成されたページか、または「ニュースリリース」で作成されたページのいずれかです。記事の概要が入力されている要素は「ニュース」の場合には「リード文」であり、また、「ニュースリリース」の場合には「概要」ですが、summary() というメソッドが違いを吸収しているので展開の記述が非常に簡潔になっています。
目次に限らず、リンク要素でも同様にリンク先ページのメソッドを呼び出すことができます。また、何らかの方法で入手した Page オブジェクトに対しても、同じ方法で相手先のメソッドを呼び出すことができます。
この例で、テンプレート「ニュースリリース」に定義されているメソッド summary() が、「ニュースリリース」側で Private に指定されている場合は、このような方法で外部から summary() を呼び出すことはできません。
テンプレートやコンポーネントの展開やメソッドからは、コンポーネントに定義されているメソッドを呼び出すことができます。コンポーネントに関しては下記を参照してください。