Catalyst::Helper::View::TT::Bootstrap::Manual - User guide and reference for files generated by Catalyst::Helper::View::TT::Bootstrap::YUI.


This is a replacement for Catalyst::View::TT, which operates in the same fashion. To create all the necessary files, simply run:

 script/ view TT TT::Bootstrap::YUI

This will generate the entire bootstrapped site structure. Read on for details.


Files and Directory

The files and directories generated under your application root (e.g. MyApp/) are:

    lib/MyApp/View/ # The TT View module with a couple extras

           # routes all pages to their appropriate layout
              # renders the html wrapper.  See below

            header/            # directory for header templates
           # placeholder masthead for you to override

            footer/            # directory for footer templates
           # placeholder footer for you to override

            nav/               # directory for navigation templates. See below
           # placeholder nav for you to override

            layout/            # directory for various content layouts
           # basic layout, renders content only

            shared/            # directory for templates shared by several pages
              # core macros and stash framework.  See below

        static/                # directory root of static resources
            images/            # content images go here or in a subdir
            scripts/           # javascript files go here or in a subdir
            css/               # stylesheets go here or in a subdir
                screen.css     # global stylesheet supporting the provided
                               # layouts and resetting default browser styles
                images/        # css images go here on in a subdir

View Module Configuration

The generated View sets the following configuration key/values:

 PRE_PROCESS        => 'site/shared/',
 WRAPPER            => 'site/',
 TIMER              => 0,
 static_root        => '/static',
 static_build       => 0,
 default_tz         => 'America/Los_Angeles',
 default_locale     => 'en_US',
 formats => {
    # All date formats to define:
    date => {
        'date'  => '%D',
        'short' => '%b %e, %G',
        'long'  => '%F %l:%M %p'

Formatting and Dynamic Filters

The generated class defines filters for (at the moment) doing DateTime formatting, complete with locale and timezone settings.

Either a DateTime object or a string that can be parsed as a Date/Time can be passed in to the filters:

    [% dt_object | date_long %]

This will set the timezone, and then format according to the configuration.

If you just have a string, it is useful for doing standard date formatting in your application:

    [% '2009-01-01T03:13:56' | date_long %]

The name of the filter is "date_$configkey", so if you wanted to have a format called "_for_americans" you could add this configuration:

 date => {
    'for_americans' => '%m/%d/%y'

This would create the usable filter "date_for_americans".

static_build and static_root

These options are unique to the ::Bootstrap package, and give you a managed static path to reference, as well as a "static" macro.

 <p>The current static root is [% static_root %]</p>
 <p>And the current static build is [% static_build %]</p>

Used by the macro 'static' (see below) to locate static resources such as images, stylesheets, and javascript files. The default value is '/static' (served from MyApp/root/static).


(Optional) Used by the macro 'static' to append the returned URIs with a query string 'ver' with the value assigned to static_build. This is particularly useful to ensure returning site visitors get the latest version of static resources, and not served from the browser cache. By default, this is set to 0 (versioning off).

Two strategies for use are

  1. Manually update it when a static file is modifed, using the a datestamp value. Using a YAML config makes this more convenient.

            static_build: 20070907
  2. Assign it the result of a call to localtime, so every time the server restarts, static requests will avoid the browser cache (first request only).

Template variable framework and the page variable

site/shared/ is PRE_PROCESSed before any page template rendering. It adds the following variables and macros:

MACRO ref(variable)

Works essentially like the native perl ref. Since TT auto-converts variables, it's often difficult to incorporate type checking into any template conditionals. This makes that functionality available again.

    IF colors && ref(colors) == 'HASH'; something...
MACRO static(resource, versioned, query)

Wraps c.uri_for for static resources. The full URI is returned with any query params appended. If a non-false value is passed for the versioned param, the query param ver => [% static_build %] will be added to the query string if static_build is set.

    <img alt="Sample image" src="[% static('images/sample.png') %]">
    BECOMES (e.g.)
    <img alt="Sample image" src="">

    <script type="text/javascript" src="[% static('scripts/changes_often.js',1) %]"></script>
    <script type="text/javascript" src=""></script>

For flexibility, if a full URI or a path starting with "/" is passed as the resource param, it will be returned unaltered. No query params nor the static_build versioning will be appended to the URI.


This hash struct contains key/value pairs used by the template structure to describe how the page should be rendered. Don't create or clobber a template stash variable named 'page', as this will cause havok. Work with the page variable structure provided.

The stuff you can and should play with are ...

    [% page.layout = '2columns'; %]

Assign the short name of the template found in MyApp/root/site/layout. Will cause the page to be wrapped in the appropriate layout. Add any new layouts (say to this directory and the page.layout will do the right thing. The default value is 'default'.

Other magic values are:


Don't use a layout. Just place the content in the wrapper. Out of the box, this is equivalent to the default.


Don't even wrap in This is useful for Ajax calls returning only bits of a page dynamically. Just the content, and nothing more.


Assigned to the title element in the html head. The default value is the name of your app (e.g. MyApp).

Note, unless you refer to page.title in the content area, this is NOT displayed in your page content.

    [% page.header = 'small_screen' %]

Similar to page.layout, this accepts a string short name for templates in MyApp/root/site/header. The default value is 'default'.

This also accepts the value 'none' to omit the inclusion of a header.

Note that page.header and page.footer are still rendered when page.layout is set to 'none' unless they too are set to 'none'.

    [% page.footer = 'no_contact_us' %]

Works like page.header.

    [% page.nav = 'green' %]

Similar to page.layout, this accepts a string short name for templates in <MyApp/root/site/nav>. The default value is 'default';

The out of the box default header happens to PROCESS page.nav, but in a real world application, you should add the PROCESS call in either your header or a layout template according to where you want the nav located.

        'widgets.css', 'widgets.css', page_name _ '.css',

Holds an array of css file names/URIs. Each entry will be added to the head element after locating the resource URI using the static macro. Duplicates will be ignored. Filenames will be prepended with /css and absolute URIs will be left alone. Local files will also be versioned according to the configuration of static_build (see above).

The above example will produce the following links:

    <link rel="stylesheet" type="text/css" href="" media="screen">
    <link rel="stylesheet" type="text/css" href="" media="screen">
    <link rel="stylesheet" type="text/css" href="" media="screen">

Note that screen.css is not included in the page.head.stylesheets list, but is instead listed at the end in root/site/ This is to ensure that the screen.css overrides are always at a higher precedence.

        'widgets.js', 'widgets.js', page_name _ '.js',

Holds an array of javascript file names/URIs. Works in the same fashion as page.head.stylesheets.

Note that it is generally preferable from a performance standpoint to place script tags at the bottom of the body tag. For this reason, it is advisable to use page.body.scripts rather than this.

Apply an ID to the body tag

    [% page.body.classes.push('foo','foo','bar'); %]

Holds an array of class names to add to the body tag. Duplicates are ignored.

Note that automatically adds classes 'IE' and 'IE(5|6|7)' to the body tag using conditional comments. These will only be added when the requesting browser is Internet Explorer. This is useful for adding style rules to target IE without resorting to css hacks.

Because of the nature of this package being reliant upon YUI out of the box, ithe default value for page.body.classes includes "yui-skin-sam".


Works exactly as page.head.scripts, except it adds script tags to the very end of the body content.

The default value is to include YUI 3.0.0.

    [% page.content_class = 'wide_content' %]

Used by, assigned to the class of the div containing the page content. Also used by layouts as a default container class. See the info on the layouts below. Default value is 'content'. points of interest creates the html, head and body elements of each page. As noted above, it references many of the page.* variables to populate these sections.

HTML 4.01 strict DOCTYPE

Per the recommendation of the w3c, the broadcasted DOCTYPE is HTML 4.01 strict. It was either this or XHTML 1.0 strict, but since you're likely delivering your pages with Content-Type header set to 'text/html', this is more correct. There are arguments for and against using HTML 4.01 instead of XHTML 1.0, but it's probably not worth the reading, since you really just want to get stuff done.

That said, please use HTML style closed tags or change the DOCTYPE in

    <p>This is<br>GOOD</p>
    <p>This is<br/>a waste of a character</p>
    [% # in some PRE_PROCESS template
    MACRO devel_env BLOCK;

    debug_init = 'devel_env';

If your server is running in debug mode, before anything, it checks if a variable named debug_init is populated. If it is, it attempts to execute a macro by the name assigned to the variable. This allows you to set up logging, add scripts or stylesheets etc for use in development.

IE detection uses IE conditional comments to decorate the body tag with a class 'IE' and another class 'IE5', 'IE6', or 'IE7' depending on the version of the browser requesting the page. Non-IE browsers will no have these classes added.

This allows you to use the cascade in your css to target IE to correct display issues that may*cough*WILL*cough* arise.

    /* Container dimensions */
    .container {
        width: 276px;
        padding: 10px:
        border: 2px solid #eee;

    /* correction for IE's box model */
    .IE .container {
        width: 300px;

The header, content, and footer are rendered separately under the body element, not wrapped in a global wrapping div. This was done to allow layouts to use the full content width for header/footer if their design mandates, but keep a narrower content area centered. If your design mandates consistent width, it's probably easiest to move the open and close div tags surrounding [% content %] to encompass the header and footer includes.


J. Shirley <<gt>


Lucas Smith <>


Version 0.1, released Dec 30, 2009


Copyright (C) J. Shirley and Lucas Smith. All Rights Reserved.

This module is free software; you can redistribute it and/or modify it under the same terms as Perl itself.