The London Perl and Raku Workshop takes place on 26th Oct 2024. If your company depends on Perl, please consider sponsoring and/or attending.


    Plack::Middleware::TemplateToolkit - serve a pages via Template Toolkit


    use Plack::Builder;

    my $root = '/path/to/html_doc_root';

    builder {

        # Page to show when requested file is missing
        enable 'ErrorDocument',    #
            404 => "$root/page_not_found.html";

        # These files can be served directly
        enable 'Static',
            path => qr{\.(gif|png|jpg|swf|ico|mov|mp3|pdf|js|css)$},
            root => $root;

        enable 'TemplateToolkit',
            INCLUDE_PATH => $root,    # required
            pass_through => 1;        # delegate missing templates to $app


A minimal .psgi script as stand-alone application:

    use Plack::Middleware::TemplateToolkit;
    Plack::Middleware::TemplateToolkit->new( INCLUDE_PATH => "/path/to/docs" );


Enable this middleware or application to allow your Plack-based application to serve files processed through Template Toolkit (TT). The idea behind this module is to provide content that is ALMOST static, but where having the power of TT can make the content easier to manage. You probably only want to use this for the simplest of sites, but it should be easy enough to migrate to something more significant later.

As Plack::Middleware derives from Plack::Component you can also use this as simple application. If you just want to serve files via Template Toolkit, treat this module as if it was called Plack::App::TemplateToolkit.

You can mix this middleware with other Plack::App applications and Plack::Middleware which you will find on CPAN.

This middleware reads and sets the PSGI environment variable tt.vars for variables passed to templates. By default, the QUERY_STRING params are available to the templates, but the more you use these the harder it could be to migrate later so you might want to look at a propper framework such as Catalyst if you do want to use them:

  [% params.get('field') %] params is a L<Hash::MultiValue>
  [% request.parameters.field %] configured with request_vars => ['parameters']

A full example application is included in this module in the exmple directory.


You can use all configuration options that are supported by Template Toolkit (INCLUDE_PATH, INTERPOLATE, POST_COMP...). See Template::Manual::Config for an overview. The only mandatory option is INCLUDE_PATH to point to where the templates live.


Specifies an URL pattern or a callback to match with requests to serve templates for. See Plack::Middleware::Static for further description. Unlike Plack::Middleware::Static this middleware uses '/' as default path. You may also consider using Plack::App::URLMap and the mount syntax from Plack::Builder to map requests based on a path to this middleware.


Limit to only files with this extension. Requests for other files within path will result in a 404 response or be passed to the next application if pass_through is set.


Specify the Content-Type header you want returned. If not specified, the content type will be guessed by Plack::MIME based on the file extension with default_type as default.


Specify the default Content-Type header. Defaults to to text/html.


Which file to use as a directory index, defaults to index.html.


Specify a hash reference with template variables or a code reference that gets a Plack::Request objects and returns a hash reference with template variables. By default only the QUERY_STRING params are provided as 'params'. Templates variables specified by this option are added to existing template variables in the tt.vars environment variable.


Specify a list of request variables from Plack::Request to be collected in a template variable 'request'. For instance ['path','base'] gives you the template variables request.path and request.base. Setting this parameter to 'all' gives you the original Plack::Request object, but this is unstable, bad practice because the object may change and your templates may damage the request object.

By default the request variables are decoded from byte strings to Unicode. You can change this with the configuration value decode_request.


If this option is enabled, requests are passed back to the application, if the incoming request path matches with the path but the requested template file is not found. Disabled by default, so all matching requests result in a valid response with status code 200, 404, or 500.


Directly set an instance of Template instead of creating a new one:

  Plack::Middleware::TemplateToolkit->new( %tt_options );

  # is equivalent to:

  my $tt = Template->new( %tt_options );
  Plack::Middleware::TemplateToolkit->new( tt => $tt );

If your templates or template variables are Unicode strings, the output must be encoded, because PSGI expects the content body to be a byte stream. You can specify an encoding, such as utf8 with this parameter, so the output is encoded to a byte string. The default setting is utf8 which encodes to UTF-8 bytes. This default option is useful if your input contains non-ASCII characters, but it may lead to double encoded UTF-8 bytes, if you accidently mix strings with UTF-8 flag and without. To find such implicit encoding conversions, try encoding::warnings.


Similar to encode_response, this parameter decodes the input request from a byte string to an encoding of your choice. Set to utf8 by default.

It is highly recommended to use Plack::Middleware::Lint and test your app with Unicode from several sources (templates, variables, parameters, ...).


Time the processing and add tt.start, tt.end, and tt.elapsed to the environment.

404 and 500

Specifies an error template that is processed when a file was not found (404) or on server error (500). The template variables error with an error message, path with the request path, and request with the request objects are set for processing. If an error template count not be found and processed, another error with status code 500 is returned, possibly also as template.


This middleware inspects and/or manipulates the following variables from the PSGI environment:


Injected as template variables if defined. Set to the template variables.


Set to the template that was asked to process. This is equal to the local path (path_info in Plack::Request) if the request matched. If this variable is set before the middleware is called, it uses its value instead of path_info.


Set to the template that has actually been processed. If this variable is set before the middleware is called, the specified template is processed. In this all other settings (path, extensions, dir_index, and tt.path) are ignored.

You can view these variables with Plack::Middleware::Debug::TemplateToolkit.


In addition to the call() method derived from Plack::Middleware, this class defines the following methods for internal use.

process_template ( $template, $code, \%vars )

Calls the process() method of Template and returns the output in a PSGI response object on success. The first parameter indicates the input template's file name. The second parameter is the HTTP status code to return on success. A reference to a hash with template variables may be passed as third parameter. On failure this method returns an error message instead of a reference.

process_error ( $code, $error, $type, $req ) = @_;

Returns a PSGI response to be used as error message. Error templates are used if they have been specified and prepare_app has been called before. This method tries hard not to fail: undefined parameters are replaced by default values. In list context this returns a PSGI response and the actual template that has been used to create the error document.


Plack, Template, Plack::Middleware::Debug::TemplateToolkit


Leo Lapworth (started) and Jakob Voss (most of the work!)