「あそんで♪HuggPet」(以下HuggPet)では、開発にFreeMarkerというテンプレートエンジンを使用しています。今回は、FreeMarkerを使った開発を、フロントサイドの視点から少しばかりご紹介したいと思います。
FreeMarkerとは
FreeMarkerはJavaベースのテンプレートエンジンです。FreeMarker Template Languageという言語で書かれたテンプレートファイルとJavaオブジェクトから、動的にHTMLのソースコードを生成することができます。
今回ご紹介するのは、テンプレートファイル(以下FTLファイル)側の基本的な書き方です。「そもそもFreeMarkerってなに?」「どう書けば良いの?」というフロントディベロッパーさんにお読みいただけると良いかもしれません。
FreeMarkerの全体的な機能についての詳細は、ここでは省略させていただきます。
ご興味のある方は、こちらをご参照ください。
FTLファイルの基本
先程も述べた通り、FTLファイルでは動的にHTMLのソースコードを生成できます。まずはサーバサイドから受け取った変数をブラウザに出力してみましょう。下記のようなFTLファイルを用意します。
test.ftl
<!DOCTYPE html> <html lang="ja"> <head> <title>テスト</title> </head> <body> <#-- テスト --> <p>テスト:${hoge}</p> </body> </html>
普通のhtmlファイルのソースコードと違うのは、
<#-- テスト --> <p>テスト:${hoge}</p>この辺りの記述ですね。
ここで、サーバサイドで、変数"hoge"に"fuga"という文字列を設定したとします。
すると、test.ftlのブラウザでの実行結果は
テスト:fugaとなります。"${hoge}"の部分に変数の値が出力されます。
FTLファイルでは、"${(変数名)}"という記述で変数にアクセスできます。変数には、文字列・数値・ブール値・配列・ハッシュ・Date型の値などを入れることができます。
変数の値をHTMLに直接出力する際は、エスケープ処理を忘れないようにしなければなりません。FTLにはエスケープ処理をしてくれるビルトインが用意されていて、
${hoge?html}このように記述すればOKです。
また、コメント文は下のように書きます。
<#-- ここにコメントを書く -->
このように、サーバサイドから値を受け取ってソースコードを動的に生成していくのがFTLファイルの基本的な動きとなります。
それでは、HuggPetのソースコードを見ながら、現場での使用例をご紹介していきます。
"${(変数名)}"の使用例
画像の赤枠の部分は、ユーザーのピグ画像・ペット画像・体力ゲージを表示するモジュールです。この部分のFTLファイルのソースコードは、以下のようになっています。
<#-- ピグ画像・ペット画像 --> <span id="pigg"><img src="${piggImageUrl!'default'?html}"></span> <span id="piggPet"><img src="${synthesizeImage!'default'?html}"></span> <#-- 体力ゲージ --> <div id="piggStamina"> <p class="time">あと${timeOfMaxStamina!?html}で全回復!</p> <dl class="gauge"> <dt style="width: ${(currentStamina / maxStamina * 100)?floor}%"></dt> <dd>${currentStamina!?html}/${maxStamina!?html}</dd> </dl> </div>
imgタグにおける使用
最初のピグ画像・ペット画像の部分を見てみます。<span id="pigg"><img src="${piggImageUrl!'default'?html}"></span> <span id="piggPet"><img src="${synthesizeImage!'default'?html}"></span>画像のsrc属性の値を変数で受け取って、各ユーザーに対応する画像を表示しています。
src="${piggImageUrl!'default'?html}"先程登場したビルトイン"?html"に加えて、"!'default'"という記述があります。この部分ではデフォルト値を設定しています。(省略可能です)
こう書いておくと、万一piggImageUrlの値を正常に受け取れなかった場合、src="default"となります。一部のAndroid端末ではsrc属性が空のimgタグが存在すると画面が正常に動作しないため、デフォルト値の設定が有効です。
数値計算
体力ゲージは、オレンジ色のゲージ部分のwidthを下記のように指定しています。style="width: ${(currentStamina / maxStamina * 100)?floor}%"体力ゲージのmax値(maxStamina)と現在の体力値(currentStamina)を受け取って割合を計算し、数値用のビルトイン"?floor"で数値を切り下げてから、オレンジ色の部分の幅を指定しています。
もう1ヶ所、使用例を見てみます。
こちらは「ひろば」(HuggPet内のサークル機能)のメンバー一覧を表示するモジュールです。
ひろばに所属しているユーザーの情報を、所属している人数分、表示しています。
この一覧部分のソースコードは、以下のようになっています。
※装飾のためのclassやidを省くなど、実際のソースコードより簡易化してあります。
<ul class="members"> <#list memberListPager.list as member> <li> <section> <#-- ユーザー画像・ピグ画像 --> <div> <img src="${member.userImg!'default'?html}"> <img src="${member.petImg!'default'?html}"> </div> <#-- ユーザー情報 --> <div> <p>${member.userName!?html}</p> <#if member.titleName??> <p>称号:${member.titleName!?html}</p> <#else> <p>称号はありません</p> </#if> <p>わざの数: ${member.normalSkillLearnedCount!?html}/ ${member.normalSkillTotalCount!?html}</p> <#if member.eventSkillLearnedCount != 0> <p class="specialSkillCnt">${member.eventSkillLearnedCount!?html}</p> </#if> </div> </section> </li> </#list> </ul>
制御文の使用
FTLファイルでは、if文やswitch文などの制御文が使えます。例の中では、変数の存在を確かめるためにif文を使っています。<#if member.titleName??> <p>称号:${member.titleName!?html}</p> <#else> <p>称号はありません</p> </#if>この<#if hoge??>という書き方は、よく使用します。
変数の後に"??"をつけると、「変数が存在すればtrue」となります。変数が定義されていれば、空の場合でもtrueを返します。この例では、"member.titleName"が存在すれば値が表示され、"member.titleName"が存在しなければ「称号はありません」と表示されます。
因みにこのソースコードには登場しませんが、同じくよく使う記述に
<#if hoge?has_content>というものがあります。こちらも変数が存在する場合にtrueを返しますが、"??"と異なるのは、変数が空のときはfalseを返すことです。
ループ処理
次に、ユーザー情報をリスト表示している大枠の部分です。javascriptなどならfor文で実装するところですが、FTLでは
<ul class="members"> <#list memberListPager.list as member> <li>~省略~</li> </#list> </ul><#list>を使うことで、受け取ったlistの要素数だけ、ループ処理をします。所属しているユーザーの情報を埋め込んだli要素を、ユーザーの数="memberListPager.list"の要素数分出力してくれるわけです。
listの中の値には、<#list>内のas以降に指定した変数名を使ってアクセスできます。この例の中では、member.○○○という書き方をしています。
その他よく使用する記述
その他、HuggPetのFTLファイル内でよく登場する記述をご紹介しておきます。<#assign>
変数を定義します。
<#assign hoge = "fuga"> <p>テスト:${hoge?html}</p>
(出力結果) テスト:fugaといった具合です。
<#compress></#compress>
ホワイトスペースを削除します。ftlソースの一番外側をこれで囲む、というような使い方をしています。
<#include>
ファイルを読み込みます。例えば、共通ヘッダーをheader.ftlというファイル名で作成した場合、各ページでヘッダーを表示したい位置に
<#include "header.ftl">と記述すればOKです。モジュールごとにファイルを分けて管理することができます。
まとめ
今回ご紹介したのは、ほんの一部分の基礎的な機能です。突っ込んだ使い方については、こちらをご確認いただければと思います。
FreeMarker Manual
FreeMarkerは日本語のドキュメントが少ないので、本記事が少しでも参考になれば幸いです。
ここまでお読みいただきありがとうございました。
最後になりますが、「あそんで♪HuggPet」もぜひよろしくお願い致します。スマホで可愛いペットたちと触れ合ってみてください!
![](https://stat.ameba.jp/user_images/20130506/20/ca-1pixel/9c/b2/p/o0600019312528553699.png?caw=800)