Skip to content

Instantly share code, notes, and snippets.

@niczero
Last active August 29, 2015 14:02
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save niczero/12e8e07bc0b231324716 to your computer and use it in GitHub Desktop.
Save niczero/12e8e07bc0b231324716 to your computer and use it in GitHub Desktop.
Feature Request: Assignable layouts with extending templates

Summary

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.

Use Case 1: Default layout

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.

Use Case 2: Dynamic layout

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.

Benefits

Now two important rendering features can be combined.

Costs

A couple of extra tests are needed.

Breakage

I think the only thing that breaks is where someone writes a base template assuming that their layout would be ignored. But

  1. that is not documented behaviour,
  2. they were probably doing it to workaround not being able to use (dynamic) layouts,
  3. there is an easy fix (% layout undef),
  4. it is probably better design to make such templates true layouts.

Example

#!/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>};

Feature Branch

https://github.com/niczero/mojo/compare/dynamic_layout_selection

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment