the class used to create the TT object can now be customized
[catagits/Catalyst-View-TT.git] / lib / Catalyst / View / TT.pm
index dc3307d..f51331f 100644 (file)
@@ -8,11 +8,13 @@ use Data::Dump 'dump';
 use Template;
 use Template::Timer;
 use MRO::Compat;
-use Scalar::Util qw/blessed/;
+use Scalar::Util qw/blessed weaken/;
 
-our $VERSION = '0.34';
+our $VERSION = '0.36';
+$VERSION = eval $VERSION;
 
 __PACKAGE__->mk_accessors('template');
+__PACKAGE__->mk_accessors('expose_methods');
 __PACKAGE__->mk_accessors('include_path');
 
 *paths = \&include_path;
@@ -42,6 +44,7 @@ Catalyst::View::TT - Template View Class
         PRE_PROCESS        => 'config/main',
         WRAPPER            => 'site/wrapper',
         render_die => 1, # Default for new apps, see render method docs
+        expose_methods => [qw/method_in_view_class/],
     );
 
 # render view from lib/MyApp.pm or lib/MyApp::Controller::SomeController.pm
@@ -86,6 +89,7 @@ sub new {
     my $config = {
         EVAL_PERL          => 0,
         TEMPLATE_EXTENSION => '',
+        CLASS              => 'Template',
         %{ $class->config },
         %{$arguments},
     };
@@ -127,6 +131,7 @@ sub new {
     # Set base include paths. Local'd in render if needed
     $self->include_path($config->{INCLUDE_PATH});
 
+    $self->expose_methods($config->{expose_methods});
     $self->config($config);
 
     # Creation of template outside of call to new so that we can pass [ $self ]
@@ -184,8 +189,8 @@ sub new {
     }
 
     $self->{template} =
-        Template->new($config) || do {
-            my $error = Template->error();
+        $config->{CLASS}->new($config) || do {
+            my $error = $config->{CLASS}->error();
             $c->log->error($error);
             $c->error($error);
             return undef;
@@ -264,16 +269,33 @@ sub template_vars {
     return  () unless $c;
     my $cvar = $self->config->{CATALYST_VAR};
 
-    defined $cvar
+    my %vars = defined $cvar
       ? ( $cvar => $c )
       : (
         c    => $c,
         base => $c->req->base,
         name => $c->config->{name}
-      )
+      );
+
+    if ($self->expose_methods) {
+        my $meta = $self->meta;
+        foreach my $method_name (@{$self->expose_methods}) {
+            my $method = $meta->find_method_by_name( $method_name );
+            unless ($method) {
+                Catalyst::Exception->throw( "$method_name not found in TT view" );
+            }
+            my $method_body = $method->body;
+            my $weak_ctx = $c;
+            weaken $weak_ctx;
+            my $sub = sub {
+                $self->$method_body($weak_ctx, @_);
+            };
+            $vars{$method_name} = $sub;
+        }
+    }
+    return %vars;
 }
 
-
 1;
 
 __END__
@@ -558,6 +580,28 @@ the TT configuration hash, or to set the options as below:
 
 The list of paths TT will look for templates in.
 
+=head2 expose_methods
+
+The list of methods in your View class which should be made available to the templates.
+
+For example:
+
+  expose_methods => [qw/uri_for_css/],
+
+  ...
+
+  sub uri_for_css {
+    my ($self, $c, $filename) = @_;
+
+    # additional complexity like checking file exists here
+
+    return $c->uri_for('/static/css/' . $filename);
+  }
+
+Then in the template:
+
+  [% uri_for_css('home.css') %]
+
 =head2 C<CATALYST_VAR>
 
 Allows you to change the name of the Catalyst context object. If set, it will also
@@ -644,6 +688,26 @@ from the general config, into the config for the provider:
 This can prove useful when you want to use the additional_template_paths hack
 in your own provider, or if you need to use Template::Provider::Encoding
 
+=head2 C<CLASS>
+
+Allows you to specify a custom class to use as the template class instead of
+L<Template>.
+
+    package MyApp::View::Web;
+
+    use strict;
+    use base 'Catalyst::View::TT';
+
+    use Template::AutoFilter;
+
+    __PACKAGE__->config({
+        CLASS => 'Template::AutoFilter',
+    });
+
+This is useful if you want to use your own subclasses of L<Template>, so you
+can, for example, prevent XSS by automatically filtering all output through
+C<| html>.
+
 =head2 HELPERS
 
 The L<Catalyst::Helper::View::TT> and
@@ -686,6 +750,8 @@ Jesse Sheidlower, C<jester@panix.com>
 
 Andy Wardley, C<abw@cpan.org>
 
+Luke Saunders, C<luke.saunders@gmail.com>
+
 =head1 COPYRIGHT
 
 This program is free software. You can redistribute it and/or modify it