More Fun with HTML::Mason

Perl stuff
* Mason stuff
Tk stuff
C stuff

In my Perl page, I showed a rudimentary introduction to HTML::Mason for very plain looking web pages. Just a header and footer. But the average Mason user is going to want some more. You may have noticed a nice motif in Web pages that is becoming common, which is a sidebar to the left with a tree of a web site's content. The sidebar will contain the main topical divisions of a web site. If the individual page is further deep into the site, the table cell for a topic will have below it a table listing that topic subtopics, in a limitedly recursive fashion.

I like that. So, let's Masonize it. A modified version of my header component omits the table I showed in my previous page and instead calls my sidetable component. Let's look at that.

my %entries = 
     'default' => 
      { 'name' => 'faq' , 'url' => 'faq.html', 'text' => 'faq' }  ,
      { 'name' => 'perl' , 'url' => 'perl.html', 'text' => 'Perl stuff' }  ,
      { 'name' => 'cstuff', 'url' =>'cstuff'  , 'text' => 'C stuff' }  ,
      { 'name' => 'randomness', 'url' =>'randomness.html' ,
	'text' => 'Randomness'}  
     'perl' => 
      { 'name' => 'mason' , 'url' => 'mason.html' , 'text' => 'Mason stuff'}, 
      { 'name' => 'tk' , 'url' => 'tk.html' , 'text' => 'Tk stuff'}, 
      { 'name' => 'RecDescent' , 'url' => 'RecDescent.html' ,
	'text' => 'RecDescent <BR> stuff'}
The <%perl> tag opens our initialization section. Each table is a hash with a name and an anonymous array, which in turn holds a set of anonymous hashes. Our top level table is the 'default' one. We have one lower-level table so far. Each table cell needs a name (for our purposes), a URL to point to (local in this case, but it need not be), and some text.
my @names = split ':', $sidebar_subtopic; 
my $subtopic = shift @names;  
my $next_subtopic = join(':',@names); 
The first two arguments to become relevant here are $sidebar_topic, which selects the table this component deals with, and $sidebar_subtopic, which selects the recursive tables to be opened up. These last three lines of Perl code allow us to make as many recursions as we want, but that woould begin to look tiresome if overused.
<table height="100%" width="<% $sidebar_width %>" 
    align="<% $sidebar_align %>" 
    cellpadding=0 cellspacing=0
    border="<% $sidebar_border %>" >
This is the simple part. We're just starting our table.
 % foreach my $entry ( @{$entries{$sidebar_topic}}) {
	<td align="<% $sidebar_align %>" valign="top"
 %       if ($subtopic ne '' && defined $entries{$subtopic} ){
 %       }
 %       if ($subtopic eq $entry->{name} ) {
                bgcolor="<% $sidebar_highlight_bg %>"
 %       }
Now we go through each entry in the table. If our table is going to have a recursion in it, then each cell that does not do the recursion is going to need an added column span. That makes the tables fit together nicely. If the current subtopic matches the name of this cell, then we highlight it by changing the background color. This is actually an ugly way to do it. A bullet image file would be better, but my skills with GIMP need more work than my Perl skills.
	    <a href="<% $entry->{url} %>" >
		<% $entry->{text} %> </a>
Our cell is ready to have things in it, so we give it the text and the link. Now, if this particular cell is part of our context, as specified in the arguments, we need to make the recursive component call:
 %       if ($subtopic eq $entry->{name} && defined $entries{$subtopic}) {
 		<tr>	<td valign="top" >
 			<img src="graphics/tablearrow.gif"
			     height="32" width="32">	
		<td valign="top">
		<& sidetable.comp , 
		   sidebar_border => '0',
                   sidebar_width => '99%' , 
                   sidebar_subtopic => "$next_subtopic", 
		   sidebar_topic => "$subtopic" &>
 %	}
 % }
We close the loop and close the table, and we are done. All that is left to do is the arguments. Note that a large list of them makes it easier to customize the use of this component. Static Mason use means you can be generous with predefined arguments!
        $sidebar_bg => "#22bb22"
        $sidebar_highlight_bg => "black"
        $sidebar_fg => "#ff0000"
        $sidebar_subtopic => ''
        $sidebar_topic => 'default'
	$sidebar_border => '0'
	$sidebar_width => '99%'
	$sidebar_align => 'left'
So, this component lets you create an easily navigated tree of your web pages, which you can stick anywhere. For more creativity you can modify your header or footer to let you navigate forward and backward (if your tree table is an actual table of contents, for example). I'll wait a few days before doing it for my pages, however.
Home To top

Omri Schwarz, March 9, 2001