| [ Team LiB ] |
|
HTML + Tcl TemplatesThe template system uses HTML pages that embed Tcl commands and Tcl variable references. The server replaces these using the subst command and returns the results. The server comes with a general template system, but using subst is so easy you could create your own template system. The TclHttpd template framework has these components:
Where to Put Your Tcl CodeThere are three places you can put the code of your application: directly in your template pages, in the per-directory .tml files, or in the library directory. There are pros and cons to each:
Templates for Site StructureThe next few examples show a simple template system used to maintain a common "look and feel" across the pages of a site. The key to a successful template system is a data structure that defines the structure of the site, and some procedures that generate standard navigational HTML structure for your pages. Once you do this, then you can easily add new pages by updating your data structure. The template procedures automatically reformat your site to include the new pages. Example 18-6 shows a simple one-level site definition that is kept in the root .tml file. This structure lists the title and URL of each page in the site: Example 18-6 A one-level site structure
set site(pages) {
Home /index.html
"Ordering Computers"/ordering.html
"New Machine Setup" /setup.html
"Adding a New User" /newuser.html
"Network Addresses" /network.html
}
Of course, your Web site is likely to have more pages and a more elaborate structure. For example, you might have several main sections, each with a collection of pages, or even a three-level hierarchy of pages. Example 18-7 shows another simple data structure to define a two-level structure. The site(sections) variable stores the names and URLs of the main sections. For each section, there is an element of site that lists the pages in that section. Only the About section is shown in the example: Example 18-7 A two-level site structure
set site(sections) {
About /about
Products /products
Support /support
}
set site(About) {
Company company.html
Contacts contacts.html
Directions directions.html
}
In practice, you may want to include more information in your data structure to help you generate HTML. For example, if you have graphics for the main sections, you may need to record their size. Whatever you need, collect it into your data structures and then generate the HTML from procedures. You can quickly give your whole site a face lift with new graphics by changing the template procedures that generate your pages. In contrast, if you hand-code all your pages, it can take months instead of days. Example 18-8 shows a sample template file for the one-level structure shown in Example 18-6. Each page includes two commands, SitePage and SiteFooter, that generate HTML for the navigational part of the page. Between these commands is regular HTML for the page content: Example 18-8 A HTML + Tcl template file[SitePage "New Machine Setup"] This page describes the steps to take when setting up a new computer in our environment. See [SiteLink "Ordering Computers"] for instructions on ordering machines. <ol> <li>Unpack and setup the machine. <li>Use the Network control panel to set the IP address and hostname. <!-- Several steps omitted --> <li>Reboot for the last time. </ol> [SiteFooter] The SitePage procedure takes the page title as an argument. It generates HTML to implement a standard navigational structure. Example 18-9 has a simple implementation of SitePage: Example 18-9 SitePage template procedure, version 1
proc SitePage {title} {
global site
set html "<html><head><title>$title</title></head>\n"
append html "<body bgcolor=white text=black>\n"
append html "<h1>$title</h1>\n"
set sep ""
foreach {label url} $site(pages) {
append html $sep
if {[string compare $label $title] == 0} {
append html "$label"
} else {
append html "<a href='$url'>$label</a>"
}
set sep " | "
}
return $html
}
The foreach loop that computes the simple menu of links turns out to be useful in many places. Example 18-10 splits out the loop and uses it in a new version of SitePage along with the SiteFooter procedure. This version of the templates creates a left column for the navigation and a right column for the page content. The example also puts a few more visual elements (e.g., page background color) into the site array so you can easily maintain them: Example 18-10 SiteMenu and SiteFooter template procedures
array set site {
bg white
fg black
mainlogo /images/mainLogo.gif
}
proc SitePage {title} {
global site
set html "<html><head><title>$title</title></head>\n\
<body bgcolor=$site(bg) text=$site(fg)>\n\
<!-- Two Column Layout -->\n\
<table cellpadding=0>\n\
<tr><td>\n\
<!-- Left Column -->\n\
<img src='$site(mainlogo)'>\n\
<font size=+1>\n\
[SiteMenu <br> $site(pages)]\n\
</font>\n\
</td><td>\n\
<!-- Right Column -->\n\
<h1>$title</h1>\n\
<p>\n"
return $html
}
proc SiteFooter {} {
global site
set html "<p><hr>\n\
<font size=-1>[SiteMenu | $site(pages)]</font>\n\
<!-- Close Right Column -->\n\
</td></tr></table>\n"
return $html
}
proc SiteMenu {sep list} {
global page
set s ""
set html ""
foreach {label url} $list {
if {[string compare $page(url) $url] == 0} {
append html $s$label
} else {
append html "$s<a href='$url'>$label</a>"
}
set s $sep
}
return $html
}
There are many other applications for "macros" that make repetitive HTML coding chores easy. For example, take the SiteLink procedure call in Example 18-8. Instead of hand-coding the <A> tag with the link to /ordering.html, the page uses the SiteLink procedure to format the link with a consistent label for the link. Using the procedure also means that the page will automatically get updated if you change the URL associated with the ordering page by modifying site(pages). Example 18-11 shows SiteLink: Example 18-11 The SiteLink procedure
proc SiteLink {label} {
global site
array set map $site(pages)
if {[info exist map($label)]} {
return "<a href='$map($label)'>$label</a>"
} else {
return $label
}
}
Using Variables for Important Site InformationAnother useful feature of templates is the ability to embed variable references in your pages. Instead of hard coding the sales phone number, or the current product version number, or even the product name, you can put variables into your pages. For example, SiteLink and SitePage take a parameter that is the page title. Instead of hard coding your page titles, you could keep all of your page titles in an array, and use array references everywhere. That puts all the text in one place and makes it easy to change. The array definition would look something like this:
array set title {
Home Home
Order "Ordering Computers"
Setup "New Machine Setup"
AddUser "Adding a New User"
Network "Network Addresses"
}
And the calls to SitePage or SiteLink could be made like this: [SitePage $title(Order)] The .tml pages are a good place to define the variables because the definitions are shared by all pages in that directory, and in any subdirectories. Also, the definitions in the per-directory .tml override any definitions that come from the top-level .tml file at the root of your URL tree. Changing the definition of the variable in the .tml file immediately updates all the pages that share it. The main drawback to variable references is the clash with $ in pricing. If you put $10 into a page.tml file, it will raise an error (unless the variable 10 is defined). It turns out that you want to generate prices from some database anyway, so you should avoid hard coding prices into your pages anyway. It is much better to put [price T-shirt] or $price(T-shirt) into your page than $10, although if you must do that, just quote the $ with a backslash, \$10. |
| [ Team LiB ] |
|