[Catalyst-commits] r11689 - in Catalyst-View-TD/trunk: . lib/Catalyst/View t t/lib/TestApp/TD/HTML

theory at dev.catalyst.perl.org theory at dev.catalyst.perl.org
Thu Oct 29 19:04:49 GMT 2009


Author: theory
Date: 2009-10-29 19:04:48 +0000 (Thu, 29 Oct 2009)
New Revision: 11689

Added:
   Catalyst-View-TD/trunk/t/lib/TestApp/TD/HTML/User.pm
Modified:
   Catalyst-View-TD/trunk/
   Catalyst-View-TD/trunk/lib/Catalyst/View/TD.pm
   Catalyst-View-TD/trunk/t/12tdstuff.t
Log:
Document auto-aliasing

Also Added test to ensure that non-utility aliased templates work, and that
they can use the utility templates themselves. Oh, and I added some
`svn:ignore` values.




Property changes on: Catalyst-View-TD/trunk
___________________________________________________________________
Name: svn:ignore
   + META.yml
pm_to_blib
blib
inc
Makefile
README


Modified: Catalyst-View-TD/trunk/lib/Catalyst/View/TD.pm
===================================================================
--- Catalyst-View-TD/trunk/lib/Catalyst/View/TD.pm	2009-10-29 16:57:20 UTC (rev 11688)
+++ Catalyst-View-TD/trunk/lib/Catalyst/View/TD.pm	2009-10-29 19:04:48 UTC (rev 11689)
@@ -26,8 +26,9 @@
     MyApp->config(
         name     => 'MyApp',
         root     => MyApp->path_to('root'),
-        'View::TD' => {
+        'View::HTML => {
             dispatch_to     => ['TestApp::TD::HTML'], # Default
+            auto_alias      => 1,
             preprocessor    => sub { ... },
             around_template => sub { ... },
         },
@@ -55,7 +56,7 @@
         my ( $self, $c ) = @_;
         $c->stash->{template} = 'hello';
         $c->stash->{user}     = 'Slim Shady';
-        $c->forward( $c->view('TD') );
+        $c->forward( $c->view('HTML') );
     }
 
 =cut
@@ -247,13 +248,14 @@
 is to call the C<config()> method in the view subclass. This happens when the
 module is first loaded.
 
-    package MyApp::View::TD;
+    package MyApp::View::HTML;
 
     use strict;
     use base 'Catalyst::View::TD';
 
     MyApp::View::TD->config({
         dispatch_to     => [ 'MyApp::TD::HTML' ],
+        auto_alias      => 1,
         postprocessor   => sub { ... },
         around_template => sub { ... },
     });
@@ -268,18 +270,18 @@
         my $self = shift;
         $self->config({
             dispatch_to     => [ 'MyApp::TD::HTML' ],
+            auto_alias      => 1,
             postprocessor   => sub { ... },
             around_template => sub { ... },
         });
         return $self->next::method(@_);
     }
 
-The final, and perhaps most direct way, is to define a class item in your main
-application configuration, again by calling the ubiquitous 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 C<new()> method (which is one
-reason why you must remember to call it via C<MRO::Compat> if you redefine the
-C<new()> method in a subclass).
+The final, and perhaps most direct way, is to call the ubiquitous C<config()>
+method in your main application configuration. The items in the class hash are
+added to those already defined by the above two methods. This happens in the
+base class C<new()> method (which is one reason why you must remember to call
+it via C<MRO::Compat> if you redefine the C<new()> method in a subclass).
 
     package MyApp;
 
@@ -290,6 +292,7 @@
         name     => 'MyApp',
         'View::HTML' => {
             dispatch_to     => [ 'MyApp::TD::HTML' ],
+            auto_alias      => 1,
             postprocessor   => sub { ... },
             around_template => sub { ... },
         },
@@ -335,18 +338,132 @@
 
 =head2 Auto-Aliasing
 
-Unless you specify C<dispatch_to> in your configuration, Catalyst::View::TD
-dispatches to only one template class. That class has the same name as your
-view class, except that C<View> is replaced with C<TD>. Thus, a view named
-C<MyApp::View::Whatever> would dispatch to the template class
-C<MyApp::TD::Whatever>. You can specify your own template class via the
-C<dispatch_to> configuration if you'd like to use a different template class.
+In addition to the dispatch template class (as defined in the C<dispatch_to>
+configuration, or defaulting to C<MyApp::TD::ViewName>), you can write
+templates in other classes and they will automatically be aliased into the
+dispatch class. The aliasing of templates is similar to how controller actions
+map to URLs.
 
-But the point is, that one template class (or however many you choose to
-include in the C<dispatch_to> configuration) is the only class who's templates
-will be available. But putting all of your templates in a single template
-class can get messy fast, especially if you have non-root actions.
+For example, say that you have a dispatch template class for your
+C<MyApp::View::XHTML> view named C<MyApp::TD::XHMTL>:
 
+    package TestApp::TD::XHTML;
+    use Template::Declare::Tags;
+
+    template home => sub {
+        html {
+            head { title { 'Welcome home' } };
+            body { h1    { 'Welcome home' } };
+        };
+    };
+
+This will handle a call to render the C</home> (or just C<home>):
+
+        $c->stash->{template} = 'home';
+        $c->forward( $c->view('XHTML') );
+
+But let's say that you have a controller, C<MyApp::Controller::Users>, that
+has an action named C<list>. Ideally what you'd like to do is to have it
+dispatch to a view named C</users/list>. And sure enough, you can define one
+right in the dispatch class if you like:
+
+    template 'users/list' => sub {
+        my ($self, $args) = @_;
+        ul {
+            li { $_ } for @{ $args->{users} };
+        };
+    };
+
+But it can get to be a nightmare to manage I<all> of your templates in this
+one class. A better idea is to divide them up into other classes just
+as you have them in separate contollers. The C<auto_alias> feature of
+Catalyst::View::TD does just that. Rather than define a template named
+C<users/list> in the dispatch class (C<MyApp::TD::XHTML>), create one
+named C<list> in C<MyApp::TD::XHTML::Users>:
+
+    package TestApp::TD::XHTML::Users;
+    use Template::Declare::Tags;
+
+    template list => sub {
+        my ($self, $args) = @_;
+        ul { li { $_ } for @{ $args->{users} } };
+    };
+
+Catalyst::View::TD will automatically mix the templates found in all classes
+defined below the dispatch class into the dispatch class. Thus this template
+will be mixed into C<MyApp::TD::XHTML> as C<users/list>. The nice thing about
+this is it allows you to create template classes with templates that
+correspond directly to controller classes and their actions.
+
+You can also use this approach to create utility templates. For example,
+if you wanted to put the header and footer output into utility templates,
+you could put them into a Util class:
+
+    package TestApp::TD::XHTML::Util;
+    use Template::Declare::Tags;
+
+    template header => sub {
+        my ($self, $args) = @_;
+        head { title {  $args->{title} } };
+    };
+
+    template footer => sub {
+        div {
+            id is 'fineprint';
+            p { 'Site contents licensed under a Creative Commons License.' }
+        };
+    };
+
+And then you can simply use these templates from the dispatch class or any
+other aliased template class, including the dispatch class:
+
+    package TestApp::TD::XHTML;
+    use Template::Declare::Tags;
+
+    template home => sub {
+        html {
+            show '/util/header';
+            body {
+                h1 { 'Welcome home' };
+                show '/util/footer';
+            };
+        };
+    };
+
+And the users class:
+
+    package TestApp::TD::XHTML::Users;
+    use Template::Declare::Tags;
+
+    template list => sub {
+        my ($self, $args) = @_;
+        html {
+            show '/util/header';
+            body {
+                ul { li { $_ } for @{ $args->{users} } };
+                show '/util/footer';
+            };
+        };
+    };
+
+If you'd rather control aliasing of templates yourself, you can always set
+C<auto_alias> to a false value. Then you'd just need to explicitly inherit
+from C<Template::Declare::Catayst> and do the mixing yourself. The equivalent
+to the auti-alising in the above examples would be:
+
+    package TestApp::TD::XHTML;
+    use base 'Template::Declare::Catalyst';
+    use Template::Declare::Tags;
+
+    use TestApp::TD::XHTML::Users;
+    use TestApp::TD::XHTML::Util;
+
+    alias TestApp::TD::XHTML::Users under '/users';
+    alias TestApp::TD::XHTML::Util under '/util';
+
+This would be the way to go if you wanted finer control over
+Template::Declare's L<composition features|Template::Declare/"Template Composition">.
+
 =head2 Rendering Views
 
 The Catlyst C<view()> method renders the template specified in the C<template>

Modified: Catalyst-View-TD/trunk/t/12tdstuff.t
===================================================================
--- Catalyst-View-TD/trunk/t/12tdstuff.t	2009-10-29 16:57:20 UTC (rev 11688)
+++ Catalyst-View-TD/trunk/t/12tdstuff.t	2009-10-29 19:04:48 UTC (rev 11689)
@@ -1,6 +1,6 @@
 use strict;
 use warnings;
-use Test::More tests => 11;
+use Test::More tests => 12;
 #use Test::More 'no_plan';
 
 use FindBin;
@@ -26,6 +26,8 @@
 ok $td->auto_alias, 'It should be auto-aliasing';
 is $td->render(undef, 'body'), "header\nbody\nfooter\n",
     'Utility templates should be aliased';
+is $td->render(undef, 'user/list'), "header\nuser list\nfooter\n",
+    'User templates should be aliased under /user';
 
 # Check manual aliasing.
 ok $td = TestApp->view('NoAlias'), 'Get NoAlias view object';

Added: Catalyst-View-TD/trunk/t/lib/TestApp/TD/HTML/User.pm
===================================================================
--- Catalyst-View-TD/trunk/t/lib/TestApp/TD/HTML/User.pm	                        (rev 0)
+++ Catalyst-View-TD/trunk/t/lib/TestApp/TD/HTML/User.pm	2009-10-29 19:04:48 UTC (rev 11689)
@@ -0,0 +1,13 @@
+package TestApp::TD::HTML::User;
+
+use strict;
+use warnings;
+use Template::Declare::Tags;
+
+template list => sub {
+    show '/util/header';
+    outs "user list\n";
+    show '/util/footer';
+};
+
+1;




More information about the Catalyst-commits mailing list