Server-side Scripting

WCTL and Nested Folder Templates

Introduction
Customizing a Folder Template
The Contents of tableFolder
Troubleshooting
Resources

Nested Templates - Introduction

In the previous section, you learned how to use a process filter to intercept vulgar words on their way to the Web Crossing database, and how process filters can allow you to even customize how Web Crossing functions.

To close out this introduction to the Web Crossing Template Language, we will show you one more powerful technique - using nested templates to customize the look and feel of a single folder hierarchy while leaving your other folders unchanged. This uses a feature of WCTL called nested templates - including one template inside another.

Using nested templates you can override the default behavior of specific templates, and limit the effect of your changes to specific folder hierarchies.

Customizing a Folder Template

Consider the template that displays the list of items in a folder: %% macro folder %%:

%% macro folder %%
<HTML><HEAD>
<!-- Page produced by %% programName %%(r)/%% platform %%-%% version %% (%% programPromo %%) for %% siteLicensee %%-->
<!-- User interface (c)Copyright 1995-1999 by Lundeen & Associates. All rights reserved.-->
<title>%% siteTitle %% - %% pathTitle %%</title></HEAD>
<body %% background %%>%% preparedFor %%%% banner %%
<b>%% backPath %%</b>
<ul><h1>%% pathTitle %%</h1></UL>
%% pathStandardHeading %%
%% pathItems %%
%% use toolbar %%
%% footer %%</BODY></HTML>
%% endmacro %%

This template uses various built-in WCTL variables and calls other macros to display the current list of items in the folder. You can refer to the list of standard templates in the sysop online reference manual for more details on the which templates are available.

Note: Unfortunately (and this is always confusing to people when they first start customizing templates) it isn't exactly clear what pathStandardHeading and pathItems actually do. If you look in the templates list you will find %% macro toolbar %%, but you will not find either %% macro pathStandardHeading %% or %% macro pathItems %%.

This is because those two commands are not actually templates. They are built-in WCTL variables which call other templates.

You can certainly create your own pathStandardHeading and pathItems macros which mirror the action of these built-in variables, and then customize them as you wish. But you need to build them from parts found in webxStd-local.tpl and webxextn.tpl.

The pathItems command creates a list of all the unique path numbers in a folder and then calls a standard template named folderListItem in a loop to actually display the items, one at a time.

Normally, when you enter a folder, you will see a list of sub-folders (and other items such as discussions, chats and links) as in figure 1.

Figure 1 - a list of sub-folders using the Classic folderListItem layout


Suppose we want to modify the behavior of folderListItem for one particular folder hierarchy without affecting the standard way other folders are viewed? You might very well want to do this if you are using Web Crossing's Virtual Forums feature and would like different folders for different groups of users to have different kinds of customization.

Let's change the behavior of this folder hierarchy to display the contents as a table, instead of a simple list, as in figure 2.

Figure 2 - a modified folder view using a customized folderListItem

The way we do this is by creating a new template called tableFolder. By editing the folder appearance (Edit Folder > Appearance) and setting the template name for the folder to be tableFolder, as in figure 3, we can override the functionality of the standard folder macro and replace it with our customized version - tableFolder.

Figure 3 - setting a custom folder template in Edit Folder

After making the above setting change, our test folder and all sub-folders contained in the same hierarchy will use tableFolder instead of the standard folder template.

Now it is just a matter of creating the tableFolder template macro.

The structure of our tableFolder macro looks like:

%% macro tableFolder %%
%% macro folder %%
our modified folder macro
%% endmacro %%
%% macro folderListItem %%
our modified folderListItem macro
%% endmacro %%
%% endmacro %%

The tableFolder macro contains all the macros whose behavior we wish to modify:

The key point here is this - we only want this folder hierarchy to display modified behavior as specified by our changes in the folder and folderListItem macros. We didn't want to change the toolbar or any of the other macros. So there was no need to specify those other macros inside tableFolder. If a macro is unspecified, the Web Crossing default behavior is used.

For example, if you just wanted to change the way the toolbar looks in your customized folders, all you would need inside tableFolder is your own customized toolbar macro. You would not need customized folder or folderListItem macros in that case.

Another major point is this - your modified folder and folderListItem macros are nested inside the tableFolder macro. This means your changes only affect folders that actually use tableFolder (your test folder and all child folders). Nesting the macros inside another macro limits the scope of their actions. If you wanted to globally change folder and folderListItem, you could simply remove the outermost

%% macro tableFolder %%
.....
%% endmacro %%

commands. This would remove the protective nesting layer and would mean that folder and folderListItem are globally customized and affect all folders in your entire Web Crossing site.

By nesting macros you can have completely different folder (and discussion) appearances and behaviors in different parts of your site.

Now let's look at the specifics of our customized tableFolder macro.

The Contents of tableFolder

You can copy the following macro into your own tablefolder.tpl file and install in on your site to test it out. To install this macro, follow the instructions in the section on WCTL Macros.

This is one of our longer examples, but the actual modifications to the standard templates are few. To make it easier to see the changes, modified sections are highlighted in red and then explained following the listing.

%% macro tableFolder %%
<!------------------- folder ---------------------------->
%% macro folder %%
<HTML><HEAD>
<!-- Page produced by %% programName %%(r)/%% platform %%-%% version %% (%% programPromo %%) for %% siteLicensee %%-->
<!-- User interface (c)Copyright 1995-1999 by Lundeen & Associates. All rights reserved.-->
<title>%% siteTitle %% - %% pathTitle %%</title></HEAD>
<body %% background %%>%% preparedFor %%%% banner %%
<b>%% backPath %%</b>
<UL><h1>%% pathTitle %%</h1></UL>
%% pathStandardHeading %%
%% set session.viewFlag 0 %%
%% pathItems %%
</TR>
</TABLE>
%% use toolbar %%
%% footer %%</BODY></HTML>
%% endmacro %%

<!----- folder item template, default presentation -------->
%% macro folderListItem %%
%% setPathToParent %%
%% set _iconRow 4 %%
%% setPath %%
%% if !_iconRow %%
%% set _iconRow 1 %%
%% endif %%
%% if session.viewFlag == 0 %%
%% set session.viewFlag 1 %%
%% set session.viewCount 1 %%
<TABLE BORDER=0 CELLPADDING=2 CELLSPACING=0>
<TR>
%% endif %%
%% if session.viewCount > _iconRow %%
</TR>
<TR>
%% set session.viewCount 1 %%
%% endif %%
<TD VALIGN=TOP CELLPADDING=4 CELLSPACING=4>
%% if pathIsFolder %%
<center>
<a href="%% pathUrl %%">
<img border=0 src="%% siteImages %%/topic.gif" alt=""><BR>
<b>%% pathTitle %%</b>
%% if pathHasItems %% <BR>
<font size=2>(%%nop%%
%% if pathHasFolders %%
%% pathFolderCount %%
%% if pathHasOneFolder %%
folder%%nop%%
%% else %%
folders%%nop%%
%% endif %%
%% if pathHasDiscussions %%
, %%nop%%
%% endif %%
%% endif %%
%% if pathHasDiscussions %%
%% pathDiscussionCount %%
%% if pathHasOneDiscussion %%
discussion%%nop%%
%% else %%
discussions%%nop%%
%% endif %%
%% endif %%
)</font>%%nop%%
%% endif %%
</a>%%nop%%
</center>
%% else if pathIsDiscussion %%
<!-- Discussion -->%%nop%%
%% if pathShowsSummaryButton %%
<a href="%% urlBase %%230@%% certificate %%@%% location %%">%%nop%%
<img align=bottom border=0 src="%% siteImages%%/outline.gif" alt="[Outline] "
%% pictSizeOutline %%>%% pathIcon border=0 align=bottom%% </a>%% nop %%
<a href="%% pathUrl %%">%%nop%%
%% else %%
<a href="%% urlBase %%230@%% certificate %%@%% location %%">%% pathIcon border=0 align=bottom%% <a href="%% pathUrl %%">%%nop%%
%% endif %%
<b>%%nop%%
%% pathTitle %%
</b>%%nop%%
%% if pathHasMessages %%
<font size=2>(%%nop%%
%% pathMessageCount %%
%% if pathHasOneMessage %%
message%%nop%%
%% else %%
messages%%nop%%
%% endif %%
%% if pathHasNewMessages %%
, %%nop%%
%% pathNewMessageCount %%
new%%nop%%
%% endif %%
)</font>%%nop%%
%% else if pathIsNew %%
<font size=2>(new)</font>
%% endif %%
</a>%%nop%%
%% else if pathIsLink %%
<!-- Link -->%%nop%%
%% setPathFollowLink %%
%% if pathIsDiscussion && pathShowsSummaryButton %%
<a href="%% urlBase %%230@%% certificate %%@%% location %%">%%nop%%
<img align=bottom border=0 src="%% siteImages%%/outline.gif" alt="[Outline] "
%% pictSizeOutline %%>%% setPath %%%% pathIcon border=0 align=bottom%% </a>%% nop %%
<a href="%% pathUrl %%">%%nop%%
%% else if pathIsDiscussion %%
<a href="%% urlBase %%230@%% certificate %%@%% location %%">%% setPath %%%% pathIcon border=0 align=bottom%% <a href="%% pathUrl %%">%%nop%%
%% else %%
%% setPath %%<a href="%% pathUrl %%">%%nop%%
%% if pathShowsSummaryButton %%
<img align=bottom border=0 src="%% siteImages%%/t.gif" alt="" %% pictSizeOutline %%>%% nop %%
%% endif %%
%% pathIcon border=0 align=bottom%%
%% endif %%
<b>%% pathTitle %%</b>%%nop%%
%% setPathToLink %%
%% if pathIsFolder && pathHasItems %%
<font size=2>(%%nop%%
%% if pathHasFolders %%
%% pathFolderCount %%
%% if pathHasOneFolder %%
folder%%nop%%
%% else %%
folders%%nop%%
%% endif %%
%% if pathHasDiscussions %%
, %%nop%%
%% endif %%
%% endif %%
%% if pathHasDiscussions %%
%% pathDiscussionCount %%
%% if pathHasOneDiscussion %%
discussion%%nop%%
%% else %%
discussions%%nop%%
%% endif %%
%% endif %%
)</font>%%nop%%
%% else if pathIsDiscussion && pathHasMessages %%
<font size=2>(%%nop%%
%% pathMessageCount %%
%% if pathHasOneMessage %%
message%%nop%%
%% else %%
messages%%nop%%
%% endif %%
%% if pathHasNewMessages %%
, %%nop%%
%% pathNewMessageCount %%
new%%nop%%
%% endif %%
)</font>%%nop%%
%% endif %%
</a>%% nop %%
%% setPath %%
%% if userCanEdit %%
&#160;<a href="%% urlBase %%138@%% certificate %%@%% location %%"><img border=0 align=top alt="Edit" src="%% siteImages%%/smedit.gif" %% pictSizeInlineButton %%></a>
%% endif %%
%% if linkShowDescription && linkDescription %%
<UL>%% linkDescription.quickEdit.tplClosure %%</UL>
%% endif %%
%% else if pathIsChat %%
<!-- Chat room -->%%nop%%
<a href="%% pathUrl %%">%%nop%%
%% if pathShowsSummaryButton %%
<img align=bottom border=0 src="%% siteImages%%/t.gif" alt="" %% pictSizeOutline %%>%% nop %%
%% endif %%
%% pathIcon border=0 align=bottom%%
<b>%%nop%%
%% pathTitle %%
</b></a>%%nop%%
%% if user.userIsMember( "socks" ) %%
<a href="%% urlBase %%196@%% certificate %%@%% location %%">[Enter from outside the firewall]</a>%%nop%%
%% endif %%
%% if userCanEdit %%
&#160;<a href="%% urlBase %%193@%% certificate %%@%% location %%"><img border=0 align=top alt="Edit" src="%% siteImages%%/smedit.gif" %% pictSizeInlineButton %%></a>
%% endif %%
%% else %%
<!-- Other -->%%nop%%
<a href="%% pathUrl %%">%%nop%%
%% if pathShowsSummaryButton %%
<img align=bottom border=0 src="%% siteImages%%/t.gif" alt="" %% pictSizeOutline %%>%% nop %%
%% endif %%
%% pathIcon border=0 align=bottom%%
<b>%%nop%%
%% pathTitle %%
</b></a>%%nop%%
%% endif %%
</TD>
%% set session.viewCount session.viewCount + 1 %%
%% endmacro %%
%% endmacro %%

As you can see, most of folderListItems was left unchanged. All that was added was some strategic code to count the columns, start a new row and add table tags in appropriate places. Here is an explanation of the changed places:

Changes in folder:

</TR>
</TABLE>

These two lines follow the built-in pathItems command, which calls the folderListItems macro in a loop (one loop for each item in the folder). When we are all finished with folderListItems we want to close the table we have created. This is accomplished by these two tags, which end the row and close the table.

Changes in folderListItem:

%% set _iconRow 4 %%

Here we set a local variable called _iconRow to the value 4. We want to make a table with 4 columns of cells on each row. You can change this number to create tables with larger or smaller rows.

%% if session.viewFlag == 0 %%
%% set session.viewFlag 1 %%
%% set session.viewCount 1 %%
<TABLE BORDER=0 CELLPADDING=2 CELLSPACING=0>
<TR>
%% endif %%
Session variables are special kinds of temporary variables that follow along with a current user. Each user has his or her own set of session variable that only exist while accessing Web Crossing. These kinds of variable are extremely useful in such applications as shopping carts and other applications that need to keep track of changing values for a currently accessing user.
Here we are using two session variables:
  1. folderListItems is called in a loop by pathItems, displaying each item (folder, discussion, etc.) one-by one. session.viewFlag is a session variable which starts off (by default) with a value of zero. It's only purpose it to test to see whether the current user has "been here before" or not - whether this is the first time in the display loop or not. If this is the first time in the display loop then we need to begin a new <TABLE> and a new <TR> (table row). We only want to do start a new <TABLE> one time, so we immediately set session.viewFlag to a value of 1. Programmers call this kind of variable a "flag" - a signal as to the current state of things while a program is running.
  2. We also start out by setting session.ViewCount to a value of 1. This session variable keeps track of the current column number. Remember, we don't want to display more than _iconRow cells on any row.
%% if session.viewCount > _iconRow %%
</TR>
<TR>
%% set session.viewCount 1 %%
%% endif %%

If the value in session.viewCount exceeds the value in _iconRow then we end the current row, begin a new row and reset session.viewCount to 1.

<TD VALIGN=TOP CELLPADDING=4 CELLSPACING=4>

We begin a new cell, aligning the contents at the top of the cells and put in a little spacing so the the table doesn't look too crowded.

</TD>
%% set session.viewCount session.viewCount + 1 %%

We close the cell and increment session.viewCount by 1.

We hope this example encourages you to try further modifications. We (Doug) has done customization at one of his sites to add customized icons to each folder, and show a red flag if there are any new messages in the sub-hierarchy, as in figure 4.

Figure 4 - a folder customized with the iconFolder template

As far as template customization goes, this iconFolder template does not require a great deal of additions to tableFolder. The main work is in creating all the icons! We also modified the template (nested inside iconFolder of course) for Edit Folder Appearance to allow the host or sysop to automatically set icons for each folder, as shown in figure 5.

Figure 5 - automatically setting an icon for a folder inside iconFolder

Once you start customizing, it is hard to stop!

Troubleshooting

I created tableFolder as described above, but when I go into my test folder it still looks the same.