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

Hi Monks!

My program sends HTML email no problem, but now I need to include a little logic inside of the "Data => qq| |,", I am using MIME::Lite, it works, but I need help on how to use this logic inside the "Data=> " part, please take a look at the code I included here, right where I commented its where I need to include the logic to make this work:

my $msg = MIME::Lite->new( From => 'Report', To => $emails, Subject => "Num: 1", Type => 'multipart/related') or die "Error Creating Message +: $!\n"; $msg->attach( Type => 'text/html', Data => qq| <table width="760" border="1" cellspacing="0" cellpadding="0" bgcolor= +"#ffffff"> <tr> <td width="760"colspan="2" height="35" bgcolor="#ffc6a5"><b>Report + Received:</b></td> </tr> <tr><td colspan=2>&nbsp;</td></tr> <tr> <td width="100" height="">Name:</td> <td width="">$name</td> </tr> <tr> <td width="100" height="">Email:</td> <td width="">$email</td> </tr> <tr> <td colspan=\"2\" width="100%"> <table width="760" border="1" cellspacing="0" cellpadding="0" bgco +lor="#ffffff"> <tr> <td width="760"colspan="7" height="35" bgcolor="#ffc6a5"><b> +Form:</b></td> </tr> <tr><td colspan="6">&nbsp;</td></tr> <tr> <td>NAME:</td> <td colspan="6">$user</td> </tr> <tr><td colspan="6">&nbsp;</td></tr> <tr> <td width="" height="">Number:</td> <td width="" height="">Menu:</td> <td width="" height="">Description:</td> <td width="" height="">ID1:</td> <td width="" height="">ID2:</td> <td width="" height="">Deliver:</td> </tr> # I must have this logic here to have this working $alt_color=0; $c=-1; foreach (@system_names){ $c++; $color1="#f3f3f3"; $color2="#a1a1a1"; $rowcolor = $alt_color++%2 ? $color1:$color2; my $out = " <tr bgcolor=\"$rowcolor\"> <td width=\"\">$system_names[$c]</td> <td width=\"\">$name_names[$c]</td> <td width=\"\">$menu_names[$c]</td> <td width=\"\">$option_names[$c]</td> <td width=\"\">$system_names[$c]</td> <td width=\"\">Received</td> </tr> "; } # end logic </table> </td> </tr> <tr><td colspan=2>&nbsp;</td></tr> <tr> <td colspan="2" height="30" bgcolor="#46575f" align="left" valign= +"middle"> <font size="2" color="#ffffff"><b>Note: Do not reply.</b></font>&n +bsp; </td> </tr> </table> |, ); # Attach GIF image $msg->attach( Type => 'image/gif', Id => 'logo_black', Encoding => 'base64', Path => 'images/logo.gif'); $msg->send();

Thanks you for the Help!!!

Replies are listed 'Best First'.
Re: HTML Email Help!
by samtregar (Abbot) on Jan 12, 2009 at 19:46 UTC
    Looks to me like you're pretty close to getting it. You can finish by moving that block of "logic" (programmers usually call it code) up above the call to MIME::Lite->new(). Now where you want the output from this block to go, put a variable like $data_table. Then all you need to do is figure out how to accumulate rows into $data_table and you're done. Give it a try and post again if you run into problems.

    Once you have it working, you might consider taking the next step and putting all that gnarly HTML into a template, perhaps using HTML::Template. Then you can separate the Perl code in your program from the HTML presentation in the email and when the graphic designer complains that you didn't get the font spacing just right you can tell them to fix it themselves!

    -sam

    A reply falls below the community's threshold of quality. You may see it by logging in.
Re: HTML Email Help!
by AnomalousMonk (Archbishop) on Jan 12, 2009 at 20:15 UTC
    I think my approach would be to generate the embedded text separately and interpolate, e.g. (untested):
    my $text_to_interpolate = ''; for my $i (0 .. $#system_names) { my ($color_0, $color_1) = ('#a1a1a1', '#f3f3f3'); $rowcolor = $i % 2 ? $color_1 : $color_0; $text_to_interpolate .= qq{ <tr bgcolor="$rowcolor"> <td width=""> $system_names[$i] </td> <td width=""> $name_names [$i] </td> <td width=""> $menu_names [$i] </td> <td width=""> $option_names[$i] </td> <td width=""> $system_names[$i] </td> <td width=""> Received </td> </tr> }; } ... Data => qq| <table width ...> $text_to_interpolate ... |, ...
    If it is necessary to interpolate directly into a double-quoted string, use this:
    my $string = "before @{[ code() . "stuff" ]} after";
    Note the "string @{[ code ]} string" idiom.
Re: HTML Email Help!
by Jenda (Abbot) on Jan 13, 2009 at 13:37 UTC
    $color1="#f3f3f3"; $color2="#a1a1a1"; $rowcolor = $alt_color++%2 ? $color1:$color2;

    Let me show you a dirty trick:

    { my $num = 0; use Interpolation 'rowcolor:->$' => sub { (++$color % 2) ? '#a1a1a1' +: '#f3f3f3'} };
    and now we have a variable that alternates between those two values. Neat isn't it? The Interpolation.pm was made to let you specify some code that gets evaluated when a variable (scalar or hash) is interpolated into a string, though of course it works even if you use the variable outside any string.

    my $out = " <tr bgcolor=\"$rowcolor\"> <td width=\"\">$system_names[$c]</td> <td width=\"\">$name_names[$c]</td> <td width=\"\">$menu_names[$c]</td> <td width=\"\">$option_names[$c]</td> <td width=\"\">$system_names[$c]</td> <td width=\"\">Received</td> </tr> ";

    This looks like a bad datastructure design. Imagine you need to pass all those arrays somewhere. Imagine you need to insert another item somewhere in the middle. And imagine you add yet another one later!

    You should use an array of hashes instead so that all this can be referenced and passed as a single datastructure:

    my $out = qq{ <tr bgcolor="$rowcolor"> <td width="">$names[$c]{system}</td> <td width="">$names[$c]{name}</td> <td width="">$names[$c]{menu}</td> <td width="">$names[$c]{option}</td> <td width="">$names[$c]{system}</td> <td width="">Received</td> </tr> };