package Catalyst::Helper::View::TT::Bootstrap::Manual; 

1;

__END__

=head1 NAME

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

=head1 SYNOPSIS

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

 script/myapp_create.pl view TT TT::Bootstrap::YUI

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

=head1 DESCRIPTION

=head2 Files and Directory

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

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

    root/
        site/
            wrapper.tt         # routes all pages to their appropriate layout
            html.tt            # renders the html wrapper.  See below

            header/            # directory for header templates
                default.tt     # placeholder masthead for you to override

            footer/            # directory for footer templates
                default.tt     # placeholder footer for you to override

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

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

            shared/            # directory for templates shared by several pages
                base.tt        # 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

=head2 View Module Configuration

The generated View sets the following configuration key/values:

 PRE_PROCESS        => 'site/shared/base.tt',
 WRAPPER            => 'site/wrapper.tt',
 TEMPLATE_EXTENSION => '.tt',
 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'
    }
 }

=head3 Formatting and Dynamic Filters

The generated View.pm 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".

=head3 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>

=over 4

=item static_root

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

=item static_build

(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

=over 4

=item 1

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

    ...
    View::TT:
        static_build: 20070907
    ...

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

=back

=back

=head2 Template variable framework

=head3 base.tt and the page variable

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

=over 4

=item 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';
        ...do something...
    END
    %]

=item 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="http://mydomain.com/static/images/sample.png">

    <script type="text/javascript" src="[% static('scripts/changes_often.js',1) %]"></script>
    BECOMES
    <script type="text/javascript" src="http://mydomain.com/static/scripts/changes_often.js?ver=20070907"></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.

=item page

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

=item page.layout

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

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

Other magic values are:

=over 4

=item 'none'

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

=item 'partial'

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

=back

=item page.title

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.

=item page.header

    [% page.header = 'small_screen' %]

Similar to page.layout, this accepts a string short name for templates in
C<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'.

=item page.footer

    [% page.footer = 'no_contact_us' %]

Works like page.header.

=item page.nav

    [% 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.

=item page.head.stylesheets

 [%
    page.head.stylesheets.push(
        'widgets.css', 'widgets.css', page_name _ '.css',
        'http://somedomain.com/hosted/stylesheet.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="http://mydomain.com/static/css/widgets.css?ver=20070907" media="screen">
    <link rel="stylesheet" type="text/css" href="http://mydomain.com/static/css/foo.css?ver=20070907" media="screen">
    <link rel="stylesheet" type="text/css" href="http://somedomain.com/hosted/stylesheet.css" media="screen">

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

=item page.head.scripts

 [%
    page.head.scripts.push(
        'widgets.js', 'widgets.js', page_name _ '.js',
        'http://somedomain.com/hosted/script.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.

=item page.body.id

Apply an ID to the body tag

=item page.body.classes

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

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

Note that html.tt 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 C<page.body.classes> includes "yui-skin-sam".

=item page.body.scripts

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.

=item page.content_class

    [% page.content_class = 'wide_content' %]

Used by html.tt, 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'.

=back

=head2 html.tt points of interest

html.tt creates the html, head and body elements of each page.  As noted above,
it references many of the page.* variables to populate these sections.

=over 4

=item 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 html.tt

    <p>This is<br>GOOD</p>
    <p>This is<br/>a waste of a character</p>

=item debug_init

    [% # in some PRE_PROCESS template
    MACRO devel_env BLOCK;
        ...etc...
    END;

    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.

=item IE detection

html.tt 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;
    }

=item Header, content, and footer separation

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.

=back

=head1 STEALING AUTHOR

J. Shirley E<lt>jshirley@cpan.org<gt>

=head1 ORIGINAL AUTHOR

Lucas Smith E<lt>lsmith@lucassmith.nameE<gt>

=head1 VERSION

Version 0.1, released Dec 30, 2009

=head1 COPYRIGHT

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.

=cut
