hmbscully has asked for the wisdom of the Perl Monks concerning the following question:

I'm working on a script to do a very specific thing, take in an online form with a file attachment and then formats it back out as an html email that displays in Lotus notes for printing. Obviously, this is an internal client need. Anyway, I'm using the CGI.pm module and MIME::Lite to send the multipart message. This is my first time using MIME::Lite and I'm having trouble figuring out how to build the html part of the message with variables. The way I've done in the past would be something like:
sub send_email { open (MAIL, "|$mailprog -t") || die "Can't open $mailprog!\n"; print MAIL "Content-type:text/html\n"; print MAIL "From: $from_email\n"; print MAIL "To: $to_email\n"; print MAIL "Subject: $attention Employment Application : $fields{'n +ame'}\n\n"; print MAIL <<to_the_end; <html> <head> <title>Human Resources : Application for Employment</title> <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1 +"> </head> <body bgcolor="#FFFFFF" marginwidth="0" marginheight="0" class="margin +"> <table width="600" border="0"> <tr valign="top"> <td width="300"><font face="Arial, Helvetica, sans-serif" size="-1"><b +>Name:</b>&nbsp;<i>$name</i></font></td> </tr> </table> to_the_end close (MAIL); }
Which worked great and would insert form variable values ($name in this example) into the email body. Now I'm trying to use
sub Email_Results{ my $message = ' <html> <head> <title>Human Resources : Application for Employment</title> <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1 +"> </head> <body bgcolor="#FFFFFF" marginwidth="0" marginheight="0" class="margin +"> <table width="600" border="0"> <tr valign="top"> <td width="300"><font face="Arial, Helvetica, sans-serif" size="-1"><b +>Name:</b>&nbsp;<i>$name</i></font></td> </tr> </table> </body> </html>'; $msg = MIME::Lite->new(From => 'net-admin@someplace.org', To => 'decoraw@someplace.org', Subject => 'Trying to send attachment', Type => 'multipart/mixed'); $msg->attach(Type => 'text/html', Data => $message); $msg->attach(Type => 'application/octet-stream', Path => "$Directory/$File_Name", Filename => $File_Name ); $msg->send(); }
and instead of printing out the value of $name, it just prints $name literally. I've been reading all over the place and everything just points to using the $message variable for the email, but how do I build the $message variable with other variable values? Is there anything similar to the print <<to_the_end; functionality for MIME? TIA

Replies are listed 'Best First'.
Re: MIME::Lite $message construction with variables
by BUU (Prior) on Jun 10, 2004 at 22:09 UTC
    A) Variables in single quotes ('') are not interpolated. Replace with double quotes.

    B) You can use the <<HEREDOC; syntax basically anywhere you want.

    $x .= <<HEREDOC; stuff stuff bar HEREDOC
      Many thanks, that seems to have solved my problem.
      Can you please share an example, i'm facing the same problem

        If you have the same problem, why doesn't the same solution help you?

        my $message = '... some message with $variable ...';

        This will never interpolate $variable. Use double quotes:

        my $message = "... some message with $variable ...";
Re: MIME::Lite $message construction with variables
by Enlil (Parson) on Jun 10, 2004 at 21:59 UTC
    How bout something like this (untested but should work):
    sub Email_Results{ $msg = MIME::Lite->new( From => 'net-admin@someplace.org', To => 'decoraw@someplace.org', Subject => 'Trying to send attachment', Type => 'multipart/mixed'); $msg->attach( Type => 'text/html', Data => << "EOHTML" <html> <head> <title>Human Resources : Application for Employment</title> <meta http-equiv="Content-Type" content="text/html; charset=iso-8859 +-1"> </head> <body bgcolor="#FFFFFF" marginwidth="0" marginheight="0" class="margin +"> <table width="600" border="0"> <tr valign="top"> <td width="300"><font face="Arial, Helvetica, sans-serif" size=" +-1"> <b>Name:</b>&nbsp;<i>$name</i></font> </td> </tr> </table> </body> </html> EOHTML ); $msg->attach( Type => 'application/octet-stream', Path => "$Directory/$File_Name", Filename => $File_Name ); $msg->send(); }
    Granted you could probably use some templating system to create the message for example Template Toolkit as shown in the introduction doc, pass the results to a variable then attach that to Data. Also if you use ' instead of " for quoting text you will not be able to interpolate variables (though with eval you could get back what you wanted as well)

    -enlil

      $msg = MIME::Lite->new( From => 'net-admin@someplace.org', To => 'decoraw@someplace.org', Subject => 'Trying to send attachment', Type => 'multipart/mixed');
      BTW, the "Type" param is not needed in the call to new(). When calling $msg->attach later, the object will automatically set the Type as needed. See the docs for more details.

      And I agree that MIME::Lite is definitely one of the coolest things since sliced bread. Major kudos to the author. I'm using it at work to mail out dynamically generated PDF's, and I think it took me all of 5 minutes after reading the docs to have working code. That's a well designed module. :-)

Re: MIME::Lite $message construction with variables
by hsinclai (Deacon) on Jun 10, 2004 at 21:34 UTC
    Just sidestepping your questions for one second -- I just discovered a great module Mail::SendEasy, that would probably simplify everything you need to do.

    It handles painless multipart message contstuction, html, plaintext, attachments (w/zip compression too), smtp AUTH, and depends only on Archive::Zip to do all that..

    Took about 3 minutes to get it going with all features in use.



      I will look into that, unfortunately, it took nearly 2 months to get my UNIX admin to install the MIME::Lite tools, so if I could make this work with what I have right now, I'd be real excited.
        $name is within ' ' single quotes.. so it will not be expanded..

        You might have to resort to something as neanderthal as:
        $message1 = ' part 1 of html code block '; print $message1; print "$name"; $message2 = ' part 2 of html code block '; print $message2;

        You could also use stuff from the CGI module to construct html, but you might need more specific than it can give you.