Skip to content

Pre-Render Template at Squatting start-up

December 23, 2008

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).

Advertisement
No comments yet

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: