[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