More pod fixes, switching view names to the standard 'TT'
[catagits/Catalyst-View-Email.git] / lib / Catalyst / View / Email / Template.pm
CommitLineData
529915ab 1package Catalyst::View::Email::Template;
2
3use warnings;
4use strict;
5
6use Class::C3;
7use Carp;
8
9use Email::MIME::Creator;
10
11use base qw|Catalyst::View::Email|;
12
4bf6fed1 13our $VERSION = '0.08';
8b10ee55 14
15__PACKAGE__->mk_accessors( qw(default_view template_prefix) );
529915ab 16
17=head1 NAME
18
19Catalyst::View::Email::Template - Send Templated Email from Catalyst
20
21=head1 SYNOPSIS
22
23Sends Templated mail, based upon your Default View. Will capture the output
24of the rendering path, slurps in based on mime-types and assembles a multi-part
25email and sends it out.
26
27=head2 CONFIGURATION
28
29 View::Email::Template:
30 # Set it up so if you have multiple parts, they're alternatives.
31 # This is on the top-level message, not the individual parts.
32 content_type: multipart/alternative
33 # Optional prefix to look somewhere under the existing configured
34 # template paths.
35 template_prefix: email
36 # Where to look in the stash for the email information
37 stash_key: email
38 # Setup how to send the email
39 sender:
40 method: SMTP
41 host: smtp.myhost.com
42 username: username
43 password: password
44
45=head1 SENDING EMAIL
46
47Sending email is just setting up your stash key, and forwarding to the view.
48
49 $c->stash->{email} = {
50 to => 'jshirley@gmail.com',
51 from => 'no-reply@foobar.com',
52 subject => 'I am a Catalyst generated email',
53 # Specify which templates to include
54 templates => [
55 qw{text_plain/test.tt},
56 qw{text_html/test.tt}
57 ]
58 };
59 $c->forward('View::Email::Template');
60
12c85b56 61Alternatively if you want more control over your templates you can use the following idiom :-
62
63 templates => [
2d59d970 64 { view => 'TT',
12c85b56 65 template => 'email/test.html.tt',
66 content_type => 'text/html'
67 },
2d59d970 68 { view => 'TT',
12c85b56 69 template => 'email/test.plain.tt',
70 content_type => 'text/plain'
71 }
72
73 ]
74
75
529915ab 76If it fails $c->error will have the error message.
77
78=cut
79
80__PACKAGE__->config(
81 template_prefix => '',
82);
83
84
85# This view hitches into your default view and will call the render function
86# on the templates provided. This means that you have a layer of abstraction
87# and you aren't required to modify your templates based on your desired engine
88# (Template Toolkit or Mason, for example). As long as the view adequately
89# supports ->render, all things are good. Mason, and others, are not good.
90
91#
92# The path here is to check configuration for the template root, and then
93# proceed to call render on the subsequent templates and stuff each one
94# into an Email::MIME container. The mime-type will be stupidly guessed with
95# the subdir on the template.
96#
97# TODO: Make this unretarded.
98#
99sub process {
100 my ( $self, $c ) = @_;
101
8b10ee55 102 my $stash_key = $self->stash_key || 'email';
529915ab 103
104 croak "No template specified for rendering"
105 unless $c->stash->{$stash_key}->{template} or
106 $c->stash->{$stash_key}->{templates};
529915ab 107 # Where to look
8b10ee55 108 my $template_prefix = $self->template_prefix;
529915ab 109 my @templates = ();
12c85b56 110
111 if ( $c->stash->{$stash_key}->{templates} && !ref $c->stash->{$stash_key}->{templates}[0]) {
529915ab 112 push @templates, map {
113 join('/', $template_prefix, $_);
114 } @{$c->stash->{$stash_key}->{templates}};
115
12c85b56 116 } elsif($c->stash->{$stash_key}->{template}) {
529915ab 117 push @templates, join('/', $template_prefix,
118 $c->stash->{$stash_key}->{template});
119 }
120
8b10ee55 121 my $default_view = $c->view( $self->default_view );
529915ab 122
123 unless ( $default_view->can('render') ) {
124 croak "Email::Template's configured view does not have a render method!";
125 }
126
127 #$c->log->_dump($default_view->config);
128
129 my @parts = ();
130 foreach my $template ( @templates ) {
131 $template =~ s#^/+##; # Make sure that we don't have an absolute path.
132 # This seems really stupid to me... argh. will give me nightmares!
133 my $template_path = $template;
134 $template_path =~ s#^$template_prefix/##;
135 my ( $content_type, $extra ) = split('/', $template_path);
136 if ( $extra ) {
137 $content_type ||= 'text/plain';
138 $content_type =~ s#_#/#;
139 } else {
140 $content_type = 'text/plain';
141 }
8b10ee55 142
143 my $output = $default_view->render( $c, $template, {
144 content_type => $content_type,
145 stash_key => $self->stash_key,
146 %{$c->stash},
147 });
148
529915ab 149 # Got a ref, not a scalar. An error!
150 if ( ref $output ) {
151 croak $output->can("as_string") ? $output->as_string : $output;
152 }
153 push @parts, Email::MIME->create(
154 attributes => {
155 content_type => $content_type
156 },
157 body => $output
158 );
159 }
12c85b56 160
161 #add user parts :-
162 if ( $c->stash->{$stash_key}->{'templates'} && ref $c->stash->{$stash_key}->{templates}[0] ) {
163 foreach my $part (@{$c->stash->{$stash_key}->{'templates'}}) {
164 my $view = $c->view($part->{'view'} || $self->config->{default_view});
165
166 my $content_type = $part->{'content_type'} || 'text/plain';
167 unless ( $view->can('render') ) {
168 croak "Part does not have valid render view";
169 }
170
171 my $output = $view->render( $c, $part->{'template'}, {
172 'content_type' => $content_type,
173 %{$c->stash} });
174
175 if ( ref $output ) {
176 croak $output->can("as_string") ? $output->as_string : $output;
177 }
178
179 push @parts, Email::MIME->create(
180 attributes => {
181 content_type => $content_type
182 },
183 body => $output
184 );
185 }
186 }
187
8b10ee55 188 delete $c->stash->{$stash_key}->{body};
189 $c->stash->{$stash_key}->{parts} ||= [];
190 push @{$c->stash->{$stash_key}->{parts}}, @parts;
529915ab 191
192 # Let C::V::Email do the actual sending. We just assemble the tasty bits.
193 return $self->next::method($c);
194}
195
196=head1 TODO
197
198=head2 ATTACHMENTS
199
200There needs to be a method to support attachments. What I am thinking is
201something along these lines:
25650747 202
529915ab 203 attachments => [
204 # Set the body to a file handle object, specify content_type and
205 # the file name. (name is what it is sent at, not the file)
206 { body => $fh, name => "foo.pdf", content_type => "application/pdf" },
207 # Or, specify a filename that is added, and hey, encoding!
208 { filename => "foo.gif", name => "foo.gif", content_type => "application/pdf", encoding => "quoted-printable" },
209 # Or, just a path to a file, and do some guesswork for the content type
210 "/path/to/somefile.pdf",
211 ]
212
213=head1 SEE ALSO
214
215=head2 L<Catalyst::View::Email> - Send plain boring emails with Catalyst
216
217=head2 L<Catalyst::Manual> - The Catalyst Manual
218
219=head2 L<Catalyst::Manual::Cookbook> - The Catalyst Cookbook
220
221=head1 AUTHORS
222
223J. Shirley <jshirley@gmail.com>
224
12c85b56 225Simon Elliott <cpan@browsing.co.uk>
226
529915ab 227=head1 LICENSE
228
229This library is free software, you can redistribute it and/or modify it under
230the same terms as Perl itself.
231
232=cut
233
2341;
235