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

Hi Monks,

I’m writing a web application in Perl. It has a form containing contact information, the code for which is currently laid out something like this:

$form_htm = <<EOF <input value="$in{firstname}" name="firstname"> <input value="$in{surname}" name="surname"> ...etc... EOF
Later on I print $form_htm (amongst other things) to display the webpage.

The above is working for me, and the fields are interpolated as expected.
However, I’d like different organisations who use this application to be able to have a different layout for their fields.  Some fields won’t apply to some organisations, and some organisations will want different sizes (on the webpage) for fields than others.
So, I thought I’d store the HTML for the form in a database (different versions in different records for different organizations).
But because the HTML is not stored in the script, the fields (like $in{firstname}) are not interpolated, so the variable names themselves are ending up on the webpage, (which is not quite the look I’m after).

Any recommendations on how I should get these variables to be evaluated in this context? (First thing that came to mind is eval(), but that seems aimed at evaluating expressions, not variables mixed in with a lot of other text.)
Or can you suggest a better approach which would allow different organisations to have different form layouts?

Edit: I have also posted this question on StackOverflow, but would like to get other opinions.

Thanks.
tel2

Replies are listed 'Best First'.
Re: Interpolation of variables in stored HTML
by NetWallah (Canon) on Nov 03, 2016 at 05:28 UTC
    HTML::Template should do the job.

            ...it is unhealthy to remain near things that are in the process of blowing up.     man page for WARP, by Larry Wall

Re: Interpolation of variables in stored HTML
by kevbot (Vicar) on Nov 03, 2016 at 06:01 UTC
Re: Interpolation of variables in stored HTML (template)
by Anonymous Monk on Nov 03, 2016 at 04:37 UTC
Re: Interpolation of variables in stored HTML
by Your Mother (Archbishop) on Nov 03, 2016 at 14:55 UTC

    Using a template framework is the right answer. Several good ones have been suggested. You should know, your code as it stands is probably insecure. I am guessing from the snippet that you aren't using strict and that you are doing something like this?

    %in = CGI->Vars;

    If so—or if the input is coming from users at any stage without being vetted—a malicious URL can be passed to your form and it could do anything from erase or take over your site to hijack other users' accounts. All user input that is displayed as HTML must be HTML encoded: HTML::Entities. Don't save a security "clean-up" pass for last. Have it in mind always: OWASP. Text::Xslate in particular does HTML encoding by default.

      Thank you My Mother.

      Are you talking about someone putting a malicious URL in the firstname field, for example?
      Are you able to give me an example of a malicious URL which could do such damage, please?
      I'm using placeholders for storing the CGI parms into the database.

      Thanks again.

        Anonymous Monk is right. If a hacker can put anything at all into your webpage they can insert JavaScript, a tag with a style attribute that imports a tracking URL to monitor other users who view the info in the future, or this one if the data goes to the DB: Exploits of a Mom.

        If you don't escape/encode/filter the values you get from database, then the resulting html can be anything, it can be <form action=http... .... javascript ... so submit doesn't post the data you want, to the url you want .... whos writing the page, the author/programmer or internet stranger?

        Also no ReadParse no CGI->Vars they corrupt data

Re: Interpolation of variables in stored HTML
by choroba (Cardinal) on Nov 03, 2016 at 21:58 UTC
    Crossposted to StackOverflow. It's considered polite to inform about crossposting to prevent people not attending both sites wasting their time replying to a question already solved at the other end of the internet.

    ($q=q:Sq=~/;[c](.)(.)/;chr(-||-|5+lengthSq)`"S|oS2"`map{chr |+ord }map{substrSq`S_+|`|}3E|-|`7**2-3:)=~y+S|`+$1,++print+eval$q,q,a,
      Thanks for the tip, choroba.
      I have now added an edit to the end of my original post, to that effect.