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