[jifty-devel] RFC: Improved Template::Declare Wrappers

David E. Wheeler david at kineticode.com
Mon Nov 9 13:47:25 EST 2009


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








More information about the jifty-devel mailing list