[Catalyst-commits] r11511 - in Catalyst-View-TD/trunk:
lib/Catalyst/View t t/lib t/lib/TestApp/TD t/lib/TestApp/View
theory at dev.catalyst.perl.org
theory at dev.catalyst.perl.org
Sat Oct 10 03:32:09 GMT 2009
Author: theory
Date: 2009-10-10 03:32:08 +0000 (Sat, 10 Oct 2009)
New Revision: 11511
Added:
Catalyst-View-TD/trunk/t/lib/TestApp/TD/Additional.pm
Catalyst-View-TD/trunk/t/lib/TestApp/View/Additional.pm
Modified:
Catalyst-View-TD/trunk/lib/Catalyst/View/TD.pm
Catalyst-View-TD/trunk/t/06includepath.t
Catalyst-View-TD/trunk/t/lib/TestApp.pm
Catalyst-View-TD/trunk/t/lib/TestApp/TD/Appconfig.pm
Log:
Added dynamic management of the C<dispatch_to> list similar to the dynamic
INCLUDE_PATH stuff in View::TT.
Modified: Catalyst-View-TD/trunk/lib/Catalyst/View/TD.pm
===================================================================
--- Catalyst-View-TD/trunk/lib/Catalyst/View/TD.pm 2009-10-09 06:19:26 UTC (rev 11510)
+++ Catalyst-View-TD/trunk/lib/Catalyst/View/TD.pm 2009-10-10 03:32:08 UTC (rev 11511)
@@ -8,6 +8,7 @@
our $VERSION = '0.01';
__PACKAGE__->mk_accessors('init');
+__PACKAGE__->mk_accessors('dispatch_to');
=head1 Name
@@ -73,7 +74,12 @@
$config->{dispatch_to} = _load_templates( $class );
}
- $class->next::method( $c, { init => $config } );
+ my $self = $class->next::method( $c, { init => $config } );
+
+ # Set base template casses. Local'd in render if needed
+ $self->dispatch_to( delete $config->{dispatch_to} );
+
+ return $self;
}
sub _load_templates {
@@ -123,7 +129,7 @@
my $output = eval { $self->render($c, $template) };
- if (my $error = $@) {
+ if (my $error = $@ ? $@ : ref $output ? $$output : undef) {
my $error = qq/Couldn't render template: "$error"/;
$c->log->error($error);
$c->error($error);
@@ -147,12 +153,20 @@
my $vars = {
ref $args eq 'HASH' ? %{ $args || {} } : $c ? %{ $c->stash } : {},
};
- Template::Declare->init( %{ $self->init } );
+
+ my $init = $self->init;
+
+ local $self->{dispatch_to} = [
+ @{ $vars->{add_template_classes} },
+ @{ $self->{dispatch_to} },
+ ] if ref $vars->{add_template_classes};
+
+ Template::Declare->init( %{ $init }, dispatch_to => $self->dispatch_to );
Template::Declare::Catalyst->context($c);
my $output = eval { Template::Declare->show($template, $vars) };
if (my $err = $@) {
return $err if ref $err;
- die $err;
+ die $$err;
}
return $output;
}
@@ -270,31 +284,26 @@
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.
-=begin comment
-
-Implement this?
-
=head2 Dynamic C<dispatch_to>
Sometimes it is desirable to modify C<dispatch_to> for your templates at
-runtime.
+runtime. Additional paths can be added to the start of C<dispatch_to> via the
+stash as follows:
-Additional paths can be added to the start of C<dispatch_to> via the stash as
-follows:
+ $c->stash->{add_template_classes} = [ 'MyApp::Other::Templates' ];
- $c->stash->{additional_template_classes} = [
- 'MyApp::Other::Templates'
- ];
-
If you need to add template classes paths to the end of C<dispatch_to>, there
is also a C<include_path()> accessor:
- push( @{ $c->view('HTML')->dispatch_to }, 'My::Templates' );
+ my $view = $c->view('HTML')
+ push @{ $view->dispatch_to }, 'My::Templates'
+ unless grep { $_ eq 'My::Templates' } $view->dispatch_to;
-Note that if you use C<dispatch_to()> to add extra paths to C<dispatch_to>,
-you B<must> check for duplicate paths. Without such checking, the above code
-will add "My::Templates" to C<dispatch_to> for every request, leading to a
-memory leak.
+Note that if you use C<dispatch_to()> to add extra template classes, they are
+I<permanently> added. You therefore B<must> check for duplicate paths if you
+do this on a per-request basis, as in this example. Otherwise, the class will
+continue to be added on every request, which woudld be a rather ugly memory
+leak.
A safer approach is to use C<dispatch_to()> to overwrite the array of template
classes rather than adding to it. This eliminates both the need to perform
@@ -302,12 +311,11 @@
$c->view('HTML')->dispatch_to( ['My::Templates', 'Your::Templates'] );
-If you are calling C<render> directly then you can specify dynamic paths by
-having a C<additional_template_classes> key with a value of additonal
-directories to search. See L</"Capturing Template Output"> for an example of
-this.
+This is safe to do on a per-request basis.
-=end comment
+If you are calling C<render> directly, then you can specify extra template
+classes under the C<add_template_classes> key. See L</"Capturing Template
+Output"> for an example.
=head2 Rendering Views
@@ -398,8 +406,8 @@
Subject => 'A TD Email',
],
body => $c->view('TD')->render($c, 'email', {
- additional_template_classes => [ 'My::EmailTemplates' ],
- email_tmpl_param1 => 'foo'
+ add_template_classes => [ 'My::EmailTemplates' ],
+ email_tmpl_param1 => 'foo'
}),
);
# Redirect or display a message
Modified: Catalyst-View-TD/trunk/t/06includepath.t
===================================================================
--- Catalyst-View-TD/trunk/t/06includepath.t 2009-10-09 06:19:26 UTC (rev 11510)
+++ Catalyst-View-TD/trunk/t/06includepath.t 2009-10-10 03:32:08 UTC (rev 11511)
@@ -1,30 +1,36 @@
use strict;
use warnings;
-use Test::More skip_all => 'Not sure we will need this feature with TD';
+use Test::More tests => 12;
-use Test::More tests => 10;
-
use FindBin;
use lib "$FindBin::Bin/lib";
use_ok('Catalyst::Test', 'TestApp');
my $response;
-my $inital_dispatch_to = [ @{ TestApp->view('Appconfig')->dispatch_to } ];
+my $initial_dispatch_to = [ @{ TestApp->view('Appconfig')->dispatch_to } ];
-ok(($response = request("/test_includepath?view=Appconfig&template=testpath&additionalpath=test_dispatch_to"))->is_success, 'additional_template_path request');
-is($response->content, TestApp->config->{default_message}, 'additional_template_path message');
+ok(($response = request("/test_dispatchto?view=Appconfig&template=testclass&additionalclass=TestApp::TD::Additional"))->is_success, 'additional_template_class request');
+is($response->content, "From Additional: " . TestApp->config->{default_message}, 'additional_template_class message');
-is_deeply($inital_dispatch_to,
+is_deeply($initial_dispatch_to,
TestApp->view('Appconfig')->dispatch_to,
- 'Include path is unchanged');
+ 'dispatch_to is unchanged');
-ok(($response = request("/test_includepath?view=Includepath&template=testpath"))->is_success, 'scalar include path from config request');
-is($response->content, TestApp->config->{default_message}, 'scalar include path with delimiter from config message');
+ok(($response = request("/test_dispatchto?view=Additional&template=testclass"))->is_success, 'dispatch_to set to the alternate class');
+is($response->content, "From Additional: " . TestApp->config->{default_message}, 'request to view using the alternate template class');
-ok(($response = request("/test_includepath?view=Includepath2&template=testpath"))->is_success, 'object ref (that stringifys to the path) include path from config request');
-is($response->content, TestApp->config->{default_message}, 'object ref (that stringifys to the path) include path from config message');
+ok(($response = request("/test_dispatchto?view=Appconfig&template=testclass&addclass=TestApp::TD::Additional"))->is_success, 'add class to the array');
+is($response->content, "From Additional: " . TestApp->config->{default_message}, 'added class template renders');
-ok(($response = request("/test_includepath?view=Includepath3&template=testpath&addpath=test_dispatch_to"))->is_success, 'array ref include path from config not replaced by another array request');
-is($response->content, TestApp->config->{default_message}, 'array ref include path from config not replaced by another array message');
+is_deeply([@$initial_dispatch_to, 'TestApp::TD::Additional'],
+ TestApp->view('Appconfig')->dispatch_to,
+ 'dispatch_to has been changed');
+ok(($response = request("/test_dispatchto?view=Appconfig&template=testclass&setclass=TestApp::TD::Additional"))->is_success, 'set dispatch_to from request');
+is($response->content, "From Additional: " . TestApp->config->{default_message}, 'set class template renders');
+
+is_deeply(['TestApp::TD::Additional'],
+ TestApp->view('Appconfig')->dispatch_to,
+ 'dispatch_to has been overridden');
+
Added: Catalyst-View-TD/trunk/t/lib/TestApp/TD/Additional.pm
===================================================================
--- Catalyst-View-TD/trunk/t/lib/TestApp/TD/Additional.pm (rev 0)
+++ Catalyst-View-TD/trunk/t/lib/TestApp/TD/Additional.pm 2009-10-10 03:32:08 UTC (rev 11511)
@@ -0,0 +1,13 @@
+package TestApp::TD::Additional;
+
+use strict;
+use warnings;
+use Template::Declare::Tags;
+use base 'Template::Declare';
+
+template testclass => sub {
+ my ($self, $args) = @_;
+ outs "From Additional: $args->{message}";
+};
+
+1;
Modified: Catalyst-View-TD/trunk/t/lib/TestApp/TD/Appconfig.pm
===================================================================
--- Catalyst-View-TD/trunk/t/lib/TestApp/TD/Appconfig.pm 2009-10-09 06:19:26 UTC (rev 11510)
+++ Catalyst-View-TD/trunk/t/lib/TestApp/TD/Appconfig.pm 2009-10-10 03:32:08 UTC (rev 11511)
@@ -3,6 +3,7 @@
use strict;
use warnings;
use Template::Declare::Tags;
+use TestApp::TD::Additional;
template test => sub {
my ($self, $args) = @_;
Added: Catalyst-View-TD/trunk/t/lib/TestApp/View/Additional.pm
===================================================================
--- Catalyst-View-TD/trunk/t/lib/TestApp/View/Additional.pm (rev 0)
+++ Catalyst-View-TD/trunk/t/lib/TestApp/View/Additional.pm 2009-10-10 03:32:08 UTC (rev 11511)
@@ -0,0 +1,6 @@
+package TestApp::View::Additional;
+
+use strict;
+use base 'Catalyst::View::TD';
+
+1;
Modified: Catalyst-View-TD/trunk/t/lib/TestApp.pm
===================================================================
--- Catalyst-View-TD/trunk/t/lib/TestApp.pm 2009-10-09 06:19:26 UTC (rev 11510)
+++ Catalyst-View-TD/trunk/t/lib/TestApp.pm 2009-10-10 03:32:08 UTC (rev 11511)
@@ -36,21 +36,21 @@
$c->stash->{message} = $c->request->param('message') || $c->config->{default_message};
}
-sub test_includepath : Local {
+sub test_dispatchto : Local {
my ($self, $c) = @_;
- $c->stash->{message} = ($c->request->param('message') || $c->config->{default_message});
+ $c->stash->{message} = $c->request->param('message') || $c->config->{default_message};
$c->stash->{template} = $c->request->param('template');
- if ( $c->request->param('additionalpath') ){
- my $additionalpath = Path::Class::dir($c->config->{root}, $c->request->param('additionalpath'));
- $c->stash->{additional_template_paths} = ["$additionalpath"];
+ if ( my $class = $c->request->param('additionalclass') ){
+ $c->stash->{add_template_classes} = [$class];
}
- if ( $c->request->param('addpath') ){
- my $additionalpath = Path::Class::dir($c->config->{root}, $c->request->param('addpath'));
- my $view = 'TestApp::View::' . ($c->request->param('view') || $c->config->{default_view});
- no strict "refs";
- push @{$view . '::include_path'}, "$additionalpath";
- use strict;
+ if ( my $class = $c->request->param('addclass') ){
+ my $view = $self->view($c->request->param('view') || $c->config->{default_view});
+ push @{ $view->dispatch_to}, $class;
}
+ if ( my $class = $c->request->param('setclass') ){
+ my $view = $self->view($c->request->param('view') || $c->config->{default_view});
+ $view->dispatch_to([$class]);
+ }
}
sub test_render : Local {
More information about the Catalyst-commits
mailing list