Perl / cgi / include file a la #include

M

me

I have a perl script generating HTML code. I'd like to include some
existing HTML files (e.g. header.htm, footer.htm) in the output,
while the perl program will generate the majority of the html code.

I know I can do a "require" statement and pull the files in while the
perl program runs. I have a couple questions though:

1. Is it possible to get the web server to parse the perl output and
simply have a standard #include in the generated html that would
include the header and footer just before delivery to the client? Or
will the server always deliver the program output directly with no
further parsing?

2. If it's possible to put the #include in there (item 1 above), is
this a more or less efficient way to deliver the code? In other words,
does it make more sense to have the perl code run once and include all
that's needed, or will the server be more efficient at doing the
include? This specific implementation will be in a shared server
environment, so I don't know that I can count on the included files
being buffered anywhere on the server.

Thanks,
 
C

C.DeRykus

I have a perl script generating HTML code. I'd like to include some
existing HTML files (e.g. header.htm, footer.htm) in the output,
while the perl program will generate the majority of the html code.

I know I can do a "require" statement and pull the files in while the
perl program runs. I have a couple questions though:

1. Is it possible to get the web server to parse the perl output and
simply have a standard #include in the generated html that would
include the header and footer just before delivery to the client? Or
will the server always deliver the program output directly with no
further parsing?

2. If it's possible to put the #include in there (item 1 above), is
this a more or less efficient way to deliver the code? In other words,
does it make more sense to have the perl code run once and include all
that's needed, or will the server be more efficient at doing the
include? This specific implementation will be in a shared server
environment, so I don't know that I can count on the included files
being buffered anywhere on the server.

These are web server rather than Perl issues. If
the server allows server-side includes. SSI's
'include' command is an option. If SSI's aren't
available, you could easily use Perl itself to
read/insert a file: perldoc -q external. Or, to
avoid a separate process, you could DIY with
a short subroutine possibly using File::Slurp.
 
J

Jürgen Exner

me said:
I have a perl script generating HTML code. I'd like to include some
existing HTML files (e.g. header.htm, footer.htm) in the output,
while the perl program will generate the majority of the html code.

A simple File::slurp and print() should do nicely.
I know I can do a "require" statement and pull the files in while the
perl program runs. I have a couple questions though:

Aehmmm, probably not. Or how would perl interpret the require()d
header.htm?
1. Is it possible to get the web server to parse the perl output and
simply have a standard #include in the generated html that would
include the header and footer just before delivery to the client? Or
will the server always deliver the program output directly with no
further parsing?

That really has nothing to with Perl at all. And I can't see what would
be stopping you from calling e.g. 'foobar.pl | cpp' instead of just a
plain 'foobar.pl'
2. If it's possible to put the #include in there (item 1 above), is
this a more or less efficient way to deliver the code? In other words,
does it make more sense to have the perl code run once and include all
that's needed, or will the server be more efficient at doing the
include?

I would guess this very much depends upon what server you are using,
what features it has, and how it is configured. But in general terms
starting additional processes is always expensive, so you want to avoid
doing that as much as possible.

On the other hand, maybe all you are looking for is really a simple
templating system.

jue
 
U

Uri Guttman

JE> I would guess this very much depends upon what server you are using,
JE> what features it has, and how it is configured. But in general terms
JE> starting additional processes is always expensive, so you want to avoid
JE> doing that as much as possible.

JE> On the other hand, maybe all you are looking for is really a simple
JE> templating system.

and since my File::Slurp has been mentioned, i might as well bring up
Template::Simple. as you said, the OP really is asking for a templater
and doesn't know it. that module can do includes, substitutions and more
and is very easy to learn and use. don't generate html directly from
perl as it is noisy and annoying to handle all sorts of things.

uri
 
M

me

A simple File::slurp and print() should do nicely.


Aehmmm, probably not. Or how would perl interpret the require()d
header.htm?

Yes... I discovered a little gotcha in that process. Open / Read works
but I will check out Slurp.
That really has nothing to with Perl at all. And I can't see what would
be stopping you from calling e.g. 'foobar.pl | cpp' instead of just a
plain 'foobar.pl'

I don't think I can do what you are suggesting as a cgi program.
I would guess this very much depends upon what server you are using,
what features it has, and how it is configured. But in general terms
starting additional processes is always expensive, so you want to avoid
doing that as much as possible.

On the other hand, maybe all you are looking for is really a simple
templating system.

Yes... that might work better although "templating" is overkill for
this site as there is only one page that needs to be programmatically
created.
 
M

me

and since my File::Slurp has been mentioned, i might as well bring up
Template::Simple. as you said, the OP really is asking for a templater
and doesn't know it. that module can do includes, substitutions and more
and is very easy to learn and use. don't generate html directly from
perl as it is noisy and annoying to handle all sorts of things.

Thanks, I will look into the Template module.
 
J

Jürgen Exner

me said:
I don't think I can do what you are suggesting as a cgi program.

Again, this has nothing to do with the CGI program.
Somewhere in the web server configuration there must be a description
for what the server is supposed to do when the resource http:/..... is
being requested. If the web server doesn't allow that description to be
a shell command with a pipe, then still you could write a 1/2 line
wrapper script which does nothing but call 'foobar.pl | cpp'.

Now, I am not saying this is a good solution for your original problem,
not at all. But it sure is possible.

jue
 
U

Uri Guttman

m> Yes... that might work better although "templating" is overkill for
m> this site as there is only one page that needs to be programmatically
m> created.

'programmatically created' means template. you can do it by breaking up
the html into parts and build it up in the template. you may still need
code to mung the data with perl to work with the template but it will be
easier than generating the html in perl. there are other advantages to
using a template including allowing a designer to do the html/css and a
coder to work on the perl. rarely can one person be very good at both.

uri
 
C

ccc31807

I have a perl script generating HTML code. I'd like to include some
existing HTML files (e.g. header.htm, footer.htm) in the output,
while the perl program will generate the majority of the html code.

This is a very, very common need.

I create Perl modules which output HTML, and call the functions that
return the HTML in my scripts. Like this:

-----------HTML.pm------------------
package HTML;

....

sub print_header
{
my $title = shift;
print qq(<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<title>$title</title>
<link type="text/css" rel="stylesheet" href="http://site.css" />
</head>
<body>
);
}

....

---------------index.cgi-----------------
use HTML;

....

HTML::print_header($page);

....

exit(0);

CC
 
U

Uri Guttman

c> This is a very, very common need.

c> I create Perl modules which output HTML, and call the functions that
c> return the HTML in my scripts. Like this:

that doesn't return the html, it prints it directly.

c> print qq(<?xml version="1.0" encoding="UTF-8" ?>

c> HTML::print_header($page);

a better style i teach is called "print rarely, print late". instead of
printing directly, return the string you make up. build up the final
page in a buffer (using .= is easiest) and then you can decide what to
do with it. you can print to stdout as usual, print to a file for later
use by the web server, print to a socket if desired. or more than one of
those at the same time. by printing directly from the html subs you lose
the flexibility. it is also a bit faster to call print one time than
multiple times (.= is faster than print). and you can decide where to
print at the higher level which keeps the logic cleaner. i have seen
requests for dual handles which can print to a file and to stdout (i
think IO::Tee does that) but this is even easier and faster. so the rule
print rarely means build up a full string in a buffer before you print
it. print late means print only when you are done and can decide where
to print it.

uri
 
C

ccc31807

a better style i teach is called "print rarely, print late". instead of
printing directly, return the string you make up.

In Paul Graham's book 'On Lisp' in chapter 3, 'Functional
Programming', he makes an extended case for this, which I find
compelling but not necessarily persuasive. I've been slowly making my
way through the dead tree version of HOP by MJD, and I also have found
a lot to like in that. My problems are (as Graham notes) an imperative
habit, a lack of opportunity, and little discretionary time.
build up the final
page in a buffer (using .= is easiest) and then you can decide what to
do with it.

I actually use this quite a bit in my day job. I almost always find
myself constructing and deconstruction strings and arrays (and
hashes), moving between them, and as a result I do this quite a bit.
(I've also found the ||= operator useful.)
you can print to stdout as usual, print to a file for later
use by the web server, print to a socket if desired. or more than one of
those at the same time. by printing directly from the html subs you lose
the flexibility. it is also a bit faster to call print one time than
multiple times (.= is faster than print). and you can decide where to
print at the higher level which keeps the logic cleaner.

As an explanation if not a defense of what I wrote previously, most of
my HTML consists of front ends to databases, and most of the heavy
lifting is the SQL part. When I write my HTML files, I use variables
to trigger both the SQL and the HTML. I quite frequently end up with a
cgi script that looks something like this (illustration only):

HTML::print_header(@vars1);
HTML::print_banner(@vars2);
HTML::print_menu(@vars3);
my $hashref = SQL::get_list($var1);
HTML::print_content($hashref);
$hashref = SQL::get_calendar($var2);
HTML::print_content($hashref);
HTML::print_footer();
exit;
i have seen
requests for dual handles which can print to a file and to stdout (i
think IO::Tee does that) but this is even easier and faster. so the rule
print rarely means build up a full string in a buffer before you print
it. print late means print only when you are done and can decide where
to print it.

In this case, I am 'printing' a response to an HTTP request, not a
physical device. I also do some JSP, and for some reason, the JSP
doesn't seem any faster than my CGI, and sometimes is noticeably
slower.

CC
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,743
Messages
2,569,478
Members
44,899
Latest member
RodneyMcAu

Latest Threads

Top