[Templates] Streaming Templates

Andy Wardley abw@andywardley.com
Wed, 8 Oct 2003 10:54:40 +0100


Jose Luis Mart?nez wrote:
> Is there any way of making TT stream (or flush parts of the output), 

This has come up on the list a couple of times in the past, and by 
coincidence, I was talking about it just yesterday with James Duncan.  
I can't think of any easy way to implement it *properly* and had all
but concluded that it wasn't possible.

The problem is that if you flush output as it is generated then you break 
the WRAPPER directive and related option.

Having said that, if you don't mind breaking the WRAPPER directive for this
special case, then you might like to try the following.

First, you'll need to get the very latest Template::Directive.pm from
CVS, or hack your own version to change $OUTPUT to a package variable.

  Line 42:
  -use vars qw( $VERSION $DEBUG $PRETTY $WHILE_MAX );
  +use vars qw( $VERSION $DEBUG $PRETTY $WHILE_MAX $OUTPUT );

  Line 48:
  -my $OUTPUT = '$output .= ';
  +$OUTPUT    = '$output .= ';

I'm not sure why I didn't make it a package var in the first place, but
now that it is, you can easily change it from a script.  This variable
is used in all the Perl code generated for the compiled template to 
determine what happens to output.  Usually, it gets concatenated onto 
the '$output' variable (see above), but we're going to change it to 
print the output directly.

   use Template;
   use Template::Directive;

   $Template::Directive::OUTPUT = 'print ';

   my $tt = Template->new();  
   ...etc...

Then you go ahead and use TT as usual.  Any output generated in a template
will be printed directly rather than being built up into a string.  Remember 
that WRAPPER is broken (you'll get the content first, then the wrapper rather
than the content *inside* the wrapper), and some other things too.  For 
example, this won't work [% stuff = INCLUDE somefile %] and the OUTPUT 
option(s) probably won't make much sense.

But if you're not too worried about that or can work around it, then 
perhaps this will do what you want for this special case?

Hope that helps. 

A