[Catalyst-commits] r8763 - trunk/examples/CatalystAdvent/root/2008/pen

zamolxes at dev.catalyst.perl.org zamolxes at dev.catalyst.perl.org
Sat Dec 6 15:47:02 GMT 2008


Author: zamolxes
Date: 2008-12-06 15:47:02 +0000 (Sat, 06 Dec 2008)
New Revision: 8763

Added:
   trunk/examples/CatalystAdvent/root/2008/pen/6.pod
Log:
c::v::email article


Added: trunk/examples/CatalystAdvent/root/2008/pen/6.pod
===================================================================
--- trunk/examples/CatalystAdvent/root/2008/pen/6.pod	                        (rev 0)
+++ trunk/examples/CatalystAdvent/root/2008/pen/6.pod	2008-12-06 15:47:02 UTC (rev 8763)
@@ -0,0 +1,177 @@
+=head1 Getting the word out with Catalyst::View::Email
+
+I don't think you'll find many web applications that B<don't> need to
+send emails. You know the common patterns: confirmation emails, password
+recovery emails, monthly newsletter, here's your order, invoice
+attached. The works. 
+
+L<Catalyst::View::Email> is the pretty much standard way to send email
+from Catalyst apps. So you can start removing that nasty email sending
+code from your controllers now ;)
+
+=head2 Getting started
+
+Well, first things first, install L<Catalyst::View::Email> from CPAN. 
+
+Now let's start building our app. Not being very original , I decided to
+go with a Christmas theme: this will allow people to let their would-be
+Santa know what they want for Christmas. So we'll need the user's email and
+name, Santa's email and a description for the gift. Wrap all this in an
+email and deliver to Santa :)
+
+Obviously I'll just focus on the email part, so I'll leave important stuff
+like input validation or DOS protection (you don't want some kiddie sending 
+gazillions of emails through your app) as an exercise to the reader :)
+
+
+Here goes:
+
+ catalyst.pl SantaLetter
+ cd SantaLetter
+ script/santaletter_create view TT TT
+
+Add a wrapper option in your TT.pm 
+
+ __PACKAGE__->config(WRAPPER => 'wrapper.tt');
+
+and create root/wrapper.tt
+
+ <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+ <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+ <head>
+        <meta http-equiv="content-type" content="text/html;charset=iso-8859-1" />
+        <title>Instant Santa lettery delivery service</title>
+        <style type="text/css"> label,textarea { display: block }
+ </style>
+ </head>
+ <body>
+ [% content %]
+ </body>
+ </html>
+
+Now create a simple form in root/index.tt:
+ 
+ <h1>Let Santa know what you want :)</h1>
+ <form method="post" action="[% c.uri_for('/') %]">
+     <fieldset><legend>Tell me everything</legend>
+         <label>Your email:<input type="text" name="email"/></label>
+         <label>Your name:<input type="text" name="name"/></label>
+         <label>Your Santa's email:<input type="text" name="santa"/></label>
+         <label>Your wish:<textarea name="gift" rows="5" cols="40"></textarea></label>
+         <input type="submit" name="submit" value="Go!"/>
+     </fieldset>
+ </form>
+
+Remove the welcome message line in the index action from Root.pm and you 
+can admire the form at L<http://localhost:3000>
+
+=head2 Let's send some emails
+
+Create the view:
+
+ script/santaletter_create.pl view Email Email
+
+If you have an exotic setup, you can tweak the config options. By 
+default it will use the local mail setup, you may want to use an
+external SMTP server for instance.
+
+Don't forget to set TT as default view in santaletter.conf:
+
+ default_view TT
+
+Everything is set up, so let's write the controller code, in Root.pm:
+
+ sub index :Path :Args(0) {
+     my ( $self, $c ) = @_;
+ 
+     return unless $c->req->method eq 'POST';
+     # TODO input validation
+ 
+     $c->stash->{email} = {
+         to => $c->req->param('santa'),
+         from  => $c->req->param('email'),
+         subject => sprintf( "Letter for santa from %s",  $c->req->param('name')),
+         body => sprintf( "Hey Santa,\n\nYou should grant this Christmas wish for %s:\n\n%s\n-- \nMerry X-mas,\nSanta's helpers",
+                     $c->req->param('name'),$c->req->param('gift'))
+     };
+     $c->forward( $c->view('Email') );
+     $c->res->redirect($c->req->uri_with({success=>1}));
+ 
+ }
+
+After the POST is handled, we redirect back, but it would be useful to 
+show some feedback. Add this in index.tt:
+
+ [% IF c.req.param('success') %] <p>Your wish is on its way to Santa!</p> [% END %]
+
+
+=head2 Using an email template
+
+So now you know how to quickly send emails from Catalyst. But stuffing
+that message buddy in a string is rather dirty. This is where 
+L<Catalyst::View::Email::Template> comes handy. It will use your default
+view to render a template, assemble a multi-part email using 
+L<Email::MIME::Creator> and send it out.
+
+So let's give it a spin:
+ 
+ script/santaletter_create.pl view Email::Template Email::Template
+
+We'll create a second TT view, without a wrapper:
+ 
+ script/santaletter_create.pl view TT::NoWrap TT
+
+And tell Email::Template to use it by adding this in its config:
+
+ default => { view => 'TT::NoWrap' }
+
+The new controller code is:
+
+ sub index :Path :Args(0) {
+     my ( $self, $c ) = @_;
+ 
+     return unless $c->req->method eq 'POST';
+     # TODO input validation
+ 
+     $c->stash->{email} = {
+         to => $c->req->param('santa'),
+         from  => $c->req->param('email'),
+         subject => sprintf( "Letter for santa from %s",  $c->req->param('name')),
+         content_type => 'multipart/alternative',
+         template=> 'email.tt'
+     };
+     $c->forward( $c->view('Email::Template') );
+     $c->res->redirect($c->req->uri_with({success=>1}));
+ 
+ }
+
+
+And here's the email template in root/email.tt :
+ 
+ Hey Santa,
+ 
+ You should grant this Christmas wish for [% c.req.params.name %]:
+ 
+ [% c.req.params.gift %]
+ 
+ --
+ Merry X-mas,
+ Santa's helpers
+
+Now you can change your email templates without touching the controller code. Cool!
+
+=head2 What now?
+
+You probably want more features, like sending HTML email or attaching files.
+L<Catalyst::View::Email> handles these things as well, instead of directly setting
+the email body, you can pass an arrayref with Email::Mime parts , and there's
+a nice example in the documentation. 
+
+So go read the docs and learn about the other features, and you can always bug us
+on IRC ( irc.perl.org , #catalyst) if things don't work out. 
+
+=head1 AUTHOR
+
+Bogdan Lucaciu <bogdan at sinapticode.ro>
+Sinapticode




More information about the Catalyst-commits mailing list