David E. Wheeler
2009-11-09 18:47:25 UTC
Shifty Jiftys,
I've been thinking about Template::Declare wrappers since I [blogged](http://www.justatheory.com/computers/programming/perl/catalyst/template-declare-wrapper.html
) about them last week. They just feel way too bolted on. This is my
fault, as I created them without really understanding how
Template::Declare worked. But now that I do understand, I'd like to
propose a new API for wrappers. My inspiration is Mason autohandlers,
FWIW.
First, wrappers would be declared just like other templates, but with
the `wrapper` keyword, like so:
wrapper template wrap => sub {
my $self = shift;
};
As with all other templates, arguments would be passed as normal. They
would also have paths, just like other templates. However, you'd be
limited to one wrapper template per path level per dispatch class.
Thus, given the above wrapper, creating a second one like this would
result in an error:
wrapper template foo => sub {};
Putting the wrapper in a subpath, however, would not cause an error:
wrapper template => 'politics/wrapper' => sub {};
Similarly, mixing in or aliasing templates would mix in and alias
wrappers, and since they'd usually go into subpaths, the limitation of
one wrapper per path level would continue to hold.
The wrapper template would dispatch the rest of the template stack by
calling a method on the invocant, like so:
wrapper template wrap => sub {
my $self = shift;
html {
body {
$self->next;
};
};
};
`next` may or may not be a great name for the method. But the
advantage is that it would dispatch other wrapper templates found in
the paths, just like Mason autohandlers (though no inheritance). So
say that we have the wrap wrapper template above, and then
wrapper template 'politics/wrapper => sub {
my $self = shift;
h1 { 'Politics' }
div {
id is 'politics';
$self->next;
};
};
Then say that we have a couple of standard templates:
template story => sub {
my $self = shift;
for my $p (@args) { p { $p } }
};
template politics/story => sub {
my $self = shift;
div { 'Send feedback to us!' };
for my $p (@args) { p { $p } }
}
Then executing the 'story' template would yield output like this:
<html>
<body>
<p>first graph</p>
</body>
</html>
And executing the 'politics/story' template would yield something like:
<html>
<body>
<h1>Politics</h1>
<div>Send feedback to us!</div>
<div id="politics">
<p>first graph</p>
</div>
</body>
</html>
Thoughts?
Best,
David
I've been thinking about Template::Declare wrappers since I [blogged](http://www.justatheory.com/computers/programming/perl/catalyst/template-declare-wrapper.html
) about them last week. They just feel way too bolted on. This is my
fault, as I created them without really understanding how
Template::Declare worked. But now that I do understand, I'd like to
propose a new API for wrappers. My inspiration is Mason autohandlers,
FWIW.
First, wrappers would be declared just like other templates, but with
the `wrapper` keyword, like so:
wrapper template wrap => sub {
my $self = shift;
};
As with all other templates, arguments would be passed as normal. They
would also have paths, just like other templates. However, you'd be
limited to one wrapper template per path level per dispatch class.
Thus, given the above wrapper, creating a second one like this would
result in an error:
wrapper template foo => sub {};
Putting the wrapper in a subpath, however, would not cause an error:
wrapper template => 'politics/wrapper' => sub {};
Similarly, mixing in or aliasing templates would mix in and alias
wrappers, and since they'd usually go into subpaths, the limitation of
one wrapper per path level would continue to hold.
The wrapper template would dispatch the rest of the template stack by
calling a method on the invocant, like so:
wrapper template wrap => sub {
my $self = shift;
html {
body {
$self->next;
};
};
};
`next` may or may not be a great name for the method. But the
advantage is that it would dispatch other wrapper templates found in
the paths, just like Mason autohandlers (though no inheritance). So
say that we have the wrap wrapper template above, and then
wrapper template 'politics/wrapper => sub {
my $self = shift;
h1 { 'Politics' }
div {
id is 'politics';
$self->next;
};
};
Then say that we have a couple of standard templates:
template story => sub {
my $self = shift;
for my $p (@args) { p { $p } }
};
template politics/story => sub {
my $self = shift;
div { 'Send feedback to us!' };
for my $p (@args) { p { $p } }
}
Then executing the 'story' template would yield output like this:
<html>
<body>
<p>first graph</p>
</body>
</html>
And executing the 'politics/story' template would yield something like:
<html>
<body>
<h1>Politics</h1>
<div>Send feedback to us!</div>
<div id="politics">
<p>first graph</p>
</div>
</body>
</html>
Thoughts?
Best,
David