T time

プログラミングや電子工作、各種ガジェットに関するブログです。

LotusでOne-file-applicationを作る(4) - Templateを表示する

前回は、ルーティング情報を追加する方法と、それを元にパスを生成する方法を紹介しました。

今回は、テンプレートを使って情報を表示してみたいと思います。

今回のゴール

http://localhost:2300/mynameis にアクセスすると、テンプレートを表示します。さらにURLクエリにより表示が変わります。

Webブラウザで以下のように表示されます。

f:id:tatur0u:20150624052402p:plain

f:id:tatur0u:20150624052413p:plain

フォルダ構成

以下が、フォルダ構成です。

$ tree -a -L 2 lotus_onefile
lotus_onefile/
├── .bundle/
│   ├── config
│   └── ruby/
├── templates/
│   └── home/
│        └── mynameis.html.erb
├── .lotusrc
├── .ruby-version
├── Gemfile
├── Gemfile.lock
└── config.ru

templates/home/mynameis.html.erb を追加しました。

Template

Lotusを紹介した時に、「静的な情報はテンプレートで表示する」と書きました。

templates/home/mynameis.html.erb ファイルがテンプレートです。

中身はあとで紹介しますが、これは HTML そのもの(+α)です。 「静的な情報」というのはそういうことです。コンテンツによって変更することがない情報をテンプレートで表示します。 たとえば、このブログでいうと、記事の中身は変わりますが、ブログのタイトルや右サイドバーのプロフィール、一番下の「Powered by Hatena Blog」などは記事によって変わることはありません*1。 そういう情報はテンプレートで表示し、記事の中身はビューで表示するのが Lotus のやりかたです。

configu.ru

今回は、コードが configu.ru と mynameis.html.erb に分かれています。 まずは config.ru を見てみましょう。

書き足しているのでずいぶん長くなりました。

以下が追加されたのが分かると思います。

  • ルーティング情報 /mynameis
  • Controllers::Mynameis
  • Views::Mynameis

ルーティング情報とコントローラは今までと変わりませんが、ビューは見慣れない感じです。

Views::Mynameis

このビューには render メソッドがありません。 代わりに template 'templates/home/mynameis' が書いてあります。

これは Lotus::View でテンプレートを指定するための DSL です。

template <テンプレート>

により、このビューが使用するテンプレートを指定しています。

よく見ると、今回追加したファイル templates/home/mynameis.html.erb にそっくりなのが分かると思います。 拡張子以外は全く同じです。

では逆に .html.erb はなぜ省略されているのでしょう。そしてこれは何を示しているのでしょう。

これは、'.(Format).(Engines)' が省略されているのです。

Format

前回、_raw の説明で「render が出力するコンテンツはデフォルトで html と設定されています。 」と書きました。 それがフォーマットです。 そのビューが出力するコンテンツの種類を示しています。

フォーマットを明示的に設定すると、以下のようになります。

module Views
  class Mynameis
    include OneFile::View
    format :html
  end
end

もしビューが JSON を返す場合は format :json を、ATOM を返す場合は format :atom を設定します。 Web API を作る場合は json を指定すれば良いですね。

Engines

これはレンダリングエンジンの指定です。

「テンプレートは静的な情報」と書きましたが、本当に静的な情報しか表示できないと不便です。 例えば、ブログの場合、各ページの構造は静的でもコンテンツは動的な情報です。 そのため、静的な情報と動的な情報を組み合わせて表示できると便利です。

それを実現するのがレンダリングエンジンです。

Lotus ではデフォルトで ERb が設定されています。 ERb は、テキストファイル埋め込まれた Ruby スクリプトを実行することができます。Ruby スクリプトは eRuby の書式で埋め込みます。 ERb を使うと例えば以下の様なことができます。

<html>
  <body>
    1 + 1 = <%= 1+1 %>
  </body>
</html>

これは HTML ファイルですが、<%= %> という見慣れないタグがあります。 これが eRuby の書式です。 この HTML を ERb に通すと、<%= %> 内の文字が Ruby の式として評価され、結果が出力されます。

この例だと以下の様な HTML が出力されます。

<html>
  <body>
    1 + 1 = 2
  </body>
</html>

もちろん、変数も使えますし、<% %> を使用することで制御文も実行できます。

eRuby や ERb の詳しい説明は以下のページを参照してください。

Rubyist Magazine - 標準添付ライブラリ紹介 【第 10 回】 ERB

なお、Lotus は ERb だけではなく、様々なレンダリングエンジンに対応しています。 レンダリングエンジンの一覧は以下を見てください。

github.com

templates/home/mynameis.html.erb

では、テンプレートの中身を見てみましょう。

前半は HTML のコメントです。 後半を見ると以下のようになっています。

<% if params['name'] %>
  ...
<% else %>
  ...
<% end %>

これが eRuby の部分ですね。ERb により以下の ruby コードとして実行されます。

if params['name']
  ...
else
  ...
end

<% %> を取っただけですね。このように Ruby コードがそのまま書けます。

paramsControllers::Home::Mynameis#call の引数です。 ここには URLクエリ が入ってくるのでした。

http://localhost:2300/mynameis?name=Johann にアクセスがあると params['name'] の値は Johann となります。 ? 以下が無い場合、 params['name'] の値は nil となります。 これを利用して、名前の指定がある場合と無い場合で表示を分けています。

コード

今回作ったアプリケーションの全ファイルは、以下から入手できます。

github.com

あとがき

今回は、テンプレートを使って情報を表示する方法を見ました。
おさらいです。

  • テンプレートを使用する場合はビューに template <テンプレート名> を書く
  • テンプレートを使用する場合は render メソッドは必要ない
  • テンプレートのファイル名は '*.html.erb` とする
  • ビューに指定するテンプレート名は .html.erb を省略した名前とする
  • テンプレートは eRuby 記法で記述する

今回で、ひとまず One-file-application の紹介は終わります。

Lotus のきほんの「き」くらいは紹介できたと思いますが、いかがだったでしょうか。 このように Lotus はとても素直なフレームワークで、やりたいことが素直に実現できます。

ただ、今回紹介しただけの機能では、本格的なWebアプリケーションは作れませんね(configu.ru が長いし)。 今度はジェネレータを使用したアプリケーションの作成方法を紹介する予定です。

*1:はてなブログ」というシステムから見ると全てが動的な情報ですが。