3. webmaster.pl - a working HTML::Template example
HTML templates can be a really powerful tool when creating and maintaining web sites.
Headers, footers, and navigation bars can be stored in a few templates, which can be used as a layout for the whole site.
This site is maintained with a script called webmaster.pl.
Basically, web pages in this site are divided into 3 categories:
All web pages, independent of category, use the same layout, stored in a HTML template called layout.tmpl.html.
The template contains two tags: <TMPL_VAR NAME="TITLE"> <TMPL_VAR NAME="PAGE_CONTENTS">
Category 1: Static web pages(top)
The advantage of using a layout template is that all changes to the layout is made in one single file.
Running webmaster.pl then applies the changes to all web pages in the whole site.
All static web pages are listed (together with their title) in the configuration file templates.conf:
# Column format: FILE_NAME TITLE
aboutus.html Red Antigua - About Us
# Other pages may follow...
The contents of each static web page is stored in its own HTML template.
The template uses the same name as the resulting web page, using the the tmpl.html extension instead of html.
For example, the web page aboutus.html has a corresponding template called aboutus.tmpl.html.
In this case, the layout and contents templates simply are "merged" together and save as a resulting web page as follows:
As aboutus.html is a static web page, the corresponding template aboutus.tmpl.html contains no template tags.
What follows is a code extract, not a complete working example:
# Example code how to generate a web page using a layout template
my$layout_template = HTML::Template->new(filename => 'layout.tmpl.html');
# File name and title obtained from templates.conf
my$web_page_file_name = 'aboutus.html';
my$title = 'About Us';
# Replace the extension '.html' for '.tmpl.html' to get the corresponding template file name
(my$web_page_template_name = $web_page_file_name) =~ s/\.html$/\.tmpl\.html$/;
my$page_template = HTML::Template->new(filename => $web_page_template_name);
# No template params to set in about.tmpl.html - no need to call HTML::Template->param()
my$page_contents = $page_template->output();
# Set template params in layout.tmpl.html
$layout_template->param(
TITLE => $title
PAGE_CONTENTS = > $page_contents;
);
my$web_page_contents = $layout_template->output();
# Save the generated web page to disk
open(OUTPUT,"> $web_page_file_name") || die("can't open $web_page_file_name: $!");
print OUTPUT $web_page_contents;
close(OUTPUT) || die"can't close $web_page_file_name: $!";
How static web pages are composed is illustrated in figure 1:
Figure 1: Composition of a static web page
layout.tmpl.html - the common layout template
aboutus.tmpl.html - the template with the contents
aboutus.html - the resulting web page
Category 2: Static web pages with navigation bars(top)
Static web pages using a navigation bar are almost identical to any other static web page, with the exception of a generated navigation bar on each page.
This is practical when a tutorial spans over various pages.
If a page is added after or inserted in a tutorial, the navigation bars are re-generated without the needs of editing them by hand.
Static web pages using a navigation bar are listed in the configuration file templates-navbar.conf:
...
# Column format: FILE_NAME HREF_TEXT (OPTIONAL) TITLE (OPTIONAL)
# The next line is blank, indicating the beginning of a new group
html-template.html 'Red Antigua - HTML::Template Tutorial'
html-template1.html '"Hello, World!", simple'
html-template2.html '"Hello, World!", using HTML::Template'
html-template3.html 'webmaster.pl - A working example with HTML::Template'
# Other groups may follow...
...
Web pages listed in templates-navbar.conf are grouped, each group separated by one or more blank lines.
The first file in a group is defined as the group index page, which contains a list index of all other pages in that group.
The page html-template.html is an example of a group index page.
The list index is a list of links to all other pages in the group.
The list is generated by using the first column (the file name) as a href link.
The href text also defaults to the file name, but if a second column is present (HREF_TEXT), that text is used instead.
(The third optional column, TITLE, isn't used in the group index page.)
Code fragment to generate the index list:
# Get all group file names and corresponding href text
my@group_data = (); # initialize an array to hold your loop
# Skip first element (the group index itself) from index list
for (my$j = 1; $j < (scalar(@{$groups{$group_name}}) - 1); $j++) {
my%row_data; # get a fresh hash for the row data
$row_data{FILE_NAME} = $groups{$group_name}[$j]{file_name};
$row_data{HREF_TEXT} = $groups{$group_name}[$j]{href_text};
push(@group_data, \%row_data);
}
$page->param(
INDEX_LIST => \@group_data,
);
and the corresponding fragment of the HTML template:
Previous - link to previous page in group (in this case html-template2.html)
Next - link to next page in group (in this case none)
The Index link is obtained from the first column in the first line in a group from templates-navbar.conf.
The Index link is the same for all navigation bar in all pages within a group.
The Previous link is disabled for the first page in a group, as ther is none.
The Next link is disabled for the last last page in a group, as there is none.
The navigation bar template navbar.tmpl.html looks like this:
<!-- navbar - begin --><divstyle="width: 80%; padding: 5px"><spanstyle="width: 33%; padding-right: 10px"><ahref="<TMPL_VAR NAME="INDEX">">Index</a></span><TMPL_IF NAME="PREVIOUS"><spanstyle="width: 33%; padding-right: 10px"><ahref="<TMPL_VAR NAME="PREVIOUS">">Previous</a></span><TMPL_ELSE><!-- disabled link - begin --><spanstyle="width: 34%; padding-right: 10px; color: #999999">Previous</span><!-- disabled link - end --></TMPL_IF><TMPL_IF NAME="NEXT"><spanstyle="width: 33%; padding-right: 10px"><ahref="<TMPL_VAR NAME="NEXT">">Next</a></span><TMPL_ELSE><!-- disabled link - begin --><spanstyle="width: 34%; padding-right: 10px; color: #999999">Next</span><!-- disabled link - end --></TMPL_IF></div><!-- navbar - end -->
How the group index pages and pages with navigation bars are composed is illustrated in figure 2a and figure 2b:
Figure 2a: Composition of a group index page
Figure 2b: Composition of a web page with navigation bars
Figure 2a:
layout.tmpl.html - the common layout template
html-template.tmpl.html - the template with the contents
output from <TMPL_LOOP NAME="INDEX_LIST"> - the index list
html-template.html - the resulting web page
Figure 2b:
layout.tmpl.html - the common layout template
html-template3.tmpl.html - the template with the contents
navbar.tmpl.html - the navigation bar(s)
html-template3.html - the resulting web page
Category 3: Dynamic web pages (CGI scripts) (top)
Web pages with dynamic contents (CGI scripts) are not listed in any configuration files.
The CGI script may generate generate any title feed it to the <TMPL_VAR NAME="TITLE">
tag, and generate whatever contents, using a template or not, feed it to the <TMPL_VAR NAME="PAGE_CONTENTS">
tag, before sending the output to the browser (not to a file, as done in Category 1 & 2).
In the case of the CGI script Your IP, it is only listed in layout.tmpl.html as any other internal or external link.
The script uses a template called yourip.tmpl.html to generate its contents, but the real advantage is the usage of layout.tmpl.html, which makes CGI scripts have the same look and feel as any other page in this site.
How dynamic web pages are composed is illustrated in figure 3:
Figure 3: Composition of a dynamic web page
layout.tmpl.html - the common layout template
/cgi-bin/yourip.pl - dynamic contents
/cgi-bin/yourip.pl - the resulting dynamic web page, "merging" layout.tmpl.html with the dynamic contents
To start creating and maintaining your own website, you need to download:
Edit anything you want to, but don't forget to backup any existing web pages before running the script!
The webmaster.pl script is a very basic tool.
Any output from webmaster.pl is in HTML, so the script can be run either from the command line or as a CGI script.
Anyway, I prefer to edit the template files with Emacs, and execute M-! webmaster.pl (Type 'Alt + !', then 'webmaster.pl') inside Emacs to modify and update the entire site without leaving the text editor.
You can probably improve the script, or maybe you got another idea how to use HTML::Template by your own.