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

All my scripts are CGI and as I like to give out my scripts as open source to visitors, I'd like a way to make it easier for them to change the layout of everything. Uptil this point, I included some print <<"HTML" and told them to add their HTML there but there are scripts out there that have prebuilt HTML templates for them.

How do you go about building these? Do you open these other pages with open(PAGE, "") and just include the source that way inside the script? The basic idea I don't understand is how you get variables from the template.html file into the script.

Any tips on going about this would be very much appreciated, thanks everyone.



"Age is nothing more than an inaccurate number bestowed upon us at birth as just another means for others to judge and classify us"

sulfericacid

Replies are listed 'Best First'.
Re: Page Templates
by waswas-fng (Curate) on Feb 11, 2004 at 05:51 UTC
Re: Page Templates
by jeffa (Bishop) on Feb 11, 2004 at 16:53 UTC

    There was a recent question at the Template Toolkit mailing list regarding handing Templates over to vistitors. merlyn pointed out a very scary security hole that bites even when you turn off most of the dangerous TT features:

    foo.match('$x[system "rm -rf /"]');
    My recommomendation is to instead consider CSS as the solution. This is, however, a hard road to travel -- if you thought designing a Perl script was hard, just wait till you try to design your site for CSS! But, with the help of the CSS Zen Garden, you might be able to allow your visitors to supply a StyleSheet instead. Take a look at the source for the Zen Garden home page ... that's all you need to do: no <table>'s, all <div>'s -- the rest is up to your vistors. ;)

    Oh yeah (shameless plug) ... check out my home node for another example of how CSS allows site users to customize their pages.

    jeffa

    L-LL-L--L-LL-L--L-LL-L--
    -R--R-RR-R--R-RR-R--R-RR
    B--B--B--B--B--B--B--B--
    H---H---H---H---H---H---
    (the triplet paradiddle with high-hat)
    
Re: Page Templates
by dws (Chancellor) on Feb 11, 2004 at 07:18 UTC
Re: Page Templates
by edan (Curate) on Feb 11, 2004 at 10:22 UTC

    Perhaps I missed it, but I don't see that anyone has yet mentioned TT, so I thought I'd point out that it is another popular choice, from what I understand.

    --
    edan (formerly known as 3dan)

Re: Page Templates
by nite_man (Deacon) on Feb 11, 2004 at 08:15 UTC

    I'd suggest you look at Mason and Embperl. Those tools will help you include your Perl code in the HTML page. Of course, there are many other features. But in a few words, Mason is more complicated tool than Embperl.

    I prefer use Mason for huge projects. I'd like Mason philosophy: first you develop some components and then build your pages using them. It's very helpful to reuse those components later.
    Also, Mason is de-facto standard for development web applications in USA.

    Embperl is much easy but it has some disadvantages: very critical of HTML code - endless loops if you forgot type end of table or define name of SELECT tag, for example, etc. But all bugs are fixed quickly.

    In summary, both tools are very useful to build dynamically HTML pages and develop common parts of application which can be reused later.

    -- Michael Stepanov

Re: Page Templates
by brianviehland (Initiate) on Feb 11, 2004 at 08:35 UTC
    Another way to do it would be to have the user supply a fully written html tempate but use special tags in it to place different items. You define those tags in your script
    $item1 = "blah blah blah blah"; $item2 = "<img src=\"http://sitename.com/images/foo.gif\">"; $pagecontents = "Hello world\n"; $pagecontents .= "
    \nHow are you\n
    \n";
    Then when you're ready to display the page results, open the template, read in the contents and replace the tags with the information you want
    $templatefile = "template.html"; open(LOCAL, "<$templatefile") || &error('Cannot Open Template File'); if ($^O eq "dos") { binmode LOCAL; } else { flock(LOCAL, 2); } @template = <LOCAL>; close LOCAL or &error('Cannot Close New File'); foreach $line(@template) { $line =~ s/<insert item1>/$item1/g; $line =~ s/<insert item2>/$item2/g; $line =~ s/<page body>/$pagecontents/g; print "$line"; }
      Please consider using HTML::Template instead of rolling your own solution like you have done. It's tested, it works, it's supported ... it's free. :)

      jeffa

      L-LL-L--L-LL-L--L-LL-L--
      -R--R-RR-R--R-RR-R--R-RR
      B--B--B--B--B--B--B--B--
      H---H---H---H---H---H---
      (the triplet paradiddle with high-hat)