Monday, October 26, 2009

Calling a Perl Script from a web page using JavaScript

Ever wanted to include some dynamic data on your web page, but didn't want to (or restrictions didn't allow you to) code the entire page server-side? There is actually a pretty straightforward way to accomplish this, by making the Perl script return valid JavaScript and then calling the Perl script as if it were JavaScript. Confused? I was too until I developed a working example of how it works.

For this example, I will combine the random quotation Perl script I outlined in a previous post with cowsay, also outlined in a previous post on this blog. The Perl script will call the random quotation script, pipe it through cowsay, then return the output in JavaScript to be executed by the browser.

First, the Perl code; I'll call it "cow_quote.pl":
#!/usr/bin/perl 

use strict;
my $line;

# Get a random quotation from www.quotationspage.com
# using random_quote.pl, then pipe the output through
# the cowsay program, limiting the output to 30 columns
my $cowsay = `perl random_quote.pl | cowsay -W 30`;

# Substitute all occurrences of the backslash ("\")
# with the HTML escape code ("\")
$cowsay =~ s/\\/\/g;

# Substitute all occurrences of the space (" ")
# with the HTML escape code (" ")
$cowsay =~ s/ / /g;

# Split the resulting cowsay text into individual lines
my @cowsay = split(/\n/, $cowsay);

# Declare the Internet Media (MIME) type  - The browser
# REQUIRES this to be declared; without it this example
# WILL NOT WORK!
print "Content-type: text/html\n\n";

# Using CSS, declare a style for our DIV tag, setting the
# font to bold courier, with the size of the font being
# 83% of the normal size.  This will permit us to utilize
# all 30 columns of the cowsay text in the narrow sidebar. 
print "document.write(\"<style>\\n\");\n";
print "document.write(\"  \#cowsay\\n\");\n";
print "document.write(\"  {\\n\");\n";
print "document.write(\"    font-family:courier;\\n\");\n";
print "document.write(\"    font-weight:bold;\\n\");\n";
print "document.write(\"    font-size:83%;\\n\");\n";
print "document.write(\"  }\\n\");\n";
print "document.write(\"</style>\\n\");\n";

# Create the cowsay DIV tag, and output the multiple lines
# of the cowsay text, separating each line with an HTML
# break, then close the DIV tag.
print "document.write(\"<div id=\'cowsay\'>\\n\");\n";
foreach $line (@cowsay)
{
  print "document.write(\"  $line\\n\");\n";
  print "document.write(\"  <br />\\n\");\n";
}
print "document.write(\"</div>\\n\");\n";
As you can see, all the output from the Perl script is in JavaScript, allowing the code to be executed client-side by the browser.

Now all that we need to do is to call the script from the web page, using the following code:
<script type="text/javascript" src="http://yourdomain.com/cgi-bin/cow_quote.pl"> 
</script>
Of course, you would substitute your domain for the one listed above.

This is by no means the limit of what could be done utilizing this method. As long as the output is in JavaScript, the sky is the limit!

The Perl source for cow_quote.pl is available here. In order for function properly, it does require that cowsay and random_quote.pl (and it's dependent Perl modules) be installed on your server.

6 comments:

  1. Hello there I am so delighted I found your blog page, I really found you by mistake, while I was researching for something else,
    Regardless I am here now and would just like to say many thanks for a remarkable post and a all round enjoyable blog.Please do keep up the excellent work.
    industrial training indore

    ReplyDelete
    Replies
    1. Thank you for your kind comments! It has been several years since I posted anything new, but I feel inspired by your positive feedback.

      Delete
  2. I quite like this, handy for printing environment vars in quick web page

    ReplyDelete
    Replies
    1. I am glad you found it useful. :-)

      I really need to start blogging again. As you can see it has been several years, although this blog still gets 20+ hits a day...

      Delete
  3. I am new to this. Maybe I am making a mistake but this is what I did.

    I edited this line of the 'cow_quote.pl' file.
    my $cowsay = `RANDOM TEXT`;

    Now, I created an HTML page, test.html with your content inside the head tag of html. The body tag is empty.

    Both the perl file and the html file are in the same folder. When I run this html page in chrome, nothing shows on the screen and the debug console shows me 'Uncaught SyntaxError: Unexpected token ILLEGAL' on sample.pl line 1.

    Please help.

    ReplyDelete
  4. I think you may be confused by what the line you are editing does.

    The variable $cowsay doesn't contain the string you want cowsay to say. The line you tried to edit has the result of storing the output from executing the cowsay command in the variable $cowsay. If you want the cow to say "RANDOM TEXT", the line should look like this:

    my $cowsay = `/usr/games/cowsay "RANDOM TEXT"`;

    Take note that those are backticks enclosing the command to be executed, NOT apostrophes. Enclosing a command to be executed in backticks stores the output of the executed command into the defined variable.

    Here is a link to an article explaining how backticks are used to execute commands in perl: http://alvinalexander.com/blog/post/perl/use-backtick-operator-access-system-commands

    Also, the JavaScript should go in the body tag, not in the head tag. The perl script actually outputs JavaScript, which is in turn executed client-side by your browser. The JavaScript has to be executed in the body in order to be displayed.

    ReplyDelete

If you happened across my blog and find some of the information contained here useful, you have a question, comment, suggestion or perhaps (gasp!) a correction? Please, take a minute and leave a comment.

>