Pre-Render Template at Squatting start-up
In previous post I mentioned that you could build a static CSS file from a template when Squatting first starts up.
Well here’s a complete example using Template Toolkit ( CSS.pm )….
use strict; use warnings; { package CSS; use base 'Squatting'; use Template; BEGIN { our %CONFIG = ( docroot => './www', # Continuity htdocs static => '/static', # Our unique prefix/folder under above pre_render => { # CSS profile css => { tt => 'css.tt', # CSS template file => 'static.css', # Name of static file to build v => { # template variables colour => 'red', }, }, # Other pre render template profile... # js => { ... }, # jquery => { ... }, }, TT => { object => Template->new( INCLUDE_PATH => './tt' ), postfix => '.tt', site_tit => 'Static CSS demo', }, ); } # static file handling sub continue { my $app = shift; $app->next::method( docroot => $CSS::CONFIG{ docroot }, staticp => sub { $_[0]->url =~ m/\.(jpg|jpeg|gif|png|css|ico|js|swf)$/ }, @_ ); } # pre-render stuff # for eg. lets build the CSS file on startup as ./www/static/static.css my $tt = $CSS::CONFIG{ TT }->{ object }; my $prefix = $CSS::CONFIG{ docroot } . $CSS::CONFIG{ static } . '/'; for my $key ( keys %{ $CSS::CONFIG{ pre_render } } ) { my $render = $CSS::CONFIG{ pre_render }->{ $key }; open my $fh, '>', $prefix . $render->{ file } or die "Unable to write to $render->{file}: $!"; $tt->process( $render->{ tt }, $render->{ v }, $fh ) or die "Help!\n"; close $fh; } } { package CSS::Controllers; use Squatting ':controllers'; our @C = ( C( Home => [ '/' ], get => sub { my ( $self ) = @_; $self->render( 'home' ); }, ), ); } { package CSS::Views; use Squatting ':views'; our @V = ( V( 'tt', tt => $CSS::CONFIG{ TT }->{ object }, layout => sub { my ( $self, $v, $body ) = @_; my $tt = $self->{ tt }; $v->{ site_tit } = $CSS::CONFIG{ TT }->{ site_tit }; $v->{ body } = $body; my $output; $tt->process( 'layout'. $CSS::CONFIG{ TT }->{ postfix }, $v, \$output) or return view_error( $tt->error ); return $output; }, _ => sub { my ( $self, $v ) = @_; my $tt = $self->{ tt }; $v->{ R } = \&R; $v->{ Static } = $CSS::CONFIG{ static }; my $output; $tt->process( $self->{template} . $CSS::CONFIG{ TT }->{ postfix }, $v, \$output) or return view_error( $tt->error ); return $output; }, ), ); sub view_error { my ( $error ) = shift; warn $error; return "<pre>" . $error . "</pre>\n"; # should HTML encode } } 1;
$CSS::CONFIG{ pre_render } contains all the profiles to pre-render on. You just need to name a profile and tell it what template (tt), what static filename should be (file) & provide variables for the rendering (v)….
# CSS profile css => { tt => 'css.tt', # CSS template file => 'static.css', # Name of static file to build v => { # template variables colour => 'red', }, },
So above renders css.tt to ./www/static/static.css
Here is an example css.tt
h1 { color: [% colour %]; }
And to make things complete here the other templates (all in ./tt folder)….
# layout.tt <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <title>[% site_tit %]</title> <link rel="stylesheet" href="[% Static %]/static.css" type="text/css" /> </head> <body> [% body %] </body> </html> # home.tt <h1>This should be red</h1>
And if all works fine then you will see “This should be red” in red π
/I3az/
NB. This example should only be used with single occurrence of your App running with Squatting::On::Continuity. For multiple occurrences then ideally you need to take care when writing to static file (ie. only write when changed or need locking or have unique static files for each occurrence).