Site Moved

This site has been moved to a new location - Bin-Blog. All new post will appear at the new location.

Bin-Blog

Inline Perl code in HTML

I would always recommend PHP over Perl when it comes to web development. PHP was created with just one purpose - Web Development. Perl, on the other hand, can be used in many different ways - one of which is web development. I began using Perl much before I began using PHP. I have been using PHP for just over a year but I have been using perl for at least 3 years now. I have even written a tutorial on CGI using the Perl language.

One of the main advantage of using PHP is that you can embed PHP code inside HTML files - just give it the extension '.php' and the server will parse it and serve the resulting page. In Perl, you will have to embed HTML code in perl's print statements - this is a much tougher approach.

Solution

There are some programs like BML which will let you embed Perl script into HTML files - LiveJournal uses this approach. But the trouble with this approach is that you will have to have access to the server's 'httpd.conf' file. You will have to configure the server to parse all the files with the '.bml' extension with a script provided by you.

I tried to solve this problem a few months ago - I made a small script called H2P that will parse all file with the extension '.perl'. This don't need any server side configuration so the installation process was much simpler. The only necessary thing was '.htaccess' and the 'mod_rewrite' Apache module. Unfortunately, this project failed and failed miserably. And since I had the PHP option to fall back on, I did not go to great lengths to try to fix it.

Even thought that project was a failure, I created this little gem. This function will let you execute a small bit of Perl code embedded inside a HTML file like this...


<p>This is just html code. <?perl print "This is Perl code."; ?>
Html code once again.</p>

The final output will be like this.


<p>This is just html code. This is Perl code.
Html code once again.</p>

Code


sub showFile {
 my $file = shift; #The first argument is the file name.
 open(IN,$file) or die "Can't read display page '$file' : $!";
 my @lines = <IN>;
 close IN;

 my $count = 0;
 
 for(my $i=0; $i<scalar(@lines); $i++) {
  my $line = $lines[$i];
  
  if($line =~ /<\?perl/i) {
   #If there is a perl code embedded in this, get the code to the finishing point
   my $code = "";
   my $j;
   for($j=$i; $j<scalar(@lines); $j++) {
    my $this_line = $lines[$j];
    $code .= $this_line;
    last if($this_line =~ /\?>/);
   }
   if($code =~ /(.*)<\?perl(.+?)\?>(.*)/is) { #Take out the code.
    my $text_before_code = $1;
    $code = $2;
    my $text_after_code = $3;
    
    print $text_before_code;
    
    #Execute the code.
    eval $code;
    die $@ if $@; #Die if there was an error.
 
    print $text_after_code;
   }
   $i = $j;
 
  } else {
   print $line;
  }
 }
}

#Print the contents of a file after parsing it.
showFile('file.html');

Problems

No Automatic Parsing
Does not parse the files with a specific extension - you will have to call the file via the 'showFile(file_name)' function.
Local scope
The code within the <?perl ... ?> is 'eval'ed. So all the variables that was created in that block exists only within that block. If you have used the 'use strict;' option(and you must), this will limit you very much. If you mush use a variable from another block, you will have to make it a global variable using 'use vars qw($variable_name);'. Still, better than nothing.

Filed Under...

4 Comments:

Randal L. Schwartz said...

Hmm. Reinventing Mason, which has a huge community and deployment. If you're gonna do Perl-in-HTML, might as well do Mason.

Anonymous said...

That's a pretty neat approach. What if we try to use a variable from the main file like $cgi for example?

Binny V A said...

@Randal
Mason is a better way to solve this problem, but it has the same problem as BML does - you have to have access to the server's configuration files. One must change the server configuration to get it working. In the case of my function no such change is necessary. So for a smaller site, my method is better. But for larger sites with dedicated servers, Mason may be a better approach.

@Brian
Try this...
#-----------------------
use vars qw($cgi $sql $session $cookie);

# ... whatever ...

showFile("login_form.html");
#-----------------------
Now you will have the variables $cgi, $sql, $session and $cookie in the login_form.html
and you can use it like this...

#---------- login_form.html -------------------

The value of 'action' is param('action'); ?>

#----------------------------------------------

chorny said...

Why mix Perl and HTML? Even PHP programmers now separate desigh and program. When I was writing program in PHP, I wrote simple template engine to handle this.