テンプレートのレイアウトの話 。例えば…
- デフォルトは2カラムで右側にサイドバー
- でも
about
ページとかは1カラムにしたい
っていう要望よくあると思うんですよ。でMojoliciousの Mojolicious::Plugin::DefaultHelpers
の中からヘルパーメソッドをいくつかチョイスして使えば実現可能です。ただ、ついつい分かりやすい layout
と include
メソッドだけを使ってこねくり回す感じでいわば強引に上記の1カラムと2カラムの切り替えを僕は以前やっていました。すると include するためのパーツをいくつも切り分けなくてはいけなくてちょっと管理が煩雑になるので最近使ってる手法を紹介します。
content
メソッドと extends
メソッドを使います。アプリの本体はMojolicious::Liteでこのように短く書いてみます。
#!/usr/bin/env perl
use Mojolicious::Lite;
get '/' => sub { shift->render('index') };
get '/about' => sub { shift->render('about') };
app->start;
/
にアクセスされたらデフォルトの2カラム、/about
にアクセスが来たら1カラムで表示してみましょう。
まず、2カラムでも1カラムでも共通で使う 外枠 のラッパーを定義します。
@@ layouts/wrapper.html.ep
<!DOCTYPE html>
<html>
<head><title>Hello Mojolicious</title></head>
<body>
% content container => begin
<%= content %>
% end
%= content 'container'
</body>
</html>
content
メソッドの中で一度「container」という名前でこれからつくる /layouts/default
と /layout/one_column
の内容を読み込ませてすぐさま表示しています。次にデフォルトの2カラム、そして1カラムのテンプレートを書きます。
@@ layouts/default.html.ep
% extends 'layouts/wrapper';
% content container => begin
<div><%= content %></div>
<div id="sidebar">sidebar</div>
% end
%= content 'container'
@@ layouts/one_column.html.ep
% extends 'layouts/wrapper';
% content container => begin
<div><%= content %></div>
% end
%= content 'container'
extends
メソッドで例の layouts/wrapper
を呼び出して「container」という名前でテンプレートの実態を渡しています。これで
- 一番外側がlayouts/wrapper
- 中身はそれぞれlayouts/default, layouts/one_columnで実装
することが叶えられるのです。最後に、個別のテンプレート、つまりコントローラから呼び出されるモノについて書きましょう。ここは特に意識することなく layout
メソッドで default
もしくは one_column
を指定するだけです!
@@ index.html.ep
% layout 'default';
2 cloumns!!
@@ about.html.ep
% layout 'one_column';
1 cloumn!!
ちょいラッパーとその中身をつくる仕掛けが複雑ですが、一度定義してしまえば、個別のテンプレートは layout
メソッドで切り替えるだけでよいのでこれはなかなか良いですね。他にテンプレートの応用の仕方がありましたら本Advent Calendarにて記事を書いてくれると嬉しいっす!