update for newer catalyst unicode changes
[catagits/Catalyst-View-TT.git] / lib / Catalyst / View / TT.pm
index 3d8c751..db72b25 100644 (file)
@@ -10,11 +10,13 @@ use Template::Timer;
 use MRO::Compat;
 use Scalar::Util qw/blessed weaken/;
 
-our $VERSION = '0.35';
+our $VERSION = '0.42';
+$VERSION = eval $VERSION;
 
 __PACKAGE__->mk_accessors('template');
 __PACKAGE__->mk_accessors('expose_methods');
 __PACKAGE__->mk_accessors('include_path');
+__PACKAGE__->mk_accessors('content_type');
 
 *paths = \&include_path;
 
@@ -28,17 +30,14 @@ Catalyst::View::TT - Template View Class
 
     myapp_create.pl view Web TT
 
-# add custom configration in View/Web.pm
+# add custom configuration in View/Web.pm
 
     __PACKAGE__->config(
         # any TT configuration items go here
-        INCLUDE_PATH => [
-          MyApp->path_to( 'root', 'src' ),
-          MyApp->path_to( 'root', 'lib' ),
-        ],
         TEMPLATE_EXTENSION => '.tt',
         CATALYST_VAR => 'c',
         TIMER        => 0,
+        ENCODING     => 'utf-8'
         # Not set by default
         PRE_PROCESS        => 'config/main',
         WRAPPER            => 'site/wrapper',
@@ -46,6 +45,17 @@ Catalyst::View::TT - Template View Class
         expose_methods => [qw/method_in_view_class/],
     );
 
+# add include path configuration in MyApp.pm
+
+    __PACKAGE__->config(
+        'View::Web' => {
+            INCLUDE_PATH => [
+                __PACKAGE__->path_to( 'root', 'src' ),
+                __PACKAGE__->path_to( 'root', 'lib' ),
+            ],
+        },
+    );
+
 # render view from lib/MyApp.pm or lib/MyApp::Controller::SomeController.pm
 
     sub message : Global {
@@ -88,6 +98,7 @@ sub new {
     my $config = {
         EVAL_PERL          => 0,
         TEMPLATE_EXTENSION => '',
+        CLASS              => 'Template',
         %{ $class->config },
         %{$arguments},
     };
@@ -136,7 +147,7 @@ sub new {
     # as INCLUDE_PATH config item, which then gets ->paths() called to get list
     # of include paths to search for templates.
 
-    # Use a weakend copy of self so we dont have loops preventing GC from working
+    # Use a weakened copy of self so we don't have loops preventing GC from working
     my $copy = $self;
     Scalar::Util::weaken($copy);
     $config->{INCLUDE_PATH} = [ sub { $copy->paths } ];
@@ -187,8 +198,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;
@@ -219,7 +230,8 @@ sub process {
     }
 
     unless ( $c->response->content_type ) {
-        $c->response->content_type('text/html; charset=utf-8');
+        my $default = $self->content_type || 'text/html; charset=UTF-8';
+        $c->response->content_type($default);
     }
 
     $c->response->body($output);
@@ -255,7 +267,7 @@ sub render {
             die $self->template->error if $self->{render_die};
             return $self->template->error;
         }
-        $c->log->debug('The Catalyst::View::TT render() method will start dying on error in a future release. Unless you are calling the render() method manually, you probably want the new behaviour, so set render_die => 1 in config for ' . blessed($self) . '. If you wish to continue to return the exception rather than throwing it, add render_die => 0 to your config.') if $c->debug;
+        $c->log->debug('The Catalyst::View::TT render() method will start dying on error in a future release. Unless you are calling the render() method manually, you probably want the new behaviour, so set render_die => 1 in config for ' . blessed($self) . '. If you wish to continue to return the exception rather than throwing it, add render_die => 0 to your config.') if $c && $c->debug;
         return $self->template->error;
     }
     return $output;
@@ -278,7 +290,7 @@ sub template_vars {
     if ($self->expose_methods) {
         my $meta = $self->meta;
         foreach my $method_name (@{$self->expose_methods}) {
-            my $method = $meta->get_method( $method_name );
+            my $method = $meta->find_method_by_name( $method_name );
             unless ($method) {
                 Catalyst::Exception->throw( "$method_name not found in TT view" );
             }
@@ -316,11 +328,9 @@ replacing C<MyApp> with the name of your application) which looks
 something like this:
 
     package FooBar::View::Web;
+    use Moose;
 
-    use strict;
-    use warnings;
-
-    use base 'Catalyst::View::TT';
+    extends 'Catalyst::View::TT';
 
     __PACKAGE__->config(DEBUG => 'all');
 
@@ -375,22 +385,32 @@ first way is to call the C<config()> method in the view subclass.  This
 happens when the module is first loaded.
 
     package MyApp::View::Web;
-
-    use strict;
-    use base 'Catalyst::View::TT';
+    use Moose;
+    extends 'Catalyst::View::TT';
 
     __PACKAGE__->config({
-        INCLUDE_PATH => [
-            MyApp->path_to( 'root', 'templates', 'lib' ),
-            MyApp->path_to( 'root', 'templates', 'src' ),
-        ],
         PRE_PROCESS  => 'config/main',
         WRAPPER      => 'site/wrapper',
     });
 
 You may also override the configuration provided in the view class by adding
-a 'View::Web' section to your application config (either in the application
-main class, or in your configuration file). This should be reserved for
+a 'View::Web' section to your application config.
+
+This should generally be used to inject the include paths into the view to
+avoid the view trying to load the application to resolve paths.
+
+    .. inside MyApp.pm ..
+    __PACKAGE__->config(
+        'View::Web' => {
+            INCLUDE_PATH => [
+                __PACKAGE__->path_to( 'root', 'templates', 'lib' ),
+                __PACKAGE__->path_to( 'root', 'templates', 'src' ),
+            ],
+        },
+    );
+
+You can also configure your view from within your config file if you're
+using L<Catalyst::Plugin::ConfigLoader>. This should be reserved for
 deployment-specific concerns. For example:
 
     # MyApp_local.conf (Config::General format)
@@ -430,9 +450,46 @@ checking and the chance of a memory leak:
     @{ $c->view('Web')->include_path } = qw/path another_path/;
 
 If you are calling C<render> directly then you can specify dynamic paths by
-having a C<additional_template_paths> key with a value of additonal directories
+having a C<additional_template_paths> key with a value of additional directories
 to search. See L<CAPTURING TEMPLATE OUTPUT> for an example showing this.
 
+=head2 Unicode (pre Catalyst v5.90080)
+
+B<NOTE> Starting with L<Catalyst> v5.90080 unicode and encoding has been
+baked into core, and the default encoding is UTF-8.  The following advice
+is for older versions of L<Catalyst>.
+
+Be sure to set C<< ENCODING => 'utf-8' >> and use
+L<Catalyst::Plugin::Unicode::Encoding> if you want to use non-ascii
+characters (encoded as utf-8) in your templates.  This is only needed if
+you actually have UTF8 literals in your templates and the BOM is not
+properly set.  Setting encoding here does not magically encode your
+template output.  If you are using this version of L<Catalyst> you need
+to all the Unicode plugin, or upgrade (preferred)
+
+=head2 Unicode (Catalyst v5.90080+)
+
+This version of L<Catalyst> will automatically encode your body output
+to UTF8. This means if your variables contain multibyte characters you don't
+need top do anything else to get UTF8 output.  B<However> if your templates
+contain UTF8 literals (like, multibyte characters actually in the template
+text), then you do need to either set the BOM mark on the template file or
+instruct TT to decode the templates at load time via the ENCODING configuration
+setting.  Most of the time you can just do:
+
+    MyApp::View::HTML->config(
+        ENCODING => 'UTF-8');
+
+and that will just take care of everything.  This configuration setting will
+force L<Template> to decode all files correctly, so that when you hit
+the finalize_encoding step we can properly encode the body as UTF8.  If you
+fail to do this you will get double encoding issues in your output (but again,
+only for the UTF8 literals in your actual template text.)
+
+Again, this ENCODING configuration setting only instructs template toolkit
+how (and if) to decode the contents of your template files when reading them from
+disk.  It has no other effect.
+
 =head2 RENDERING VIEWS
 
 The view plugin renders the template specified in the C<template>
@@ -600,6 +657,18 @@ Then in the template:
 
   [% uri_for_css('home.css') %]
 
+=head2 content_type
+
+This lets you override the default content type for the response.  If you do
+not set this and if you do not set the content type in your controllers, the
+default is C<text/html; charset=utf-8>.
+
+Use this if you are creating alternative view responses, such as text or JSON
+and want a global setting.
+
+Any content type set in your controllers before calling this view are respected
+and have priority.
+
 =head2 C<CATALYST_VAR>
 
 Allows you to change the name of the Catalyst context object. If set, it will also
@@ -631,7 +700,7 @@ output from your templates, such as:
 
 =head2 C<TEMPLATE_EXTENSION>
 
-a sufix to add when looking for templates bases on the C<match> method in L<Catalyst::Request>.
+a suffix to add when looking for templates bases on the C<match> method in L<Catalyst::Request>.
 
 For example:
 
@@ -645,7 +714,7 @@ Would by default look for a template in <root>/test/test. If you set TEMPLATE_EX
 
 Allows you to specify the template providers that TT will use.
 
-    MyApp->config({
+    MyApp->config(
         name     => 'MyApp',
         root     => MyApp->path_to('root'),
         'View::Web' => {
@@ -662,7 +731,7 @@ Allows you to specify the template providers that TT will use.
                 }
             ]
         },
-    });
+    );
 
 The 'name' key should correspond to the class name of the provider you
 want to use.  The _file_ name is a special case that represents the default
@@ -686,6 +755,25 @@ 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 Moose;
+    extends '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