TUTORIAL: Intro to Embedded Perl Using Mason

  • mk27
  • Proficient
  • Proficient
  • User avatar
  • Posts: 334

Post 3+ Months Ago

Introduction



Mason is a perl module which works with apache's mod_perl to present web pages with embedded perl. It's a nice alternative to php if you know and love perl. To use mason with this tutorial, you need to do three or four things:

  1. install HTML::Mason from CPAN. Be warned, HTML::Mason requires quite a few other modules, so you may want to use CPAN.pm to auto-install.
  2. install mod_perl. How you do this is system dependent, and you do need to be running apache.
  3. read the first two or three chapters of The Mason Book, which is published by O'Reilly but also free on-line and easily downloadable. You could try and do it "concurrently" if you want. They are short chapters and the book is nicely written IMO (much thanks to Dave Rolsky and Ken Williams for making it available!) There are very few mason resources for beginners on the net, which is why I decided to write this tutorial; to that end, I will not re-iterate the basics of mason as described in "the book" but instead present some complementary material. The tutorial presumes you at least understand the component based structure of a mason site, which is detailed in chapter 1 of "the book".
  4. we're also going to use an SQLite3 database, managed via perl's DBI and DBD::SQLite modules, so you need those too.

There is a widely used perl web application framework, Catalyst, akin to Ruby on Rails, Django, or ASP.NET, which uses mason. While the tutorial demo resembles a simple MVC web framework app in so far as it is based around an SQL database, it does not involve Catalyst, and I don't use the MVC vocabulary to describe it. One of the goals of the tutorial is to demonstrate how SQL and AJAX can be used in conjunction with mason; while the examples are quite simple, I do presume some familiarity with both. However, you don't don't have to know anything about MVC or web-app frameworks.

The .htaccess file, and related concerns


The Mason Book includes instructions for how to configure apache properly, either using mod_perl, or with plain cgi. Mod_perl is preferable, and the ideal is to do the configuration in httpd.conf. However, in keeping with my intention to "present alternatives", the demo used in the tutorial instead uses an .htaccess file like this:
Code: [ Select ]
 
PerlRequire /var/www/html/zoodemo/apache-perl.pl
SetHandler perl-script
PerlHandler HTML::Mason::ApacheHandler
AddType text/html mhtml
AddType text/html comp
AddHandler perl-script mhtml comp
<Files *>
Header set Cache-Control: "private, pre-check=0, post-check=0, max-age=0"
Header set Expires: 0
Header set Pragma: no-cache
</Files>
 
  1.  
  2. PerlRequire /var/www/html/zoodemo/apache-perl.pl
  3. SetHandler perl-script
  4. PerlHandler HTML::Mason::ApacheHandler
  5. AddType text/html mhtml
  6. AddType text/html comp
  7. AddHandler perl-script mhtml comp
  8. <Files *>
  9. Header set Cache-Control: "private, pre-check=0, post-check=0, max-age=0"
  10. Header set Expires: 0
  11. Header set Pragma: no-cache
  12. </Files>
  13.  

The "Files" section is just a standard no-cache bit for use in development, so that you can modify the files and not have to deal with apache cached versions. The most important part consists of the PerlHandler, AddType and AddHandler commands. You can call your files whatever you want, but (one) convention is to use the prefixes .mhtml and .comp. There is some further discussion in the Mason FAQ at "Mason HQ".

In addition, mod_perl has to load the required modules; those are listed in apache-perl.pl:
Code: [ Select ]
 
use HTML::Mason::ApacheHandler;
use CGI;
 
1;
 
  1.  
  2. use HTML::Mason::ApacheHandler;
  3. use CGI;
  4.  
  5. 1;
  6.  

You can actually call this file whatever you like as long as it's correctly referenced with PerlRequire in the .htaccess file. Notice the true return ("1;") at the end. This is list of modules for the mason/apache mod_perl process; modules used within actual pages (such as DBI) have to be included in those pages (and nb. -- use "use" and not "require"), and should not be included here.

Site Structure


The tutorial involves a simple site, The Mason Internet Zoo. This site is contained in the following directory structure:

Code: [ Select ]
 
db/
   newDB.pl
   zoodemo.db
js/
   .htaccess
   prototype.js
   site_specific.js
log/
   DBI_trace.log*
   perl.log*
.htaccess
INSTALL
ZooAnimal.pm
ZooDemo.pm
animal.comp
animals.mhtml
apache-perl.pl
cage.comp
cages.mhtml
class.comp
classes.mhtml
create_animal.comp
db_error.mhtml
header.comp
index.html    
new_animal.comp  
style.css
           
*do not exist initially and can be erased later
 
  1.  
  2. db/
  3.    newDB.pl
  4.    zoodemo.db
  5. js/
  6.    .htaccess
  7.    prototype.js
  8.    site_specific.js
  9. log/
  10.    DBI_trace.log*
  11.    perl.log*
  12. .htaccess
  13. INSTALL
  14. ZooAnimal.pm
  15. ZooDemo.pm
  16. animal.comp
  17. animals.mhtml
  18. apache-perl.pl
  19. cage.comp
  20. cages.mhtml
  21. class.comp
  22. classes.mhtml
  23. create_animal.comp
  24. db_error.mhtml
  25. header.comp
  26. index.html    
  27. new_animal.comp  
  28. style.css
  29.            
  30. *do not exist initially and can be erased later
  31.  


You can download the demo as a zip file:
Attachments:
zoodemo.zip

(40.06 KiB) Downloaded 608 times



You will have to search thru this and change references to the path /var/www/html/zoodemo as appropriate, if you cannot use it in that directory...INSTALL contains some brief instructions.

I should soon have an on-line host for The Mason Internet Zoo, but for the time being, if you want to see the demo you will have to install it yourself, which should be fairly easy and might get you familiar with a few basic things.

index.html



That's the first document we see. As long as you have the .htaccess file correct and mod_perl installed, apache will process index.html with mason, so:
Code: [ Select ]
 
<& header.comp, title=>"Zoo Demo", heading=>"Mason Internet Zoo"&>
<ul>
<li><a href="animals.mhtml">Animals</a>
<li><a href="cages.mhtml">Cages</a>
<li><a href="classes.mhtml">Classes</a>
</ul>
</body></html>
 
  1.  
  2. <& header.comp, title=>"Zoo Demo", heading=>"Mason Internet Zoo"&>
  3. <ul>
  4. <li><a href="animals.mhtml">Animals</a>
  5. <li><a href="cages.mhtml">Cages</a>
  6. <li><a href="classes.mhtml">Classes</a>
  7. </ul>
  8. </body></html>
  9.  

The big line here is in red, but since you've read chapter one of "the book" you understand that that means to include another file here, in this case header.comp, and to pass it two variables -- title and heading. So here's header.comp:
Code: [ Select ]
 
<html><head>
<title><% $ARGS{title} |h %></title>
<link rel="stylesheet" type="text/css" href="style.css"></style>
<script type="text/javascript" src="js/site_specific.js"></script>
<script type="text/javascript" src="js/prototype.js"></script>
</head>
 
<body text="#cccccc" bgcolor="#222222">
<div id="utildiv" class="utility"></div>
<h1><% $ARGS{heading} |h %></h1>
 
  1.  
  2. <html><head>
  3. <title><% $ARGS{title} |h %></title>
  4. <link rel="stylesheet" type="text/css" href="style.css"></style>
  5. <script type="text/javascript" src="js/site_specific.js"></script>
  6. <script type="text/javascript" src="js/prototype.js"></script>
  7. </head>
  8.  
  9. <body text="#cccccc" bgcolor="#222222">
  10. <div id="utildiv" class="utility"></div>
  11. <h1><% $ARGS{heading} |h %></h1>
  12.  

header.comp is a sort of pre-wrap I'm using with all the .mhtml pages. Again, if you read chapter 2 of "the book" you will recognize the use of the %ARGS hash which is passed to the component. Notice the "|h"; this is a mason function to qualify html reserved characters that may be present in a variable, since the real value will appear in the actual page source passed to the browser. As is, I have hardcoded control over all the instances at the Zoo for this particular component and don't have to worry about problem characters, but on the premonition that I may soon want to include individual pages for individual animals based on user input, they are included here.

There is a special mason file, the autohandler, which allows you to write a universal wrapper for all mason components, but since some of the Zoo components are actually innerHTML content for use with AJAX (in fact, all of the .comp files except header.comp are such), I do not use an autohandler.

Also included in header.comp are "site_specific.js" and the freely distributable prototype.js. Prototype gives us access to simplified AJAX functions like Ajax.Request. I'm gonna use those mostly with $('utildiv'), created in the other line in red (above). Note css class "utility" is set display: none in style.css, also included in header.comp. Utildiv is a popup we reuse with Ajax.Updater for various things in all the .mhtml pages. For example:
Code: [ Select ]
 
<& header.comp, title=>"Mason Internet Zoo", heading=>"Cages List"&>
 
<%init># cages.mhtml
BEGIN { push @INC,"/var/www/html/zoodemo"; }
use ZooDemo;
$m->interp->set_escape("j"=>\&js_esc);
my $db = db_handle();
my $sql = $db->prepare("select * from cages");
$sql->execute;
</%init>
 
<center>
% while (my @data=$sql->fetchrow_array()) {
        <p class="link" onclick="new Ajax.Updater($('utildiv'),'cage.comp', { method: 'post',
                parameters: { name: '<%$data[1]|j,h%>', id: '<%$data[0]%>' } });
                $('utildiv').style.display='inline';"><%$data[1]|h%> (<%$data[2]%> species)
% }
</center>
</body></html>
 
  1.  
  2. <& header.comp, title=>"Mason Internet Zoo", heading=>"Cages List"&>
  3.  
  4. <%init># cages.mhtml
  5. BEGIN { push @INC,"/var/www/html/zoodemo"; }
  6. use ZooDemo;
  7. $m->interp->set_escape("j"=>\&js_esc);
  8. my $db = db_handle();
  9. my $sql = $db->prepare("select * from cages");
  10. $sql->execute;
  11. </%init>
  12.  
  13. <center>
  14. % while (my @data=$sql->fetchrow_array()) {
  15.         <p class="link" onclick="new Ajax.Updater($('utildiv'),'cage.comp', { method: 'post',
  16.                 parameters: { name: '<%$data[1]|j,h%>', id: '<%$data[0]%>' } });
  17.                 $('utildiv').style.display='inline';"><%$data[1]|h%> (<%$data[2]%> species)
  18. % }
  19. </center>
  20. </body></html>
  21.  


Yes, some obtrusive inline javascript, presented this way in the demo for ease of illustration (since we can see the perl/html context without having to site multiple files). If you prefer, it can easily be hidden away in the site_specific.js file. The actual source here is cages.mhtml, where all the cages at the zoo are listed. By clicking on a cage, you get a pop-up containing a list of the animals in the cage.

Attachments:
forest-ss.jpg


The <%init> block, where-ever located in the page, is perl code executed before anything else is done. In this case, we are making use of ZooDemo.pm, which contains some basic functions, db_handle(), js_esc(), and log_msg().
Code: [ Select ]
 
package ZooDemo;
use strict;
 
use DBI;
use base ("Exporter");
our @EXPORT = qw(db_handle js_esc log_msg);
 
our $path = "/var/www/html/zoodemo";
 
  1.  
  2. package ZooDemo;
  3. use strict;
  4.  
  5. use DBI;
  6. use base ("Exporter");
  7. our @EXPORT = qw(db_handle js_esc log_msg);
  8.  
  9. our $path = "/var/www/html/zoodemo";
  10.  

ZooDemo takes care of loading DBI and connecting to the SQLite DB by providing db_handle() for error handling, et. al (which might also making switching databases, etc, much simpler). js_esc() is a custom handler for escaping single quotes in variables that are passed to javascript functions:
Code: [ Select ]
 
sub js_esc {
        my $ref = shift;
        $$ref =~ s/\*'/\'/g;
}
 
  1.  
  2. sub js_esc {
  3.         my $ref = shift;
  4.         $$ref =~ s/\*'/\'/g;
  5. }
  6.  

This is registered with mason via the $m->interp->set_escape(), highlighted above, and then used like the "|h" function mentioned earlier. Nice! It is important to use the "j" before the "h" flag. Take a close look at some possible "page source" output:
Code: [ Select ]
 
<p class="link" onclick="new Ajax.Updater($('utildiv'),'animal.comp', { method: 'post',
    parameters: 'name=heap\&#39;s moose &data=Rotunda&data=unknown'});
    $('utildiv').style.display='inline';">heap&#39;s moose
 
  1.  
  2. <p class="link" onclick="new Ajax.Updater($('utildiv'),'animal.comp', { method: 'post',
  3.     parameters: 'name=heap\&#39;s moose &data=Rotunda&data=unknown'});
  4.     $('utildiv').style.display='inline';">heap&#39;s moose
  5.  


Since this is embedded in html source, the ' can be rendered ' (by the |h flag) in both places; altho it is not necessary in the js tag since it would be preceeded by a '\' because of the |j flag. However, the variable could still have had unescaped < or > in it also, so we should stay safe and use both the |h and the |j flag with variables for javascipt. When passed to Ajax.Updater, this ends up as "heap\'s moose", fortunately, not "heap\'s moose". The example in purple appears on the page and is not part of any javascript, so it used only the |h flag -- hence no '\' there.

Again, just to be clear: there is no default |j flag, so you can use your own ideas here. There are other characters that can cause a js error, but the single-quote/apostrophe will be the most common one used legitimately, and is also the most dangerous one for malicious purposes. You can override the default |h handler as well, which the FAQ notes:
Quote:
...will not work with non-ISO-8559-1 encodings. If you are using such an encoding and want to switch the 'h' flag to escape just the minimal set of characters (<, >, &, "), put this in your Apache configuration:

PerlSetVar MasonEscapeFlags "h => \&HTML::Mason::Escapes::basic_html_escape"


Database Integration



"cages.mhtml" and "cage.comp" both interact with a database (db/zoodemo.db). I'm using DBI with SQLite3. The database was created and pre-populated with db/newDB.pl, which if you modify the db you can delete it and replace it using that script to restore the original state of the zoo. All the SQL commands that created the tables are in newDB.pl. Because apache must write to zoodemo.db, remember that on a unix style filesytem, the ownership of it *and* the containing directory must be "apache.apache" (or whatever the runtime uid of apache is).

"zoodemo.db" contains three tables (cages, classes, and animals), each using an autoincrementing integer primary key "id" so that we can try and keep the database working by the rules of 3rd normal form (3NF).

A mason component will accept arguments from another mason component, as in the case of index.html & header.comp (<& header.comp, title=>"Zoo Demo", heading=>"Mason Internet Zoo"&>), or as "form" parameters passed via POST. At The Mason Internet Zoo, posting is done with Ajax.Updater (as above). There is a detailed explanation of this (sans AJAX) in chapter 2 of "the book"; in any case, mason and apache do the work, so there is no difference within the component as to how the parameters are passed. Clicking on a cage listed in cages.mhtml will pop-up the utildiv window containing an instance of cage.comp, that is, a per cage specific list of the animals in that particular cage. So this will be the innerHTML for "utildiv" when so invoked:
Code: [ Select ]
 
<%init># cage.comp
#called from cages.mhtml with args "name" "id"
BEGIN { push @INC,"/var/www/html/zoodemo" }
use ZooDemo ("db_handle");
my $db = db_handle();
my $sql = $db->prepare("select * from animals where cage_id=?;");
$sql->execute($ARGS{id});
</%init>
 
<h3><%$ARGS{name}|h%></h3>
<p>Contains:
<ul>
% while (my @data = $sql->fetchrow_array()) {
        <li><%$data[1]|h%>
% }
% $db->disconnect;
</ul>
 
<p class="mini" align="center" onclick="$('utildiv').style.display='none';">[close]
 
  1.  
  2. <%init># cage.comp
  3. #called from cages.mhtml with args "name" "id"
  4. BEGIN { push @INC,"/var/www/html/zoodemo" }
  5. use ZooDemo ("db_handle");
  6. my $db = db_handle();
  7. my $sql = $db->prepare("select * from animals where cage_id=?;");
  8. $sql->execute($ARGS{id});
  9. </%init>
  10.  
  11. <h3><%$ARGS{name}|h%></h3>
  12. <p>Contains:
  13. <ul>
  14. % while (my @data = $sql->fetchrow_array()) {
  15.         <li><%$data[1]|h%>
  16. % }
  17. % $db->disconnect;
  18. </ul>
  19.  
  20. <p class="mini" align="center" onclick="$('utildiv').style.display='none';">[close]
  21.  

There's the $ARGS hash again, with the "|h" flag; note we don't actually need to examine table cages, since we already have the name of the cage. Something to notice here is the use of a placeholder (?) in the SQL select call ("where cage_id=?". This placeholder is filled in the ->execute() with $ARGS{id}. This could have been written:

Code: [ Select ]
 
my $sql = $db->prepare("select * from animals where cage_id='$ARGS{id}'");
$sql->execute();
 
  1.  
  2. my $sql = $db->prepare("select * from animals where cage_id='$ARGS{id}'");
  3. $sql->execute();
  4.  

The point of using a placeholder is to prevent abuse of the single quote (again) in SQL injection attacks on the database.

"classes.mhtml" & "class.comp" work exactly the same way as cages.mhtml & cages.comp do. This snippet also contains the three means of "embedding" the perl within what is ostensibly an html page:
  • Perl-only sections between <%perl></%perl> or <%init></%init> tags (there are others, but those are the two most common).
  • Mixed into html with <%.....%>
  • Alternating with html using % at the beginning of a line.

It might be worth mentioning at this point that the %ARGS hash can be preprocessed, placing the key/value pairs into individual variables (using the key name) for simplification. This is especially handy if you want to pass an array or hash using a reference in the caller. The mechanism for this in the callee is an <%args> block. There is a complete explanation in chapter 2 of "the book"; the Internet Zoo demo contains one example of how to use an <%args> block:
Code: [ Select ]
 
<%args># animal.comp
#called from animals.mhtml with args "name" and "data" (x2)
$name
@data
</%args>
 
<h3><%$name|h%></h3>
<p>Cage: <%$data[0]|h%><br/>Class: <%$data[1]|h%>
 
<p class="mini" align="center" onclick="$('utildiv').style.display='none';">[close]
 
  1.  
  2. <%args># animal.comp
  3. #called from animals.mhtml with args "name" and "data" (x2)
  4. $name
  5. @data
  6. </%args>
  7.  
  8. <h3><%$name|h%></h3>
  9. <p>Cage: <%$data[0]|h%><br/>Class: <%$data[1]|h%>
  10.  
  11. <p class="mini" align="center" onclick="$('utildiv').style.display='none';">[close]
  12.  

Notice the args block is not normative perl code and should not contain any. It might have been simpler here to just use the %ARGS hash again, or to use three scalars. But hey, what's a demo if it doesn't demonstrate? Passing an array from another component is as simple as passing a reference, but using form POST data is slightly more complicated. The explanation from "the book" describes how fields with the same name in a query string will be placed into an array of the same name in the component. However, you cannot pass such a string using the normative js object notation with Ajax.Updater (eg, "parameters: {name: 'bob', id: 666 }"). Instead, you must use string notation like this, which is the actual call used to animal.comp, above, from animals.mhtml, below:
Code: [ Select ]
 
<p class="link" onclick="new Ajax.Updater($('utildiv'),'animal.comp', { method: 'post',
       parameters: 'name=<%$_->{name}|j,h%>&data=<%$_->{cage}|j,h%>&data=<%$_->{class}|j,h%>' });
                $('utildiv').style.display='inline';">
 
  1.  
  2. <p class="link" onclick="new Ajax.Updater($('utildiv'),'animal.comp', { method: 'post',
  3.        parameters: 'name=<%$_->{name}|j,h%>&data=<%$_->{cage}|j,h%>&data=<%$_->{class}|j,h%>' });
  4.                 $('utildiv').style.display='inline';">
  5.  

Witness, "data" is used twice, which is why you can't use the js object notation. You might notice there is some perl->object syntax in there as well. Using objects with mason is slightly limited, because variables including object references do not persist between page calls. However, we do have one example from ZooAnimal.pm, the other module, which is used to contain the perl routines for animals.mhtml and new_animal.comp. Those are discussed in the next section.

Forms


I've included an example form submission so you can add more animals to the zoo. This option appears in the "titlebar" of animals.comp:
Attachments:
animals-ss.jpg

Code: [ Select ]
 
<div class="menu">
<p class="menulink" onclick="new Ajax.Updater($('utildiv'),'create_animal.comp');
        $('utildiv').style.display='inline';">Add New Animal
</div>
 
  1.  
  2. <div class="menu">
  3. <p class="menulink" onclick="new Ajax.Updater($('utildiv'),'create_animal.comp');
  4.         $('utildiv').style.display='inline';">Add New Animal
  5. </div>
  6.  

create_animal.comp is just a normal form with id ="newadmin" and action = "javascript: processform ($('newamin'), 'new_animal.comp')". "processform()" is in site_specific.js:
Code: [ Select ]
 
function processform(form,comp) {
        new Ajax.Updater(document.body, comp, { method: 'post', parameters: form.serialize(true) });
}
 
  1.  
  2. function processform(form,comp) {
  3.         new Ajax.Updater(document.body, comp, { method: 'post', parameters: form.serialize(true) });
  4. }
  5.  

You can see how nicely mason and AJAX work together here, taking care of the form submission and passing the input along to new_animal.comp, which adds to the database and doesn't output any html -- instead, it just includes <& animals.mhtml &> at the end, which should display the updated list. Actually, if the ZooAnimal.pm create() routine throws an SQL or other error, new_animal.comp will respond to that by including something instead of animals.mhtml:
Code: [ Select ]
 
<%init># new_animal.comp
#called from create_animal.comp with args "name" "class" "cage"
BEGIN { push @INC,"/var/www/html/zoodemo"; }
use ZooAnimal ("create");
my $check = create ZooAnimal($ARGS{name},$ARGS{cage},$ARGS{class});
</%init>
% if ($check) {
    <& animals.mhtml &>
% } else {
    <& db_error.mhtml &>
% }
 
  1.  
  2. <%init># new_animal.comp
  3. #called from create_animal.comp with args "name" "class" "cage"
  4. BEGIN { push @INC,"/var/www/html/zoodemo"; }
  5. use ZooAnimal ("create");
  6. my $check = create ZooAnimal($ARGS{name},$ARGS{cage},$ARGS{class});
  7. </%init>
  8. % if ($check) {
  9.     <& animals.mhtml &>
  10. % } else {
  11.     <& db_error.mhtml &>
  12. % }
  13.  

This method of error handling occurs in a few other places as well.

So this is somewhat like a normal CGI routine, only much nicer to work with IMO.

If your animal belongs to a new class, the class is also created.

But couldn't you just do all of this with CGI anyway?


You're welcome to try!

Debugging/Logging


db_handle() in ZooDemo.pm turns on DBI's tracing mechanism when the handle is created:
Code: [ Select ]
 
DBI->trace(1,"$path/log/DBI_trace.log");
 
  1.  
  2. DBI->trace(1,"$path/log/DBI_trace.log");
  3.  

Trace output is quite copious.

Additionally, many perl and SQL errors, as well as anything you print to STDERR, will appear in apache's error.log. log_msg(), from ZooDemo.pm, will print to a file log/perl.log; the only place this is actually used is when you create a new animal. As with the db directory, apache mod_perl writes files to the log directory and so it must be chown'd apache.apache.

Miscellaneous Issues


For one reason or another, css :hover attributes will not work unless you use the entire tag in the definition. So if you are used to using:
Code: [ Select ]
 
.link { color: #fffff; }
.link:hover { background: #ffff00; color: #000088; font-weight: bold;}
 
  1.  
  2. .link { color: #fffff; }
  3. .link:hover { background: #ffff00; color: #000088; font-weight: bold;}
  4.  

And having that effect a variety of tags, there is a slight inconvenience: .link will apply to anything class="link", but link:hover will not. To make it work you need to do this:
Code: [ Select ]
 
.link { color: #fffff; }
p.link:hover { background: #ffff00; color: #000088; font-weight: bold;}
h2.link:hover { background: #ffff00; color: #000088; font-weight: bold;}
[etc]
 
  1.  
  2. .link { color: #fffff; }
  3. p.link:hover { background: #ffff00; color: #000088; font-weight: bold;}
  4. h2.link:hover { background: #ffff00; color: #000088; font-weight: bold;}
  5. [etc]
  6.  

I have not found an explanation for this (if you have one, let us know!) so I cannot say whether this behaviour is consistent everywhere or what part of mason/apache/mod_perl is responsible, but it is worth mentioning.


That's all Folks! If you have any comments or criticisms please post and I will do my best to incorporate (sane) suggestions! And thanks to members of the mason-user list for their input -- much appreciated.

-MK27
Moderator Remark: Major update!
  • Anonymous
  • Bot
  • No Avatar
  • Posts: ?
  • Loc: Ozzuland
  • Status: Online

Post 3+ Months Ago

  • mk27
  • Proficient
  • Proficient
  • User avatar
  • Posts: 334

Post 3+ Months Ago

Okay the demo is on line if you want to check it out:

http://206.251.36.107/zoodemo/
  • chrisscm
  • Born
  • Born
  • chrisscm
  • Posts: 3

Post 3+ Months Ago

Thanks a lot for this tutorial!

Two things:
- The demo link doesn't seem active!?

- Unfortunately, in Ubuntu 10.04, the zoodemo won't work correctly when used locally.

There are Mason examples included in Ubuntu (libhtml-mason-perl-examples), which get copied into /var/www/mason_examples. Those work w/out any problems, but the zoodemo .mhtml files don't seem to get interpreted.

As I'm new to Mason, I'd greatly appreciate any hints on a possible solution to this problem!

Regards,
chrisscm
  • chrisscm
  • Born
  • Born
  • chrisscm
  • Posts: 3

Post 3+ Months Ago

I found a quick solution:

- copy configuration file from /etc/apache2/conf.d/libhtml-mason-perl-examples.conf to same location/libhtml-mason-perl-zoodemo.conf

- comment out what's not needed

This is the resulting configuration file:

Code: [ Select ]
<IfModule mod_perl.c>
  PerlModule CGI::Cookie
  <Directory /var/www/zoodemo>
    SetHandler perl-script
    PerlResponsehandler HTML::Mason::ApacheHandler
    PerlSetVar MasonArgsMethod CGI
    # CGI was previously required for Mason to work in Apache2
  </Directory>
</IfModule>
  1. <IfModule mod_perl.c>
  2.   PerlModule CGI::Cookie
  3.   <Directory /var/www/zoodemo>
  4.     SetHandler perl-script
  5.     PerlResponsehandler HTML::Mason::ApacheHandler
  6.     PerlSetVar MasonArgsMethod CGI
  7.     # CGI was previously required for Mason to work in Apache2
  8.   </Directory>
  9. </IfModule>
  • chrisscm
  • Born
  • Born
  • chrisscm
  • Posts: 3

Post 3+ Months Ago

My last post was affected by ignorance - sorry.

What I was trying to achieve was meant to be achieved by the delivered .htaccess-files.

Just these little modifications for Ubuntu 10.04 (for others who face the same problem):

- .htaccess might need to be enabled; so put a file into /etc/apache2/conf.d:

Code: [ Select ]
# Enable .htaccess server side includes
<Directory /var/www/zoodemo>
  AllowOverride Options
  AllowOverride FileInfo
</Directory>
  1. # Enable .htaccess server side includes
  2. <Directory /var/www/zoodemo>
  3.   AllowOverride Options
  4.   AllowOverride FileInfo
  5. </Directory>


- reload apache2

- in the zoodemo-.htaccess files (there's more than one!) remove the "Files *" part as the current Ubuntu apache doesn't seem to like the "Header" directive

And of course - as already stated in the tutorial's README, replace the base location (default: /var/www/html/zoodemo, for me it is /var/www/zoodemo).

Enjoy.

Post Information

  • Total Posts in this topic: 5 posts
  • Moderator: Tutorial Writers
  • Users browsing this forum: No registered users and 1 guest
  • You cannot post new topics in this forum
  • You cannot reply to topics in this forum
  • You cannot edit your posts in this forum
  • You cannot delete your posts in this forum
  • You cannot post attachments in this forum
 
cron
 

© 1998-2014. Ozzu® is a registered trademark of Unmelted, LLC.