The idea is to use perl syntax and the perl parser for the substitution, rather than a made up syntax (e.g. %NAME% and s/%NAME%/$name/). Is this crazy?

Yes, that's crazy, because:

You'll be better off with an approach that generalizes more easily. In what you have so far, the form letter text and the per-recipient data fields come from external sources (a file and a database, respectively) rather than being hard-coded in the script, and that's good.

The next step is to work out a way to externalize the relation between the form and the field data, so that this doesn't depend on how the perl script is written. If the template uses some easily recognized pattern for the field data (like "Dear %NAME%", etc), the perl script can pull these out automatically without needing to worry about how they are spelled; if these names happen to match the column names in the database, things get even easier for the script:

{ # limit the scope of $/ being undef local $/; $block = <FILE> } my %template_flds = ( EMAIL => undef ); # just in case %EMAIL% is not +in the template while ( $block =~ /\%(\w+)\%/g ) { $template_flds{$1} = undef; } my @query_flds = sort keys %template_flds; $sql = "select ".join(',',@query_flds)." from database"; while( $row = getrow( $sql )) { my $mesg = $block; for ( @query_flds ) { $mesg =~ s/\%$_\%/$row->{$_}/g; } print "Sending to $row->{EMAIL}\n"; send_email( $row->{EMAIL}, $mesg ); }
Here, only three dependencies are hard-coded: the name of the database table that holds the field data, the general form of the query string (simple select of columns from a single table with no joins or "where" conditions), and the fact that the database table needs to have a column called EMAIL.

When I wrote my own form-letter app like this, I chose to externalize the query as well. My script used two inputs: the template file, and a tab-delimited flat file (the recipient list) whose first column -- potentially the only column -- was always the email address. If there were more columns in the list, the first row/line in the list had to be a header that assigned a name to each column, and each distinct "%\w+%" string in the template had to exist in the header row, or the script would die with an error message.

Doing it that way means that the query for form data can be arbitrarily complex, so long as it delivers a simple tab-delimited report with one recipient per row; and it's entirely up to the user (not the programmer) to make sure that the template content and per-recipient data are compatible with one another.


In reply to Re: Form letters: eval a string to substutite perl variables by graff
in thread Form letters: eval a string to substutite perl variables by brycen

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.