[Catalyst-dev] Patches for Catalyst::View::TT and Catalyst::Helper
Andy Wardley
abw at wardley.org
Fri Aug 19 20:53:51 CEST 2005
Hello all,
First let me say how cool Catalyst is. I've only just started playing with it,
but I like what I see so far! Great job, guys. Big respect to everyone involved.
Rather unsurprisingly, I quickly gravitated towards the Catalyst::View::TT
module and starting poking it with a stick. I found a couple of minor things
I thought I could improve on a litte.
There's a patch attached against Catalyst-View-TT-0.12 which implements the
following:
* removed the EVAL_PERL option from the default TT configuration.
TT sets this to 0 by default anyway.
* added the TIMER option to control when Template::Timer gets used.
The default remains the same: it's on when debugging, off otherwise,
but you can explicitly set TIMER one way or the other if you want to.
Also added error checking to make sure the Timer doesn't overwrite a
CONTEXT object set explicity somewhere else in the config.
* added the CATALYST_VAR option. When unset, it reverts to the current
behaviour, giving you 'c', 'base' and 'name' variables. When set to a
value (e.g. 'Catalyst'), it creates a single template variable of that
name for the context (the base, name and others can then be fetched through
the context)
* added some error checking against the return values of Template->new()
* added another helper module, Catalyst::Helper::View::TTSite which does
the same thing as C::H::V::TT, but also creates a bunch of templates,
css files, etc, to get you started.
* updated all the documentation
There's also a tiny patch for Catalyst::Helper which adds some error checking to
the result returned from a Template->process().
Cheers
A
-------------- next part --------------
diff -Naur Catalyst-View-TT-0.12/lib/Catalyst/Helper/View/TTSite.pm Catalyst-View-TT-0.12-abw/lib/Catalyst/Helper/View/TTSite.pm
--- Catalyst-View-TT-0.12/lib/Catalyst/Helper/View/TTSite.pm 1970-01-01 01:00:00.000000000 +0100
+++ Catalyst-View-TT-0.12-abw/lib/Catalyst/Helper/View/TTSite.pm 2005-08-19 19:20:44.000000000 +0100
@@ -0,0 +1,358 @@
+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, '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 at 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';
+
+sub new {
+ my $self = shift;
+ my $c = shift;
+ my $root = $c->config->{ root };
+ my $template = $c->config->{ template } || { };
+
+ $template->{ CATALYST_VAR } ||= 'Catalyst',
+ $template->{ INCLUDE_PATH } ||= [ "$root/templates/src", "$root/templates/lib" ];
+ $template->{ PRE_PROCESS } ||= 'config/main';
+ $template->{ WRAPPER } ||= 'site/wrapper';
+ $template->{ ERROR } ||= 'error.tt2';
+
+ return $self->SUPER::new($c, @_);
+}
+
+=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">© [% 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 -Naur Catalyst-View-TT-0.12/lib/Catalyst/View/TT.pm Catalyst-View-TT-0.12-abw/lib/Catalyst/View/TT.pm
--- Catalyst-View-TT-0.12/lib/Catalyst/View/TT.pm 2005-06-27 08:16:06.000000000 +0100
+++ Catalyst-View-TT-0.12-abw/lib/Catalyst/View/TT.pm 2005-08-19 19:19:24.000000000 +0100
@@ -16,56 +16,217 @@
=head1 SYNOPSIS
- # use the helper
- myapp_create.pl view TT TT
+# use the helper to create View
- # lib/MyApp/View/TT.pm
- package MyApp::View::TT;
+ $ script/myapp_create.pl view TT TT
+# configure in lib/MyApp.pm
+
+ our $ROOT = '/home/dent/catalyst/MyApp';
+
+ MyApp->config({
+ name => 'MyApp',
+ root => $ROOT,
+ template => {
+ # 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 practice you'd probably set this from a config file;
- # defaults to $c->config->root
- __PACKAGE__->config->{INCLUDE_PATH} =
- '/usr/local/generic/templates:/usr/local/myapp/templates';
+ # In MyApp or MyApp::Controller::SomeController
+
+ sub end : Private {
+ my($self, $c) = @_;
+ $c->forward('MyApp::V::TT');
+ }
+
+=head2 CONFIGURATION
- 1;
+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';
- # Meanwhile, maybe in a private C<end> action
- $c->forward('MyApp::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>SUPER::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->SUPER::new(@_);
+ }
+The final, and perhaps most direct way, is to define a C<template>
+item in your main application configuration, again by calling the
+uniquitous C<config()> method. The items in the C<template> 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<SUPER> if you redefine the C<new()> method in a
+subclass).
-=head1 DESCRIPTION
+ package MyApp;
+
+ use strict;
+ use Catalyst;
+
+ our $ROOT = '/home/dent/catalyst/MyApp';
+
+ MyApp->config({
+ name => 'MyApp',
+ root => $ROOT,
+ template => {
+ 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 C<template> 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:
+
+F<message.tt2>:
-This is the Catalyst view class for the L<Template
-Toolkit|Template>. Your application subclass should inherit from this
-class. This plugin renders the template specified in
-C<$c-E<gt>stash-E<gt>{template}>, or failing that,
-C<$c-E<gt>request-E<gt>match>. The template variables are set up from
-the contents of C<$c-E<gt>stash>, augmented with template variable
-C<base> set to Catalyst's C<$c-E<gt>req-E<gt>base>, template variable
-C<c> to Catalyst's C<$c>, and template variable C<name> to Catalyst's
-C<$c-E<gt>config-E<gt>{name}>. The output is stored in
+ 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,
+ template => {
+ 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>.
-If you want to override TT config settings, you can do it in your
-application's view class by setting
-C<__PACKAGE__-E<gt>config-E<gt>{OPTION}>, as shown in the Synopsis. Of
-interest might be C<EVAL_PERL>, which is disabled by default,
-C<INCLUDE_PATH>, and C<LOAD_TEMPLATES>, which is set to use the
-provider.
-
-If you want to use C<EVAL_PERL>, add something like this:
-
- __PACKAGE__->config->{EVAL_PERL} = 1;
- __PACKAGE__->config->{LOAD_TEMPLATES} = undef;
-
-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:
+=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 -->
@@ -77,10 +238,17 @@
<!-- TIMER END: process mainmenu/footer.tt (0.003016 seconds) -->
-You can suppress template profiling when debug is enabled by setting:
+You can suppress template profiling by setting the C<TIMER> configuration
+item to a false value.
- __PACKAGE__->config->{CONTEXT} = undef;
+ MyApp->config({
+ template => {
+ TIMER => 0,
+ },
+ });
+You can also use this variable to enable profiling even when debugging
+is turned off. Simply set it to any true value.
=head2 METHODS
@@ -88,8 +256,8 @@
=item new
-The constructor for the TT view. Sets up the template provider,
-and reads the application config.
+The constructor for the TT view. Sets up the template provider, and
+reads the application config.
=cut
@@ -97,18 +265,45 @@
my $self = shift;
my $c = shift;
$self = $self->NEXT::new(@_);
- my $root = $c->config->{root};
- my %config = (
- EVAL_PERL => 0,
+
+ my $root = $c->config->{ root };
+ my $template = $c->config->{ template } || { };
+ my $config = {
INCLUDE_PATH => [ $root, "$root/base" ],
- %{ $self->config() }
- );
+ %{ $self->config },
+ %$template,
+ };
+
+ # copy across any CATALYST_VAR defined in template config
+ $self->config->{ CATALYST_VAR } = $template->{ CATALYST_VAR }
+ if $template->{ CATALYST_VAR };
+
+ # 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 && not exists $config{CONTEXT} ) {
- $config{CONTEXT} = Template::Timer->new(%config);
+ if ($c->debug) {
+ use Data::Dumper;
+ $c->log->debug("TT Config: ", Dumper($config));
}
- $self->template( Template->new( \%config ) );
+ my $tt = Template->new($config) || do {
+ my $error = Template->error();
+ $c->log->error($error);
+ $c->error($error);
+ return undef;
+ };
+
+ $self->template($tt);
return $self;
}
@@ -118,8 +313,11 @@
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}>. Output is stored in
-C<$c-E<gt>response-E<gt>output>.
+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
@@ -136,20 +334,17 @@
$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,
- {
- base => $c->req->base,
- c => $c,
- name => $c->config->{name},
- %{ $c->stash }
- },
- \$output
- )
- )
- {
+ unless ($self->template->process($template, $vars, \$output)) {
my $error = $self->template->error;
$error = qq/Couldn't render template "$error"/;
$c->log->error($error);
@@ -168,20 +363,39 @@
=item config
-This allows your view subclass to pass additional settings to the
-TT config hash.
+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<Template::Manual>
+L<Catalyst>, L<Catalyst::Helper::View::TT>,
+L<Catalyst::Helper::View::TTSite>, L<Template::Manual>
=head1 AUTHOR
-Sebastian Riedel, C<sri at cpan.org>
-Marcus Ramberg, C<mramberg at cpan.org>
-Jesse Sheidlower, C<jester at panix.com>
+Sebastian Riedel C<sri at cpan.org>,
+Marcus Ramberg C<mramberg at cpan.org>,
+Jesse Sheidlower C<jester at panix.com>,
+Andy Wardley, C<abw at cpan.org>
=head1 COPYRIGHT
diff -Naur Catalyst-View-TT-0.12/MANIFEST Catalyst-View-TT-0.12-abw/MANIFEST
--- Catalyst-View-TT-0.12/MANIFEST 2005-04-15 14:58:32.000000000 +0100
+++ Catalyst-View-TT-0.12-abw/MANIFEST 2005-08-19 18:50:43.000000000 +0100
@@ -1,5 +1,6 @@
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
-------------- next part --------------
diff -Naur Catalyst-5.33/lib/Catalyst/Helper.pm Catalyst-5.33-abw/lib/Catalyst/Helper.pm
--- Catalyst-5.33/lib/Catalyst/Helper.pm 2005-08-10 14:27:08.000000000 +0100
+++ Catalyst-5.33-abw/lib/Catalyst/Helper.pm 2005-08-19 17:33:43.000000000 +0100
@@ -266,7 +266,10 @@
my $template = $self->get_file( ( caller(0) )[0], $file );
return 0 unless $template;
my $output;
- $t->process( \$template, { %{$self}, %$vars }, \$output );
+ $t->process( \$template, { %{$self}, %$vars }, \$output )
+ || Catalyst::Exception->throw(
+ message => qq/Couldn't process "$file", / . $t->error()
+ );
$self->mk_file( $path, $output );
}
More information about the Catalyst-dev
mailing list