Move View::TT to new repo layout.
Florian Ragwitz [Sat, 27 Jun 2009 21:14:15 +0000 (21:14 +0000)]
12 files changed:
tags/0.13/Changes [new file with mode: 0644]
tags/0.13/MANIFEST [new file with mode: 0644]
tags/0.13/MANIFEST.SKIP [new file with mode: 0644]
tags/0.13/META.yml [new file with mode: 0644]
tags/0.13/Makefile.PL [new file with mode: 0644]
tags/0.13/README [new file with mode: 0644]
tags/0.13/lib/Catalyst/Helper/View/TT.pm [new file with mode: 0644]
tags/0.13/lib/Catalyst/Helper/View/TTSite.pm [new file with mode: 0644]
tags/0.13/lib/Catalyst/View/TT.pm [new file with mode: 0644]
tags/0.13/t/01use.t [new file with mode: 0644]
tags/0.13/t/02pod.t [new file with mode: 0644]
tags/0.13/t/03podcoverage.t [new file with mode: 0644]

diff --git a/tags/0.13/Changes b/tags/0.13/Changes
new file mode 100644 (file)
index 0000000..849a8f7
--- /dev/null
@@ -0,0 +1,50 @@
+Revision history for Perl extension Catalyst::View::TT.
+
+0.13  Fri Oct 07 13:30:00 2005
+        - Fixed constructor
+        - Big update by Andy Wardley
+        - Much improved docs
+
+0.12  Wed Jul 06 15:24:00 2005
+        - Fixed, don't set Content-Type on failure
+        - Fixed helper to use [%author%]
+        - Fixed helper templates
+        - Rewrote docs
+
+0.11  Fri Apr 15 16:00:00 2005
+        - Fixed broken helper.
+
+0.10  Fri Apr 15 16:00:00 2005
+        - Added POD tests and made them pass.
+        - updated for Catalyst 5
+        - New TT Helpers.
+
+0.09  Wed Mar 29 13:47:00 2005
+        - Don't override user-set charset/content-type
+        - Cleaned up the content-type we set.
+        - Updated README to current POD to current POD
+
+0.08  Wed Mar 29 12:22:00 2005
+        - changed order of stash so stash can override c/base/name
+        - fixed some typos
+        - extended the documentation (Andrew Ford)
+0.07  Sat Mar 04 23:00:00 2005
+        - fixed the bugs produced by draven and the_jester ;)
+
+0.06  Fri Mar 04 20:00:00 2005
+        - new helper api
+
+0.05  Mon Feb 28 10:00:00 2005
+        - added helper
+
+0.04  Sun Feb 27 22:00:00 2005
+        - better debug messages (Marcus Ramberg)
+
+0.03  Thu Feb 17 22:00:00 2005
+        - don't try to render something without a template
+
+0.02  Tue Feb 01 02:00:00 2005
+        - using $c->req->match instead of $c->req->action
+
+0.01  Fri Jan 28 22:00:00 2005
+        - first release
diff --git a/tags/0.13/MANIFEST b/tags/0.13/MANIFEST
new file mode 100644 (file)
index 0000000..97e4764
--- /dev/null
@@ -0,0 +1,11 @@
+Changes
+lib/Catalyst/Helper/View/TT.pm
+lib/Catalyst/Helper/View/TTSite.pm
+lib/Catalyst/View/TT.pm
+Makefile.PL
+MANIFEST                       This list of files
+META.yml
+README
+t/01use.t
+t/02pod.t
+t/03podcoverage.t
diff --git a/tags/0.13/MANIFEST.SKIP b/tags/0.13/MANIFEST.SKIP
new file mode 100644 (file)
index 0000000..2ffcc10
--- /dev/null
@@ -0,0 +1,25 @@
+# Avoid version control files.
+\bRCS\b
+\bCVS\b
+,v$
+\B\.svn\b
+
+# Avoid Makemaker generated and utility files.
+\bMakefile$
+\bblib
+\bMakeMaker-\d
+\bpm_to_blib$
+\bblibdirs$
+^MANIFEST\.SKIP$
+
+# Avoid Module::Build generated and utility files.
+\bBuild$
+\b_build
+
+# Avoid temp and backup files.
+~$
+\.tmp$
+\.old$
+\.bak$
+\#$
+\b\.#
diff --git a/tags/0.13/META.yml b/tags/0.13/META.yml
new file mode 100644 (file)
index 0000000..334e580
--- /dev/null
@@ -0,0 +1,13 @@
+# http://module-build.sourceforge.net/META-spec.html
+#XXXXXXX This is a prototype!!!  It will change in the future!!! XXXXX#
+name:         Catalyst-View-TT
+version:      0.13
+version_from: lib/Catalyst/View/TT.pm
+installdirs:  site
+requires:
+    Catalyst:                      5.00
+    Template:                      0
+    Template::Timer:               0
+
+distribution_type: module
+generated_by: ExtUtils::MakeMaker version 6.17
diff --git a/tags/0.13/Makefile.PL b/tags/0.13/Makefile.PL
new file mode 100644 (file)
index 0000000..0424d8d
--- /dev/null
@@ -0,0 +1,12 @@
+use ExtUtils::MakeMaker;
+
+WriteMakefile(
+    NAME      => 'Catalyst::View::TT',
+    AUTHOR    => 'Sebastian Riedel (sri@oook.de)',
+    PREREQ_PM => {
+        Catalyst        => '5.00',
+        Template        => 0,
+        Template::Timer => 0
+    },
+    VERSION_FROM => 'lib/Catalyst/View/TT.pm'
+);
diff --git a/tags/0.13/README b/tags/0.13/README
new file mode 100644 (file)
index 0000000..3e5f036
--- /dev/null
@@ -0,0 +1,276 @@
+NAME
+    Catalyst::View::TT - Template View Class
+
+SYNOPSIS
+    # use the helper to create View myapp_create.pl view TT TT
+
+    # configure in lib/MyApp.pm
+
+        our $ROOT = '/home/dent/catalyst/MyApp';
+
+        MyApp->config({
+            name     => 'MyApp',
+            root     => $ROOT,
+            'MyApp::V::TT' => {
+                # any TT configurations items go here
+                INCLUDE_PATH => [
+                  "$ROOT/templates/src", 
+                  "$ROOT/templates/lib"
+                ],
+                PRE_PROCESS => 'config/main',
+                WRAPPER     => 'site/wrapper',
+
+                # two optional config items
+                CATALYST_VAR => 'Catalyst',
+                TIMER        => 1,
+            },
+        });
+         
+    # render view from lib/MyApp.pm or lib/MyApp::C::SomeController.pm
+
+        sub message : Global {
+            my ( $self, $c ) = @_;
+            $c->stash->{template} = 'message.tt2';
+            $c->stash->{message}  = 'Hello World!';
+            $c->forward('MyApp::V::TT');
+        }
+
+    # access variables from template
+
+        The message is: [% message %].
+    
+        # example when CATALYST_VAR is set to 'Catalyst'
+        Context is [% Catalyst %]          
+        The base is [% Catalyst.req.base %] 
+        The name is [% Catalyst.config.name %] 
+    
+        # example when CATALYST_VAR isn't set
+        Context is [% c %]
+        The base is [% base %]
+        The name is [% name %]
+
+DESCRIPTION
+    This is the Catalyst view class for the Template Toolkit. Your
+    application should defined a view class which is a subclass of this
+    module. The easiest way to achieve this is using the myapp_create.pl
+    script (where myapp should be replaced with whatever your application is
+    called). This script is created as part of the Catalyst setup.
+
+        $ script/myapp_create.pl view TT TT
+
+    This creates a MyApp::V::TT.pm module in the lib directory (again,
+    replacing "MyApp" with the name of your application) which looks
+    something like this:
+
+        package FooBar::V::TT;
+    
+        use strict;
+         use base 'Catalyst::View::TT';
+
+        __PACKAGE__->config->{DEBUG} = 'all';
+
+    Now you can modify your action handlers in the main application and/or
+    controllers to forward to your view class. You might choose to do this
+    in the end() method, for example, to automatically forward all actions
+    to the TT view class.
+
+        # In MyApp or MyApp::Controller::SomeController
+    
+        sub end : Private {
+            my( $self, $c ) = @_;
+            $c->forward('MyApp::V::TT');
+        }
+
+  CONFIGURATION
+    There are a three different ways to configure your view class. The first
+    way is to call the "config()" method in the view subclass. This happens
+    when the module is first loaded.
+
+        package MyApp::V::TT;
+    
+        use strict;
+        use base 'Catalyst::View::TT';
+
+        our $ROOT = '/home/dent/catalyst/MyApp';
+    
+        MyApp::V::TT->config({
+            INCLUDE_PATH => ["$ROOT/templates/src", "$ROOT/templates/lib"],
+            PRE_PROCESS  => 'config/main',
+            WRAPPER      => 'site/wrapper',
+        });
+
+    The second way is to define a "new()" method in your view subclass. This
+    performs the configuration when the view object is created, shortly
+    after being loaded. Remember to delegate to the base class "new()"
+    method (via "$self->NEXT::new()" in the example below) after performing
+    any configuration.
+
+        sub new {
+            my $self = shift;
+            $self->config({
+                INCLUDE_PATH => ["$ROOT/templates/src", "$ROOT/templates/lib"],
+                PRE_PROCESS  => 'config/main',
+                WRAPPER      => 'site/wrapper',
+            });
+            return $self->NEXT::new(@_);
+        }
+    The final, and perhaps most direct way, is to define a class item in
+    your main application configuration, again by calling the uniquitous
+    "config()" method. The items in the class hash are added to those
+    already defined by the above two methods. This happens in the base class
+    new() method (which is one reason why you must remember to call it via
+    "NEXT" if you redefine the "new()" method in a subclass).
+
+        package MyApp;
+    
+        use strict;
+        use Catalyst;
+    
+        our $ROOT = '/home/dent/catalyst/MyApp';
+    
+        MyApp->config({
+            name     => 'MyApp',
+            root     => $ROOT,
+            'MyApp::V::TT' => {
+                INCLUDE_PATH => ["$ROOT/templates/src", "$ROOT/templates/lib"],
+                PRE_PROCESS  => 'config/main',
+                WRAPPER      => 'site/wrapper',
+            },
+        });
+
+    Note that any configuration items defined by one of the earlier methods
+    will be overwritten by items of the same name provided by the latter
+    methods.
+
+  RENDERING VIEWS
+    The view plugin renders the template specified in the "template" item in
+    the stash.
+
+        sub message : Global {
+            my ( $self, $c ) = @_;
+            $c->stash->{template} = 'message.tt2';
+            $c->forward('MyApp::V::TT');
+        }
+
+    If a class item isn't defined, then it instead uses the current match,
+    as returned by "$c->match". In the above example, this would be
+    "message".
+
+    The items defined in the stash are passed to the Template Toolkit for
+    use as template variables.
+
+    sub message : Global { sub default : Private { my ( $self, $c ) = @_;
+    $c->stash->{template} = 'message.tt2'; $c->stash->{message} = 'Hello
+    World!'; $c->forward('MyApp::V::TT'); }
+
+    A number of other template variables are also added:
+
+        c      A reference to the context object, $c
+        base   The URL base, from $c->req->base()
+        name   The application name, from $c->config->{ name }
+
+    These can be accessed from the template in the usual way:
+
+    <message.tt2>:
+
+        The message is: [% message %]
+        The base is [% base %]
+        The name is [% name %]
+
+    If you prefer, you can set the "CATALYST_VAR" configuration item to
+    define the name of a template variable through which the context can be
+    referenced.
+
+        MyApp->config({
+            name     => 'MyApp',
+            root     => $ROOT,
+            'MyApp::V::TT' => {
+                CATALYST_VAR => 'Catalyst',
+            },
+        });
+
+    message.tt2:
+
+        The base is [% Catalyst.req.base %]
+        The name is [% Catalyst.config.name %]
+
+    The output generated by the template is stored in
+    "$c->response->output".
+
+  TEMPLATE PROFILING
+    If you have configured Catalyst for debug output, "Catalyst::View::TT"
+    will enable profiling of template processing (using Template::Timer).
+    This will embed HTML comments in the output from your templates, such
+    as:
+
+        <!-- TIMER START: process mainmenu/mainmenu.ttml -->
+        <!-- TIMER START: include mainmenu/cssindex.tt -->
+        <!-- TIMER START: process mainmenu/cssindex.tt -->
+        <!-- TIMER END: process mainmenu/cssindex.tt (0.017279 seconds) -->
+        <!-- TIMER END: include mainmenu/cssindex.tt (0.017401 seconds) -->
+
+        ....
+
+        <!-- TIMER END: process mainmenu/footer.tt (0.003016 seconds) -->
+
+    You can suppress template profiling by setting the "TIMER" configuration
+    item to a false value.
+
+        MyApp->config({
+            'MyApp::V::TT' => {
+                TIMER => 0,
+            },
+        });
+
+  METHODS
+    new The constructor for the TT view. Sets up the template provider, and
+        reads the application config.
+
+    process
+        Renders the template specified in "$c->stash->{template}" or
+        "$c->request->match". Template variables are set up from the
+        contents of "$c->stash", augmented with "base" set to
+        "$c->req->base", "c" to $c and "name" to "$c->config->{name}".
+        Alternately, the "CATALYST_VAR" configuration item can be defined to
+        specify the name of a template variable through which the context
+        reference ($c) can be accessed. In this case, the "c", "base" and
+        "name" variables are omitted. Output is stored in
+        "$c->response->output".
+
+    config
+        This method allows your view subclass to pass additional settings to
+        the TT configuration hash, or to set the "CATALYST_VAR" and "TIMER"
+        options.
+
+  HELPERS
+    The Catalyst::Helper::View::TT and Catalyst::Helper::View::TTSite helper
+    modules are provided to create your view module. There are invoked by
+    the myapp_create.pl script:
+
+        $ script/myapp_create.pl view TT TT
+
+        $ script/myapp_create.pl view TT TTSite
+
+    The Catalyst::Helper::View::TT module creates a basic TT view module.
+    The Catalyst::Helper::View::TTSite module goes a little further. It also
+    creates a default set of templates to get you started. It also
+    configures the view module to locate the templates automatically.
+
+SEE ALSO
+    Catalyst, Catalyst::Helper::View::TT, Catalyst::Helper::View::TTSite,
+    Template::Manual
+
+AUTHORS
+    Sebastian Riedel, "sri@cpan.org"
+
+    Marcus Ramberg, "mramberg@cpan.org"
+
+    Jesse Sheidlower, "jester@panix.com"
+
+    Andy Wardley, "abw@cpan.org"
+
+COPYRIGHT
+    This program is free software, you can redistribute it and/or modify it
+    under the same terms as Perl itself.
+
diff --git a/tags/0.13/lib/Catalyst/Helper/View/TT.pm b/tags/0.13/lib/Catalyst/Helper/View/TT.pm
new file mode 100644 (file)
index 0000000..1b605d3
--- /dev/null
@@ -0,0 +1,78 @@
+package Catalyst::Helper::View::TT;
+
+use strict;
+
+=head1 NAME
+
+Catalyst::Helper::View::TT - Helper for TT Views
+
+=head1 SYNOPSIS
+
+    script/create.pl view TT TT
+
+=head1 DESCRIPTION
+
+Helper for TT Views.
+
+=head2 METHODS
+
+=head3 mk_compclass
+
+=cut
+
+sub mk_compclass {
+    my ( $self, $helper ) = @_;
+    my $file = $helper->{file};
+    $helper->render_file( 'compclass', $file );
+}
+
+=head1 SEE ALSO
+
+L<Catalyst::Manual>, L<Catalyst::Test>, L<Catalyst::Request>,
+L<Catalyst::Response>, L<Catalyst::Helper>
+
+=head1 AUTHOR
+
+Sebastian Riedel, C<sri@oook.de>
+
+=head1 LICENSE
+
+This library is free software . You can redistribute it and/or modify
+it under the same terms as perl itself.
+
+=cut
+
+1;
+
+__DATA__
+
+__compclass__
+package [% class %];
+
+use strict;
+use base 'Catalyst::View::TT';
+
+=head1 NAME
+
+[% class %] - TT View Component
+
+=head1 SYNOPSIS
+
+See L<[% app %]>
+
+=head1 DESCRIPTION
+
+TT View Component.
+
+=head1 AUTHOR
+
+[% author %]
+
+=head1 LICENSE
+
+This library is free software . You can redistribute it and/or modify
+it under the same terms as perl itself.
+
+=cut
+
+1;
diff --git a/tags/0.13/lib/Catalyst/Helper/View/TTSite.pm b/tags/0.13/lib/Catalyst/Helper/View/TTSite.pm
new file mode 100644 (file)
index 0000000..b3b301b
--- /dev/null
@@ -0,0 +1,356 @@
+package Catalyst::Helper::View::TTSite;
+
+use strict;
+use File::Spec;
+
+sub mk_compclass {
+    my ( $self, $helper, @args ) = @_;
+    my $file = $helper->{file};
+    $helper->render_file( 'compclass', $file );
+    $self->mk_templates( $helper, @args );
+}
+
+sub mk_templates {
+    my ( $self, $helper ) = @_;
+    my $base = $helper->{base};
+    my $tdir = File::Spec->catfile( $base, 'root', 'templates' );
+    my $ldir = File::Spec->catfile( $tdir, 'lib' );
+    my $sdir = File::Spec->catfile( $tdir, 'src' );
+
+    $helper->mk_dir($ldir);
+    $helper->mk_dir($sdir);
+
+    my $dir = File::Spec->catfile( $ldir, 'config' );
+    $helper->mk_dir($dir);
+
+    foreach my $file (qw( main col url )) {
+        $helper->render_file( "config_$file",
+            File::Spec->catfile( $dir, $file ) );
+    }
+
+    $dir = File::Spec->catfile( $ldir, 'site' );
+    $helper->mk_dir($dir);
+
+    foreach my $file (qw( wrapper layout html header footer )) {
+        $helper->render_file( "site_$file",
+            File::Spec->catfile( $dir, $file ) );
+    }
+
+    foreach my $file (qw( welcome.tt2 message.tt2 error.tt2 ttsite.css )) {
+        $helper->render_file( $file, File::Spec->catfile( $sdir, $file ) );
+    }
+
+}
+
+=head1 NAME
+
+Catalyst::Helper::View::TTSite - Helper for TT view which builds a skeleton web site
+
+=head1 SYNOPSIS
+
+# use the helper to create the view module and templates
+
+    $ script/myapp_create.pl view TT TTSite
+
+# add something like the following to your main application module
+
+    sub message : Global {
+        my ( $self, $c ) = @_;
+        $c->stash->{template} = 'message.tt2';
+        $c->stash->{message}  = $c->req->param('message') || 'Hello World';
+    }
+    
+    sub default : Private {
+        my ( $self, $c ) = @_;
+        $c->stash->{template} = 'welcome.tt2';
+    }
+    
+    sub end : Private {
+        my ( $self, $c ) = @_;
+        $c->forward('MyApp::V::TT');
+    }
+
+=head1 DESCRIPTION
+
+This helper module creates a TT View module.  It goes further than
+Catalyst::Helper::View::TT in that it additionally creates a simple
+set of templates to get you started with your web site presentation.
+
+It creates the templates in a F<templates> directory underneath your
+main project directory.  In here two further subdirectories are
+created: F<src> which contains the main page templates, and F<lib>
+containing a library of other templates components (header, footer,
+etc.) that the page templates use.
+
+The view module that the helper creates is automatically configured
+to locate these templates.
+
+=head2 METHODS
+
+=head3 mk_compclass
+
+Generates the component class.
+
+=head3 mk_templates
+
+Generates the templates.
+
+=cut
+
+=head1 SEE ALSO
+
+L<Catalyst>, L<Catalyst::View::TT>, L<Catalyst::Helper>,
+L<Catalyst::Helper::View::TT>
+
+=head1 AUTHOR
+
+Andy Wardley <abw@cpan.org>
+
+=head1 LICENSE
+
+This library is free software . You can redistribute it and/or modify
+it under the same terms as perl itself.
+
+=cut
+
+1;
+
+__DATA__
+
+__compclass__
+package [% class %];
+
+use strict;
+use base 'Catalyst::View::TT';
+
+my $root = [% app %]->config->{root};
+
+__PACKAGE__->config({
+    CATALYST_VAR => 'Catalyst',
+    INCLUDE_PATH => [ "$root/templates/src", "$root/templates/lib" ],
+    PRE_PROCESS  => 'config/main',
+    WRAPPER      => 'site/wrapper',
+    ERROR        => 'error.tt2',
+    TIMER        => 0
+});
+
+=head1 NAME
+
+[% class %] - TT View Component
+
+=head1 SYNOPSIS
+
+See L<[% app %]>
+
+=head1 DESCRIPTION
+
+TT View Component.
+
+=head1 AUTHOR
+
+[% author %]
+
+=head1 LICENSE
+
+This library is free software . You can redistribute it and/or modify
+it under the same terms as perl itself.
+
+=cut
+
+1;
+
+__config_main__
+[% USE Date;
+   year = Date.format(Date.now, '%Y');
+-%]
+[% TAGS star -%]
+[% # config/main
+   #
+   # This is the main configuration template which is processed before
+   # any other page, by virtue of it being defined as a PRE_PROCESS 
+   # template.  This is the place to define any extra template variables,
+   # macros, load plugins, and perform any other template setup.
+
+   IF Catalyst.debug;
+     # define a debug() macro directed to Catalyst's log
+     MACRO debug(message) CALL Catalyst.log.debug(message);
+   END;
+
+   # define a data structure to hold sitewide data
+   site = {
+     title     => 'Catalyst::View::TTSite Example Page',
+     copyright => '[* year *] Your Name Here',
+   };
+
+   # load up any other configuration items 
+   PROCESS config/col
+         + config/url;
+
+   # set defaults for variables, etc.
+   DEFAULT 
+     message = 'There is no message';
+
+-%]
+__config_col__
+[% TAGS star -%]
+[% site.rgb = {
+     black  = '#000000'
+     white  = '#ffffff'
+     grey1  = '#46494c'
+     grey2  = '#c6c9cc'
+     grey3  = '#e3e6ea'
+     red    = '#CC4444'
+     green  = '#66AA66'
+     blue   = '#89b8df'
+     orange = '#f08900'
+   };
+
+   site.col = {
+      page    = site.rgb.white
+      text    = site.rgb.grey1
+      head    = site.rgb.grey3
+      line    = site.rgb.orange
+      message = site.rgb.green
+      error   = site.rgb.red
+   };
+%]
+__config_url__
+[% TAGS star -%]
+[% base = Catalyst.req.base;
+
+   site.url = {
+     base    = base
+     home    = "${base}welcome"
+     message = "${base}message"
+   }
+-%]
+__site_wrapper__
+[% TAGS star -%]
+[% IF template.name.match('\.(css|js|txt)');
+     debug("Passing page through as text: $template.name");
+     content;
+   ELSE;
+     debug("Applying HTML page layout wrappers to $template.name\n");
+     content WRAPPER site/html + site/layout;
+   END;
+-%]
+__site_html__
+[% TAGS star -%]
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+ <head>
+  <title>[% template.title or site.title %]</title>
+  <style type="text/css">
+[% PROCESS ttsite.css %]
+  </style>
+ </head>
+ <body>
+[% content %]
+ </body>
+</html>
+__site_layout__
+[% TAGS star -%]
+<div id="header">[% PROCESS site/header %]</div>
+
+<div id="content">
+[% content %]
+</div>
+
+<div id="footer">[% PROCESS site/footer %]</div>
+__site_header__
+[% TAGS star -%]
+<!-- BEGIN site/header -->
+<h1 class="title">[% template.title or site.title %]</h1>
+<!-- END site/header -->
+__site_footer__
+[% TAGS star -%]
+<!-- BEGIN site/footer -->
+<div id="copyright">&copy; [% site.copyright %]</div>
+<!-- END site/footer -->
+__welcome.tt2__
+[% TAGS star -%]
+[% META title = 'Catalyst/TT View!' %]
+<p>
+  Yay!  You're looking at a page generated by the Catalyst::View::TT
+  plugin module.
+</p>
+<p>
+  This is the welcome page.  Why not try the equally-exciting 
+  <a href="[% site.url.message %]">Message Page</a>?
+</p>
+__message.tt2__
+[% TAGS star -%]
+[% META title = 'Catalyst/TT View!' %]
+<p>
+  Yay!  You're looking at a page generated by the Catalyst::View::TT
+  plugin module.
+</p>
+<p>
+  We have a message for you: <span class="message">[% message %]</span>.
+</p>
+<p>
+  Why not try updating the message?  Go on, it's really exciting, honest!
+</p>
+<form action="[% site.url.message %]"
+      method="POST" enctype="application/x-www-form-urlencoded">
+ <input type="text" name="message" value="[% message %]" />
+ <input type="submit" name="submit" value=" Update Message "/>
+</form>
+__error.tt2__
+[% TAGS star -%]
+[% META title = 'Catalyst/TT Error' %]
+<p>
+  An error has occurred.  We're terribly sorry about that, but it's 
+  one of those things that happens from time to time.  Let's just 
+  hope the developers test everything properly before release...
+</p>
+<p>
+  Here's the error message, on the off-chance that it means something
+  to you: <span class="error">[% error %]</span>
+</p>
+__ttsite.css__
+[% TAGS star %]
+html {
+    height: 100%;
+}
+
+body { 
+    background-color: [% site.col.page %];
+    color: [% site.col.text %];
+    margin: 0px;
+    padding: 0px;
+    height: 100%;
+}
+
+#header {
+    background-color: [% site.col.head %];
+    border-bottom: 1px solid [% site.col.line %];
+}
+
+#footer {
+    background-color: [% site.col.head %];
+    text-align: center;
+    border-top: 1px solid [% site.col.line %];
+    position: absolute;
+    bottom: 0;
+    left: 0px;
+    width: 100%;
+    padding: 4px;
+}
+
+#content {
+    padding: 10px;
+}
+
+h1.title {
+    padding: 4px;
+    margin: 0px;
+}
+
+.message {
+    color: [% site.col.message %];
+}
+
+.error {
+    color: [% site.col.error %];
+}
diff --git a/tags/0.13/lib/Catalyst/View/TT.pm b/tags/0.13/lib/Catalyst/View/TT.pm
new file mode 100644 (file)
index 0000000..736584d
--- /dev/null
@@ -0,0 +1,408 @@
+package Catalyst::View::TT;
+
+use strict;
+use base qw/Catalyst::Base/;
+use Template;
+use Template::Timer;
+use NEXT;
+
+our $VERSION = '0.13';
+
+__PACKAGE__->mk_accessors('template');
+
+=head1 NAME
+
+Catalyst::View::TT - Template View Class
+
+=head1 SYNOPSIS
+
+# use the helper to create View
+    myapp_create.pl view TT TT
+
+# configure in lib/MyApp.pm
+
+    our $ROOT = '/home/dent/catalyst/MyApp';
+
+    MyApp->config({
+        name     => 'MyApp',
+        root     => $ROOT,
+        'MyApp::V::TT' => {
+            # any TT configurations items go here
+            INCLUDE_PATH => [
+              "$ROOT/templates/src", 
+              "$ROOT/templates/lib"
+            ],
+            PRE_PROCESS => 'config/main',
+            WRAPPER     => 'site/wrapper',
+
+            # two optional config items
+            CATALYST_VAR => 'Catalyst',
+            TIMER        => 1,
+        },
+    });
+         
+# render view from lib/MyApp.pm or lib/MyApp::C::SomeController.pm
+    
+    sub message : Global {
+        my ( $self, $c ) = @_;
+        $c->stash->{template} = 'message.tt2';
+        $c->stash->{message}  = 'Hello World!';
+        $c->forward('MyApp::V::TT');
+    }
+
+# access variables from template
+
+    The message is: [% message %].
+    
+    # example when CATALYST_VAR is set to 'Catalyst'
+    Context is [% Catalyst %]          
+    The base is [% Catalyst.req.base %] 
+    The name is [% Catalyst.config.name %] 
+    
+    # example when CATALYST_VAR isn't set
+    Context is [% c %]
+    The base is [% base %]
+    The name is [% name %]
+
+=head1 DESCRIPTION
+
+This is the Catalyst view class for the L<Template Toolkit|Template>.
+Your application should defined a view class which is a subclass of
+this module.  The easiest way to achieve this is using the
+F<myapp_create.pl> script (where F<myapp> should be replaced with
+whatever your application is called).  This script is created as part
+of the Catalyst setup.
+
+    $ script/myapp_create.pl view TT TT
+
+This creates a MyApp::V::TT.pm module in the F<lib> directory (again,
+replacing C<MyApp> with the name of your application) which looks
+something like this:
+
+    package FooBar::V::TT;
+    
+    use strict;
+     use base 'Catalyst::View::TT';
+
+    __PACKAGE__->config->{DEBUG} = 'all';
+
+Now you can modify your action handlers in the main application and/or
+controllers to forward to your view class.  You might choose to do this
+in the end() method, for example, to automatically forward all actions
+to the TT view class.
+
+    # In MyApp or MyApp::Controller::SomeController
+    
+    sub end : Private {
+        my( $self, $c ) = @_;
+        $c->forward('MyApp::V::TT');
+    }
+
+=head2 CONFIGURATION
+
+There are a three different ways to configure your view class.  The
+first way is to call the C<config()> method in the view subclass.  This
+happens when the module is first loaded.
+
+    package MyApp::V::TT;
+    
+    use strict;
+    use base 'Catalyst::View::TT';
+
+    our $ROOT = '/home/dent/catalyst/MyApp';
+    
+    MyApp::V::TT->config({
+        INCLUDE_PATH => ["$ROOT/templates/src", "$ROOT/templates/lib"],
+        PRE_PROCESS  => 'config/main',
+        WRAPPER      => 'site/wrapper',
+    });
+
+The second way is to define a C<new()> method in your view subclass.
+This performs the configuration when the view object is created,
+shortly after being loaded.  Remember to delegate to the base class
+C<new()> method (via C<$self-E<gt>NEXT::new()> in the example below) after
+performing any configuration.
+
+    sub new {
+        my $self = shift;
+        $self->config({
+            INCLUDE_PATH => ["$ROOT/templates/src", "$ROOT/templates/lib"],
+            PRE_PROCESS  => 'config/main',
+            WRAPPER      => 'site/wrapper',
+        });
+        return $self->NEXT::new(@_);
+    }
+The final, and perhaps most direct way, is to define a class
+item in your main application configuration, again by calling the
+uniquitous C<config()> method.  The items in the class hash are
+added to those already defined by the above two methods.  This happens
+in the base class new() method (which is one reason why you must
+remember to call it via C<NEXT> if you redefine the C<new()> method in a
+subclass).
+
+    package MyApp;
+    
+    use strict;
+    use Catalyst;
+    
+    our $ROOT = '/home/dent/catalyst/MyApp';
+    
+    MyApp->config({
+        name     => 'MyApp',
+        root     => $ROOT,
+        'MyApp::V::TT' => {
+            INCLUDE_PATH => ["$ROOT/templates/src", "$ROOT/templates/lib"],
+            PRE_PROCESS  => 'config/main',
+            WRAPPER      => 'site/wrapper',
+        },
+    });
+
+Note that any configuration items defined by one of the earlier
+methods will be overwritten by items of the same name provided by the
+latter methods.  
+
+=head2 RENDERING VIEWS
+
+The view plugin renders the template specified in the C<template>
+item in the stash.  
+
+    sub message : Global {
+        my ( $self, $c ) = @_;
+        $c->stash->{template} = 'message.tt2';
+        $c->forward('MyApp::V::TT');
+    }
+
+If a class item isn't defined, then it instead uses the
+current match, as returned by C<$c-E<gt>match>.  In the above 
+example, this would be C<message>.
+
+The items defined in the stash are passed to the Template Toolkit for
+use as template variables.
+
+sub message : Global {
+    sub default : Private {
+        my ( $self, $c ) = @_;
+        $c->stash->{template} = 'message.tt2';
+        $c->stash->{message}  = 'Hello World!';
+        $c->forward('MyApp::V::TT');
+    }
+
+A number of other template variables are also added:
+
+    c      A reference to the context object, $c
+    base   The URL base, from $c->req->base()
+    name   The application name, from $c->config->{ name }
+
+These can be accessed from the template in the usual way:
+
+<message.tt2>:
+
+    The message is: [% message %]
+    The base is [% base %]
+    The name is [% name %]
+
+If you prefer, you can set the C<CATALYST_VAR> configuration item to
+define the name of a template variable through which the context can
+be referenced.
+
+    MyApp->config({
+        name     => 'MyApp',
+        root     => $ROOT,
+        'MyApp::V::TT' => {
+            CATALYST_VAR => 'Catalyst',
+        },
+    });
+
+F<message.tt2>:
+
+    The base is [% Catalyst.req.base %]
+    The name is [% Catalyst.config.name %]
+
+The output generated by the template is stored in
+C<$c-E<gt>response-E<gt>output>.
+
+=head2 TEMPLATE PROFILING
+
+If you have configured Catalyst for debug output,
+C<Catalyst::View::TT> will enable profiling of template processing
+(using L<Template::Timer>). This will embed HTML comments in the
+output from your templates, such as:
+
+    <!-- TIMER START: process mainmenu/mainmenu.ttml -->
+    <!-- TIMER START: include mainmenu/cssindex.tt -->
+    <!-- TIMER START: process mainmenu/cssindex.tt -->
+    <!-- TIMER END: process mainmenu/cssindex.tt (0.017279 seconds) -->
+    <!-- TIMER END: include mainmenu/cssindex.tt (0.017401 seconds) -->
+
+    ....
+
+    <!-- TIMER END: process mainmenu/footer.tt (0.003016 seconds) -->
+
+You can suppress template profiling by setting the C<TIMER> configuration
+item to a false value.
+
+    MyApp->config({
+        'MyApp::V::TT' => {
+            TIMER => 0,
+        },
+    });
+
+=head2 METHODS
+
+=over 4
+
+=item new
+
+The constructor for the TT view. Sets up the template provider, 
+and reads the application config.
+
+=cut
+
+sub new {
+    my ( $class, $c, $arguments ) = @_;
+
+    my $root = $c->config->{root};
+
+    my $config = {
+        EVAL_PERL    => 0,
+        INCLUDE_PATH => [ $root, "$root/base" ],
+        %{ $class->config },
+        %{$arguments}
+    };
+
+    # if we're debugging and/or the TIMER option is set, then we install
+    # Template::Timer as a custom CONTEXT object, but only if we haven't
+    # already got a custom CONTEXT defined
+
+    if ( $config->{TIMER} || ( $c->debug() && !exists $config->{TIMER} ) ) {
+        if ( $config->{CONTEXT} ) {
+            $c->log->error(
+                'Cannot use Template::Timer - a TT CONFIG is already defined');
+        }
+        else {
+            $config->{CONTEXT} = Template::Timer->new(%$config);
+        }
+    }
+
+    if ( $c->debug && $config->{DUMP_CONFIG} ) {
+        use Data::Dumper;
+        $c->log->debug( "TT Config: ", Dumper($config) );
+    }
+
+    return $class->NEXT::new(
+        $c,
+        {
+            template => Template->new($config) || do {
+                my $error = Template->error();
+                $c->log->error($error);
+                $c->error($error);
+                return undef;
+              }
+        }
+    );
+}
+
+=item process
+
+Renders the template specified in C<$c-E<gt>stash-E<gt>{template}> or
+C<$c-E<gt>request-E<gt>match>. Template variables are set up from the
+contents of C<$c-E<gt>stash>, augmented with C<base> set to
+C<$c-E<gt>req-E<gt>base>, C<c> to C<$c> and C<name> to
+C<$c-E<gt>config-E<gt>{name}>. Alternately, the C<CATALYST_VAR>
+configuration item can be defined to specify the name of a template
+variable through which the context reference (C<$c>) can be accessed.
+In this case, the C<c>, C<base> and C<name> variables are omitted.
+Output is stored in C<$c-E<gt>response-E<gt>output>.
+
+=cut
+
+sub process {
+    my ( $self, $c ) = @_;
+
+    my $template = $c->stash->{template} || $c->request->match;
+
+    unless ($template) {
+        $c->log->debug('No template specified for rendering') if $c->debug;
+        return 0;
+    }
+
+    $c->log->debug(qq/Rendering template "$template"/) if $c->debug;
+
+    my $output;
+    my $cvar = $self->config->{CATALYST_VAR};
+    my $vars = {
+        defined $cvar
+        ? ( $cvar => $c )
+        : (
+            c    => $c,
+            base => $c->req->base,
+            name => $c->config->{name}
+        ),
+        %{ $c->stash() }
+    };
+
+    unless ( $self->template->process( $template, $vars, \$output ) ) {
+        my $error = $self->template->error;
+        $error = qq/Couldn't render template "$error"/;
+        $c->log->error($error);
+        $c->error($error);
+        return 0;
+    }
+
+    unless ( $c->response->content_type ) {
+        $c->response->content_type('text/html; charset=utf-8');
+    }
+
+    $c->response->body($output);
+
+    return 1;
+}
+
+=item config
+
+This method allows your view subclass to pass additional settings to
+the TT configuration hash, or to set the C<CATALYST_VAR> and C<TIMER>
+options.
+
+=back
+
+=head2 HELPERS
+
+The L<Catalyst::Helper::View::TT> and
+L<Catalyst::Helper::View::TTSite> helper modules are provided to create
+your view module.  There are invoked by the F<myapp_create.pl> script:
+
+    $ script/myapp_create.pl view TT TT
+
+    $ script/myapp_create.pl view TT TTSite
+
+The L<Catalyst::Helper::View::TT> module creates a basic TT view
+module.  The L<Catalyst::Helper::View::TTSite> module goes a little
+further.  It also creates a default set of templates to get you
+started.  It also configures the view module to locate the templates
+automatically.
+
+=head1 SEE ALSO
+
+L<Catalyst>, L<Catalyst::Helper::View::TT>,
+L<Catalyst::Helper::View::TTSite>, L<Template::Manual>
+
+=head1 AUTHORS
+
+Sebastian Riedel, C<sri@cpan.org>
+
+Marcus Ramberg, C<mramberg@cpan.org>
+
+Jesse Sheidlower, C<jester@panix.com>
+
+Andy Wardley, C<abw@cpan.org>
+
+=head1 COPYRIGHT
+
+This program is free software, you can redistribute it and/or modify it 
+under the same terms as Perl itself.
+
+=cut
+
+1;
diff --git a/tags/0.13/t/01use.t b/tags/0.13/t/01use.t
new file mode 100644 (file)
index 0000000..ccc1771
--- /dev/null
@@ -0,0 +1,5 @@
+use strict;
+use Test::More tests => 2;
+
+BEGIN { use_ok('Catalyst::View::TT') }
+BEGIN { use_ok('Catalyst::Helper::View::TT') }
diff --git a/tags/0.13/t/02pod.t b/tags/0.13/t/02pod.t
new file mode 100644 (file)
index 0000000..1647794
--- /dev/null
@@ -0,0 +1,7 @@
+use Test::More;
+
+eval "use Test::Pod 1.14";
+plan skip_all => 'Test::Pod 1.14 required' if $@;
+plan skip_all => 'set TEST_POD to enable this test' unless $ENV{TEST_POD};
+
+all_pod_files_ok();
diff --git a/tags/0.13/t/03podcoverage.t b/tags/0.13/t/03podcoverage.t
new file mode 100644 (file)
index 0000000..d91be5e
--- /dev/null
@@ -0,0 +1,7 @@
+use Test::More;
+
+eval "use Test::Pod::Coverage 1.04";
+plan skip_all => 'Test::Pod::Coverage 1.04 required' if $@;
+plan skip_all => 'set TEST_POD to enable this test' unless $ENV{TEST_POD};
+
+all_pod_coverage_ok();