Template reuse is awesome, either via extending templates or via layouts. But what about together? A tiny change to rendering allows them to be combined, which makes it even easier to design, manage, and maximise reuse of templates.
The Rendering Guide clearly shows the value of setting a default layout and also the value of template inheritance (using 'extends'), but currently these can't be used together: the default layout is ignored and therefore missing from the rendered output.
On a rapidly growing web app I have three layouts: unauthenticated user, authenticated user, admin user. They govern the theme and mostly the head and foot of the page, and are largely independent of the content of the page.
On that app I have started using template inheritance to factor out shared boilerplate from the heart of the page. A prime example is my result_set template which sets up the structure and styles to support a jQuery datatable. So at render-time I want to specify the session-driven layout and the small template which extends the content-driven template.
Now two important rendering features can be combined.
A couple of extra tests are needed.
I think the only thing that breaks is where someone writes a base template assuming that their layout would be ignored. But
- that is not documented behaviour,
- they were probably doing it to workaround not being able to use (dynamic) layouts,
- there is an easy fix (% layout undef),
- it is probably better design to make such templates true layouts.
#!/usr/bin/env perl
use Mojolicious::Lite;
get '/' => sub {
my $self = shift;
$self->render('index');
};
app->defaults(layout => 'default');
app->start;
__DATA__
@@ layouts/default.html.ep
<!DOCTYPE html>
<html>
<head><title><%= title %></title></head>
<body><%= content %></body>
</html>
@@ structure.html.ep
<ul>
<li>Welcome to the Mojolicious real-time web framework!</li>
<li>We <%= content sentiment => q{like} %> template re-use!</li>
</ul>
@@ index.html.ep
% extends 'structure';
% title 'Welcome';
% content sentiment => q{<strong>LOVE</strong>};
https://github.com/niczero/mojo/compare/dynamic_layout_selection