1 package Catalyst::View::Email::Template;
8 use Scalar::Util qw( blessed );
10 use Email::MIME::Creator;
12 use base qw|Catalyst::View::Email|;
14 our $VERSION = '0.07';
18 Catalyst::View::Email::Template - Send Templated Email from Catalyst
22 Sends Templated mail, based upon your Default View. Will capture the output
23 of the rendering path, slurps in based on mime-types and assembles a multi-part
24 email and sends it out.
25 It uses Email::MIME to create the mail.
29 View::Email::Template:
30 # Optional prefix to look somewhere under the existing configured
31 # template paths. Default is none.
32 template_prefix: email
33 # Where to look in the stash for the email information.
34 # 'email' is the default, so you don't have to specify it.
36 # Define the defaults for the mail
38 # Defines the default content type (mime type) for every template.
39 content_type: text/html
40 # Defines the default charset for every MIME part with the content
42 # According to RFC2049 such a MIME part without a charset should
43 # be treated as US-ASCII by the mail client.
44 # If the charset is not set it won't be set for all MIME parts
45 # without an overridden one.
47 # Defines the default view which is used to render the templates.
49 # Setup how to send the email
50 # all those options are passed directly to Email::Send
54 Host: smtp.example.com # defaults to localhost
60 Sending email is just setting up your defaults, the stash key and forwarding to the view.
62 $c->stash->{email} = {
63 to => 'jshirley@gmail.com',
64 from => 'no-reply@foobar.com',
65 subject => 'I am a Catalyst generated email',
66 template => 'test.tt',
68 $c->forward('View::Email::Template');
70 Alternatively if you want more control over your templates you can use the following idiom
71 to override the defaults:
75 template => 'email/test.html.tt',
76 content_type => 'text/html',
80 template => 'email/test.plain.mason',
81 content_type => 'text/plain',
87 If it fails $c->error will have the error message.
91 # here the defaults of Catalyst::View::Email are extended by the additional
92 # ones Template.pm needs.
95 template_prefix => '',
99 # This view hitches into your default view and will call the render function
100 # on the templates provided. This means that you have a layer of abstraction
101 # and you aren't required to modify your templates based on your desired engine
102 # (Template Toolkit or Mason, for example). As long as the view adequately
103 # supports ->render, all things are good. Mason, and others, are not good.
106 # The path here is to check configuration for the template root, and then
107 # proceed to call render on the subsequent templates and stuff each one
108 # into an Email::MIME container. The mime-type will be stupidly guessed with
109 # the subdir on the template.
112 # Set it up so if you have multiple parts, they're alternatives.
113 # This is on the top-level message, not the individual parts.
114 #multipart/alternative
117 my ($self, $view) = @_;
119 croak "Email::Template's configured view '$view' isn't an object!"
120 unless (blessed($view));
122 croak "Email::Template's configured view '$view' isn't an Catalyst::View!"
123 unless ($view->isa('Catalyst::View'));
125 croak "Email::Template's configured view '$view' doesn't have a render method!"
126 unless ($view->can('render'));
130 my ($self, $c, $attrs) = @_;
132 my $template_prefix = $self->{template_prefix};
133 my $default_view = $self->{default}->{view};
134 my $default_content_type = $self->{default}->{content_type};
136 my $view = $c->view($attrs->{view} || $default_view);
137 # validate the per template view
138 $self->_validate_view($view);
139 # $c->log->debug("VIEW: $view");
141 # prefix with template_prefix if configured
142 my $template = $template_prefix ne '' ? join('/', $template_prefix, $attrs->{template}) : $attrs->{template};
144 my $content_type = $attrs->{content_type} || $default_content_type;
146 # render the email part
147 my $output = $view->render( $c, $template, {
148 content_type => "$content_type",
149 stash_key => $self->stash_key,
154 croak $output->can('as_string') ? $output->as_string : $output;
157 return Email::MIME->create(
159 content_type => "$content_type",
166 my ( $self, $c ) = @_;
168 # validate here so _generate_part doesn't have to do it for every part
169 my $stash_key = $self->{stash_key};
170 croak "Email::Template's stash_key isn't defined!"
171 if ($stash_key eq '');
173 # don't validate template_prefix
175 # the default view is validated on use later anyways...
176 # but just to be sure even if not used
177 # $self->_validate_view($c->view($self->{default}->{view}));
179 # $c->log->debug("SELF: $self");
180 # $c->log->debug('DEFAULT VIEW: ' . $self->{default}->{view});
182 # the content type should be validated by Email::MIME::Creator
184 croak "No template specified for rendering"
185 unless $c->stash->{$stash_key}->{template}
186 or $c->stash->{$stash_key}->{templates};
188 # this array holds the Email::MIME objects
189 # in case of the simple api only one
192 # now find out if the single or multipart api was used
193 # prefer the multipart one
196 if ($c->stash->{$stash_key}->{templates}
197 && ref $c->stash->{$stash_key}->{templates} eq 'ARRAY'
198 && ref $c->stash->{$stash_key}->{templates}[0] eq 'HASH') {
199 # loop through all parts of the mail
200 foreach my $part (@{$c->stash->{$stash_key}->{templates}}) {
201 push @parts, $self->_generate_part($c, {
202 view => $part->{view},
203 template => $part->{template},
204 content_type => $part->{content_type},
209 elsif($c->stash->{$stash_key}->{template}) {
210 push @parts, $self->_generate_part($c, {
211 template => $c->stash->{$stash_key}->{template},
215 delete $c->stash->{$stash_key}->{body};
216 $c->stash->{$stash_key}->{parts} ||= [];
217 push @{$c->stash->{$stash_key}->{parts}}, @parts;
219 # Let C::V::Email do the actual sending. We just assemble the tasty bits.
220 return $self->next::method($c);
227 There needs to be a method to support attachments. What I am thinking is
228 something along these lines:
231 # Set the body to a file handle object, specify content_type and
232 # the file name. (name is what it is sent at, not the file)
233 { body => $fh, name => "foo.pdf", content_type => "application/pdf" },
234 # Or, specify a filename that is added, and hey, encoding!
235 { filename => "foo.gif", name => "foo.gif", content_type => "application/pdf", encoding => "quoted-printable" },
236 # Or, just a path to a file, and do some guesswork for the content type
237 "/path/to/somefile.pdf",
242 =head2 L<Catalyst::View::Email> - Send plain boring emails with Catalyst
244 =head2 L<Catalyst::Manual> - The Catalyst Manual
246 =head2 L<Catalyst::Manual::Cookbook> - The Catalyst Cookbook
250 J. Shirley <jshirley@gmail.com>
252 Simon Elliott <cpan@browsing.co.uk>
254 Alexander Hartmaier <alex_hartmaier@hotmail.com>
258 This library is free software, you can redistribute it and/or modify it under
259 the same terms as Perl itself.