Table of Contents Previous Next Index

Section 9 Creating and Editing Mail and Web Tem­plates

Section 9 Creating and Editing Mail and Web Tem­plates
Significant changes were made both to the mail template processor and to the default mail templates themselves for the version 14.3 release and following. In the main, these changes allow an unprecedented level of control over what were previously hard-coded, non-optional internal messages sent by LISTSERV in response to various commands.
It is now possible to define site-wide defaults for all template forms without having to edit the DEFAULT MAILTPL file, which is not upgrade-safe. Any customizations made at the site level to the default templates now go into the site-level SITE MAILTPL file, which will not be disturbed during an upgrade. Defining site-wide defaults in the old $SITE$ MAILTPL file, which in any case did not work for all templates and was never intended for this use to begin with, is now deprecated, and such usage is no longer supported in LISTSERV 15.
During startup, LISTSERV will migrate existing templates from WWW_ARCHIVE MAILTPL to SITE MAILTPL, unless one of the following conditions arises:
A conflicting template (same name, different contents) is already in SITE MAILTPL
The copy of the template in WWW_ARCHIVE matches the first template in the system search order.
If there are no conflicts, WWW_ARCHIVE MAILTPL is then renamed to WWW_ARCHIVE OLDTPL. If a conflict is detected, LISTSERV will not attempt to determine which version of the template is "correct", but rather will log something like the following:
7 Oct 2004 10:57:05 Migrating templates from WWW_ARCHIVE to SITE...
- $TEST_TEMPLATE: conflicting version found in SITE
7 Oct 2004 10:57:05 Conflicts detected, finish migration manually
It is then incumbent on the site maintainer to harmonize the differing versions of any templates reported to be in conflict.
9.1 Using LISTSERV Templates
Templates are used to generate some of the mail LISTSERV sends to users in response to commands it receives. Among these are the "You are now subscribed . . ." message, the message sent to users when LISTSERV cannot find a subscription for them in a specified list, and others. Note that certain administrative mail (for instance, the response to the STATS and RELEASE commands) is hard-coded into LISTSERV and cannot be changed.
Other templates are used to generate the HTML code used by the web archive and administration interfaces.
A word about nomenclature: When we talk about "templates" we are talking about "files that contain one or more template forms", in other words, files like DEFAULT MAILTPL or DEFAULT WWWTPL. A "template form" is an individual section of a template which begins with a title line (three ">" symbols followed by a space, the name of the template form, and (optionally) a short description of the template, which for some template forms is also used as the subject of the mail LISTSERV constructs with the template form), followed by one or more lines of copy and/or imbedded commands, and ends at the next title line or the end of the file, whichever is reached first. A template may contain one or more template forms.
9.2 Getting Copies of the Default Template Files
LISTSERV stores its default mail template information in a file called DEFAULT MAILTPL, which can be requested by list owners and LISTSERV maintainers from LISTSERV with the GET command, just like any other file. The LISTSERV maintainer will find this file in LISTSERV's "A" directory (usually ~listserv/home/default.mailtpl on unix, LISTSERV\MAIN\DEFAULT.MAILTPL on Windows systems, and LISTSERV_ROOT:[MAIN]DEFAULT.MAILTPL under VMS).
Note: DEFAULT MAILTPL contains the (obsolete) static web interface template forms.
LISTSERV stores its default dynamic web interface template forms in a file called DEFAULT WWWTPL, which can be retrieved in a manner identical to that for DEFAULT MAILTPL.
Note: It is considered unwise (and it is not supported) to modify the contents of DEFAULT MAILTPL or DEFAULT WWWTPL themselves, as these files will be overwritten by upgrades. It is possible to make sitewide changes that will not be overwritten without disturbing either of these files.
All template forms may be customized using the built-in tools found in the web administration interface described in Section 11 Using the Web Administration Interface. Edited template forms are placed in site-level or list-level template files that will not be overwritten by software upgrades.
9.3 Types of Templates
There are three different types of templates – Mail Templates, Message Templates, and Message Fragments.
9.3.1 Mail Templates
A mail template is a complete mail message. All commands are available, substitutions that make sense in the context of the specific message are available, the message may be formatted, and while other templates may be imbedded with the .IM command, the message is in and of itself ready for LISTSERV to send.
9.3.2 Message Templates
The next level down is a message template, i.e. a template that by default does not send any mail but supplies text that will ultimately be shown to the user - not always by e-mail, it could be over the web interface for instance.
Typically, message templates that are sent by mail will be "bundled" into a single message. However, a given message template can be forced to send an individual unbundled mail by using the new .SM command.
In a message template, you have the following restrictions:
The commands .TO/.CC/.RE/.CS are not allowed unless you use .SM.
Normally there will be limited access to formatting unless stated otherwise in the template. By "limited" is meant that you will, at a mininum, have the capability to break the text into separate paragraphs and to use .FO ON/OFF, although leading, trailing and duplicate blank lines will be removed.
Unless stated otherwise, .QQ will suppress the message. Note that this does not mean that other related messages are also suppressed, especially if they have already been sent. .QQ only suppresses the template you are currently reading.
9.3.3 Message Fragments
The lowest level is a message fragment. It could be a list of months in French, or a common sequence of words that is put in a template not just to make other templates more readable, but to improve consistency (see &MSGREF). This fragment is used in another messages and is not itself a message, hence the following restrictions:
.SM is not supported in message fragments (and thus other commands related to sending mail, for instance, .TO/.CC, etc. are not supported, either). If .SM is specified in a message fragment, an error similar to the following is raised in the web interface:
>>> Mail template "MSG_SUBSCRIBE_FRAGMENT_OPTCHANGED1" does not support .SM
and no email is actually sent. In the example case, .SM would have to be specified in the message template MSG_SUBSCRIBE_SUCCESS in order for it to succeed.
.SJ is ignored in message fragments The .SJ command should be issued in the template that sends the actual message, not in the fragment.
Formatting (.FO ON/OFF) is not allowed. Everything will be internally merged into a single line (this is similar to what was previously called a "linear" template).
.QQ is not supported in a message fragment.
9.4 Naming Conventions for Message Templates and Fragments
The following naming convention for message templates and message fragments has been introduced:
MSG_command_action_name
'command' is the name of the command. For instance, the name of a template that controls list postings starts with "MSG_POSTING_".
'action' is some kind of general action or category of action or the like. Every template with the same command and action SHOULD have the same calling conventions, in terms of what is allowed or not allowed, how the results are used, what global variables are available. Of course, each individual template may also have one or more variables that are specific to it. For instance, when a virus is detected, you will have the name of the virus, which is not available when "Sizelim=" is exceeded. If 'action' is something_FRAGMENT, the message is a fragment.
'name' is a unique identifier.
9.5 Mail Template Format and Embedded Formatting Commands
9.5.1 Mail Template Format
Each individual template form starts with a form name and subject line, such as:
>>> EXAMPLE1 This is the subject line
The following instructions are reminders for the form name and subject line:
The template form starts with the line containing the form name and subject, and ends with the next line starting with '>>>', or at the end of the file.
The subject line may contain substitutions (such as "&LISTNAME: &WHOM requested to join").
Ensure that there is a blank space (ASCII 0x20) between ‘>>>‘ and the name of the form, or LISTSERV will not recognize the form.
The names of the template forms must be typed in UPPER CASE.
A template form contains text and, optionally, formatting/editing commands, which start with a period in column 1. All other lines are treated as normal text: sequences starting with an & sign are substituted, then lines are joined together to form a paragraph, which is finally formatted like with any non-WYSIWYG text processor. You can suspend formatting with .FO OFF and resume it with .FO ON; when formatting is suspended, LISTSERV no longer joins lines to form a paragraph, but simply writes one line of text to the message for each line read from the template form. This makes it possible to include tables or a text-mode logo, but can create seriously imbalanced text if substitutions are used. For instance, a typical &WHOM substitution can range from a dozen characters to 60 or more, even though it only takes up 5 characters on your screen when you enter it.
9.5.2 Common Variable Substitutions
The following substitutions are always available:
&DATE – Long-style date (04 Jan 1998)
&TIME – hh:mm:ss
&WEEKDAY – Three-letter day of the week, in English
&MYNAMES – The substitution you will use most of the time when you need to refer to LISTSERV. For Internet-only or BITNET-only servers, this will display LISTSERV's only e-mail address. For servers with both Internet and BITNET connectivity, it will say "LISTSERV@hostname (or LISTSERV@nodeid.BITNET)".
&MYSELF – LISTSERV's address, in the form LISTSERV@XYZ.EDU or, if no Internet hostname is available, LISTSERV@XYZVM1.BITNET.
&MYNODE – LISTSERV's BITNET nodeid, without the '.BITNET', or its Internet hostname if no NJE address is available.
&MYHOST – LISTSERV's Internet hostname or, if none is available, its NJE address (with '.BITNET').
&MBX(addr) – Looks up the specified address in LISTSERV's signup file and displays "name <addr>" if a name is available, or just the original address otherwise. This is typically used to give the name of the command originator or target, along with his e-mail address: &MBX(&WHOM) or &MBX(&INVOKER). Please note however that &WHOM and &INVOKER are not always available in every template.
The "addr" parameter is always required; &MBX by itself is syntactically invalid.
&RELEASE – LISTSERV’s release number (e.g., "15.5").
&OSTYPE – The operating system under which LISTSERV is running.
&OSNAME – The full operating system name including the version number, e.g., "VM/ESA 1.2.3", "Windows NT 4.0", "Linux 2.0.27", "SunOS 5.4", etc.
&HARDWARE – The type of machine LISTSERV is running on, e.g., "Pentium (512M)".
The following substitutions are also available for templates related to mailing lists:
&LISTNAME – Either the short or long name of the list based on the value of "List-Address=" and/or its system default. By default the long ("List-ID=") name is used if present.
&TITLE – Title of the list, or empty string.
&KWD(kwd) – Value of the specified keyword for the list. You do not need to specify the name of the list - it is implicit. You need not put quotes around the keyword names either, although quotes will be accepted if present. Optionally, you can specify a second numeric argument to extract just one of the terms of a list header keyword; for instance, if the list header contains "Notebook= Yes,L1,Monthly,Private", &KWD(NOTEBOOK,4) has the value "Private". A third argument, also optional, specifies the default value for the keyword in case it was not initialized. It is meant to be used for conditional formatting in the default templates and list owners should not worry about it.
&LITE – Has the value 1 when running the LISTSERV Lite product, and 0 otherwise. This variable can be used to write generic templates that account for the differences between the two products.
&LITEFE – Has the value 1 when running the Free Edition of LISTSERV Lite. Similar to but distinct from &LITE.
&ISODATE – Returns today’s date in ISO format, i.e., yyyy-mm-dd.
&DAYSEQ(n) – Used to create FAQ templates with rotating topics. May also be used to create bottom banners with rotating text (e.g., for lists with multiple commercial sponsors who get "ad space" in the banner on a rotating basis).
In addition, many template forms have their own specific substitutions, meaningful only in their specific context. For instance, a message informing a user that he was added to a mailing list may have an &INVOKER substitution for the address of the person who issued the ADD command. This is not meaningful for a template form intended to inform a user that he must confirm his subscription to a list within 10 days, so it is not generally available. If you attempt to use a substitution which is not available, the template processor writes an error message to the mail message it is generating, but sends it anyway, in the hope that the recipient will be able to figure out the meaning of the message in spite of the error.
Important: If you need to include a sentence with an ampersand character, you will have to double it to bypass the substitution process, as in "XYZ &&co."
The mail template processor also supports HTML-like variable closure, in addition to the traditional LISTSERV closure (both methods are supported concurrently; there is no need to select one over the other). For example:
Traditional For more information, please send mail to &EMAIL or call &PHONE.
HTML For more information, please send mail to &EMAIL; or call &PHONE;.
Previously, HTML writers who used HTML closure conventions would not get the expected results. This change makes it easier for webmasters to get the desired results the first time.
9.5.3 Template Commands
Any line starting with a period in column 1 is processed as a formatting command. Note that neither substitutions nor formatting commands are case sensitive. The table below lists the formatting commands that list owners may need to use.
Table 9-1 Formatting Commands for List Owners
Comment: anything on this line is simply ignored. This is useful for recording changes to template files when there are multiple owners. Just add a comment line with the date and your initials every time you make a change, for the benefit of the other owners.
Removes all "cc:" message recipients. You can also add message recipients by specifying a series of e-mail addresses after the .CC statement, as in .CC JOE@XYZ.EDU. PC mail users should note that in this context "cc:" is a RFC822 term that stands for "carbon copy". RFC822 messages may have "cc:" recipients in addition to their "primary" recipients. There is no real technical difference between the two, the "cc:" indicator just denotes a message that is being sent for your
information. Some administrative messages sent to list owners are copied to the user for their information, and vice-versa; this behavior can be disabled by adding a .CC OFF statement to the template.
Centers the text you specify (just the text you typed on the same line as the .CE command). This can be useful to highlight the syntax of a command.
You can resume formatting with .FO ON or .FO RAGGed. (.FO RAGGed requires LISTSERV 1.8e-2002a or later, that is, build date of 31 October 2002 or later.)
Changes right-justified text formatting to left justified text formatting. You can resume right-justified formatting with .FO ON. (.FO RAGGed requires LISTSERV 1.8e-2002a or later, that is, build date of 31 October 2002 or later.)
Cancels the message. LISTSERV stops reading the template form and does not send anything. This is useful if you want to completely remove a particular mes­sage; note however that this can be confusing with certain commands, as LIST­SERV may say "Notification is being sent to the list owners" when in fact nothing will be sent because of the .QQ command in the template form.
Ends processing of the current template as if you had reached the end, but without cancelling the message. The main purpose is to avoid multi-level nested .BB/.EB conditional blocks (see below) that are hard to keep track of.
Adds a 'Reply-To:' field pointing to the list owners in the header of the generated message. Use this command when you think users are likely to want to reply with a question. You can also use .RE POSTMASTER to direct replies to the LISTSERV administrator, if this is more appropriate.
Replaces the default recipients of a message with the value specified. For instance, if you use the ADDREQ1 template form to send new subscribers a questionnaire, application form or similar material, you will need to add a '.TO &WHOM' instruction to your modified template form, as by default the user will not receive a copy.
A number of more advanced commands are available to list owners with more sophisticated needs and some programming experience. If you encounter one of these commands in a template, you will probably want to leave it alone.
Table 9-2 Advanced Formatting Commands for List Owners
Tells LISTSERV to leave the text immediately following the .ASIS directive alone, that is, don't convert "<" and ">" characters into HTML &lt; and &gt;
when creating pages. This is specifically for use in HTML templates where it is important not to convert parts of a URL reference. For instance,
As with the .CE directive, the text you intend to affect with the .ASIS directive must not wrap. The .ASIS directive will only work on text it finds on the same physical line into which it is coded.
This setting is ignored if the template does not actually contain special charac­ters (for instance, if the template is written in 7-bit ASCII). Otherwise the appro­priate headers are created for the message in question when it is sent out.
Copies the contents of the specified DD into the message. This is meaningful only if a DD has been set up by LISTSERV for this purpose. As a rule of thumb, you should either leave these statements unchanged or remove them.
Imbeds (inserts) another template form at this point in the message. This is used to avoid duplicating large pieces of text which are mostly identical, such as the templates for "you have been added to list X by Y" and "your subscription to list X has been accepted".
As noted below, LISTSERV will not pick up an "imbedded" template form from $SITE$.MAILTPL. If you wish to include an "imbedded" template form (e.g., $SIGNUP) in $SITE$.MAILTPL, you must also include the template form that calls it with the .IM command.
Stop (i.e., QUit) processing of the current template as if you had reached the end, but without cancelling the message. The main purpose is to avoid multi-level nested .BB/.EB conditional blocks that are hard to keep track of.
(QUit IF) Similar to .QU, stop processing the current template without cancelling the message, based on the result of an inline conditional comparison. The full syntax is
Defines or redefines a substitution variable. This is convenient for storing tem­porary (text) expression results which need to be used several times. Even standard variables such as &LISTNAME can be redefined - at your own risk. You must enclose the text expression in single quotes if you want leading or trailing blanks.
1. It overwrites the heading originally obtained from the '>>>' header line starting the template. A mail template uses this heading as the "Subject:" field. A mes­sage template, on the other hand, does not use this heading for anything, but it is still changed internally. See .SM below.
2. It leaves an explicit indication to the template invoker that it is desired to change the subject line. For a mail template, this has already happened. For a message template, on the other hand, the invoker is strongly urged to take rea­sonable steps to make it happen. "Reasonable" is defined by the invoker, not by the customer.
One important caveat when not using .SM: Most templates are going to be for command replies. A command reply may be followed by another reply to the same command (eg multi-user ADD), or to another command. All these replies are bundled into the same e-mail message sent in answer to the command(s), again unless you use .SM. And this message can only have one subject by def­inition.
.SM is not available in message fragments and is only available in message templates which do not contain a comment to the effect that .SM is not sup­ported for that particular message template.
Types one line of text on the LISTSERV console log. This can be useful to the LISTSERV maintainer for debugging, and also to record information in the con­sole log.
9.5.4 Conditional Processing
LISTSERV mail templates can be programmed with an if/then/else logic that evaluates available data and performs the appropriate task depending on the outcome of the evaluation.
A conditional block begins with the command .BB (begin block) and ends with .EB (end block). In the simplest case, the boolean expression following .BB is evaluated and, if false, all the text between the .BB and .EB delimiters is skipped. For instance, from $SIGNUP:
.bb &DEFOPT ^= ''
Following instructions from the list owner, your subscription options have been set to "&DEFOPT" rather than the usual LISTSERV defaults.
For more information about subscription options, send a "QUERY &LISTNAME" command to &MYNAMES.
 
.eb
.ELSE may be specified in cases where an alternate text is required, as in this more complicated example (also from $SIGNUP):
.bb ((&x ^= POSTMASTER) and (&x ^= OWNER)) and (&x ^= OWNERS)
Please note that it is presently possible for
.bb &x = PUBLIC
anybody
.else
other people
.eb
to determine that you are signed up to the list through the use of the "REVIEW" command, which returns the e-mail address and name of all the subscribers. If you do not want your name to be visible, just issue a "SET &LISTNAME CONCEAL" command.
 
.eb
 
Additionally, it is possible to simply exit a conditional at an arbitary point by using a .QU (QUit) command. For instance, the MSG_POSTING_REJECT_BAD_ATTACHMENT message template is used both to reject unwanted attachment types as well as viruses. In order to avoid processing the entire template (which contains other text that is not germane to a virus rejection), .QU is used to simply exit processing and send the message immediately.
.bb &VIRUS = 1
.* A virus was detected in the message. Note that this is only possible
.* for messages sent to a list, LISTSERV does not execute attachments so
.* messages sent to LISTSERV are not checked for viruses.
Your posting to the &LISTNAME list has been rejected because it contains
.bb &VIRUS_NAME ^= ''
the '&VIRUS_NAME;'
.else
a
.eb
.bb &VIRUS_FILENAME ^= ''
virus in attachment '&VIRUS_FILENAME;'.
.else
virus.
.eb
You are strongly advised to check your computer for viruses as soon
as possible!
.qu
.eb
.* text for rejecting attachments follows
 
Notes: Conditional blocks may nest to an arbitrary depth.

The expression evaluator is recursive but not very sophisticated; the restriction you are most likely to encounter is that all sub-expressions have to be enclosed in parentheses if you are using boolean operators. That is, ".BB &X = 3" is valid but ".BB &X = 3 and &Y = 4" is not.

String literals do not require quoting unless they contain blanks, but quotes are accepted if supplied.

Comparison operators are = <> ^= IN and NOT IN (the last two look for a word in a blank-separated list of options, such as a keyword value). These operators are not case-sensitive; == and ^== are available when case must be respected. Boolean operators are AND and OR.

A command line in a conditional block must be contained on one physical line and may not wrap, so be careful when sending MAILTPL files back to LISTSERV that you do not accidentally wrap long .BB lines.

The operators =* and ^=* are available to perform wildcard matches in conditional blocks. For instance JOHN_DOE@UNIX.EXAMPLE.COM =* J*DOE@*EXAMPLE.COM is a true statement. The wildcard specification is on the right-hand side whereas the actual text (or variable) you are evaluating is on the left.
9.5.5 The .QUIF Command
.QUIF (QUit IF) allows the invoker to stop processing the template if a certain condition is met, but without having to define a full-blown conditional block. For instance, the .IM command used to imbed one template into another returns a success code in the template variable &RC. If imbedding succeeds, &RC is set to 0, and something like the following is possible:
>>> MSG_POSTING_REJECT_BAD_ATTACHMENT Received an attachment not allowed by "Attachments="
.* Use legacy BAD_ATTACHMENT template if present
.im *BAD_ATTACHMENT
.quif &rc = 0
.* at this point template processing stops and the message is sent if &RC = 0
.* otherwise processing would continue with any following text.
 
"quif &rc = 0" is strictly equivalent to the block
.bb &rc = 0
.qu
.eb
9.5.6 Using 8-Bit Characters in Templates
If you include 8-bit characters (e.g., accented or national language characters) in templates, LISTSERV will automatically encode the templates on-the-fly using MIME quoted-printable encoding. While there is no guarantee that every mail program will be able to properly display 8-bit characters, those mail programs that do understand MIME quoted-printable encoding should have no trouble doing so.
9.6 Editing List-Level Default Templates
Please note that list-level mail templates are not available in LISTSERV Lite.
It is strongly recommended that the web interface customization tools be used to customize the "look and feel" of list templates. However, some administrators may wish to use the old method. If so, then simply make a copy of DEFAULT.MAILTPL on your local machine and name it listname.MAILTPL. Keep the original DEFAULT.MAILTPL around in case you make a mistake and need to start over.
At this point, you could theoretically store the listname.MAILTPL back on the LISTSERV host. However, without making any changes that would be somewhat pointless. At the very least you should edit the INFO template form before storing the template. Note also that you need only store the sections of the template that you have changed. For instance, if you edit the INFO template form but leave the rest of the template untouched, you can delete the rest of the template and store the INFO template form alone as listname.MAILTPL. The benefit to this approach is that any administrative changes to the rest of the default template are automatically applicable to your list as soon as they are made, rather than requiring that you edit your mail template individually to reflect such changes. If using the manual-editing procedure, L-Soft recommends that this approach be followed as the default.
9.6.1 The INFO Template Form
The INFO template form is LISTSERV's response to the command INFO listname. By default, it contains the following:
Figure 9-1 Default Content of the INFO Template form for DEFAULT.MAILTPL
There is no information file for the &LISTNAME list. Here is a copy of the list "header", which usually contains a short description of the purpose of the list, although its main purpose is to define various list configuration options, also called "keywords". If you have any question about the
&LISTNAME list, write to the list owners at the generic address:
Note: the replaceable parameters &LISTNAME and &MYHOST. Don't change &MYHOST; LISTSERV replaces it with the correct value for the name of the host site. &LISTNAME automatically inserts the name of the list. It's probably best to use &LISTNAME to refer to the list throughout the document rather than to replace it with something like "MYLIST-L". This ensures that the template form will be consistent with the default and will be simpler to debug should a problem arise. Also, in the event the name of the list changes, it will be unnecessary to edit the template form (although it would have to be renamed to match the new name of the list, of course).
Should it be desirable to replace the default INFO template form with information about the list, it is probably best to remove the .dd &LISTHDR line. This line instructs LISTSERV to read in the header of the list and add it to the response in lieu of any other data about the list. Many list owners add descriptive comment lines to their list headers, thus this default.
Here is a minimally-edited sample INFO template form for a list called MONKEYS.1
Figure 9-2 Sample of an Edited INFO Template Form
&LISTNAME is an open, unmoderated discussion list featuring monkeys. Things such as how to care for a pet monkey, monkey diseases, monkey lore, endan­gered species of monkeys, and monkey psychology are likely to be discussed. The list is NOT intended for discussion of Darwinism and/or theories of
9.6.2 DEFAULT MAILTPL Templates
Note: We no longer provide a complete list of template forms in this section as there are simply too many of them. Templates are listed by name and description in the customization section of the web interface.
The following are template forms that can be defined, but which are not present by default in DEFAULT.MAILTPL. If you want to define them for a particular list, the easiest way to do so is via the web interface.
POSTACK1 (optional) – When present, this message is sent in reply to any message posted to the list. This is very useful for creating "infobots", or just for returning a standard acknowledgement to contributors. The &SUBJECT variable contains the subject of the original message, and naturally the usual substitutions (&LISTNAME, &DATE, &TIME) are available.
TOP_BANNER, BOTTOM_BANNER (optional) – When these template forms are present, their contents are automatically inserted at the top (respectively bottom) of each and every message posted to the list. Typically, the top banner would be used for a copyright or short legal warning which absolutely has to be seen by each and every reader. The bottom banner could contain instructions for signing off the list, a disclaimer, an acknowledgement of a sponsor's contribution, a "tip of the week", etc.
Documented Restriction: The use in banners of substitutions which do not yield a constant result (e.g., &TIME) will defeat the duplicate mail detection part of LISTSERV's loop-checking heuristics in any case where a subscriber is forwarding all mail back to the list. L-Soft advises that such substitutions never be used in a TOP_BANNER or BOTTOM_BANNER.
LISTSERV does not attempt to remove bottom banners from individual messages in digests, for instance, which have been included as quoted material in responses.
TOP_BANNER_HTML, BOTTOM_BANNER_HTML (optional) – When these template forms are present, they will be used "as is" for HTML message parts. If absent, the regular banner is used for HTML, probably with less than 100% satisfaction.
Documented Restriction: The use in banners of substitutions which do not yield a constant result (e.g., &TIME) will defeat the duplicate mail detection part of LISTSERV's loop-checking heuristics in any case where a subscriber is forwarding all mail back to the list. L-Soft advises that such substitutions never be used in a TOP_BANNER_HTML or BOTTOM_BANNER_HTML.
CONTENT_FILTER (optional) – When present, provides LISTSERV with a ruleset for message content filtering that can be configured at the list level. See Section 7.18 Content Filtering for more information on how to use content filtering.
9.6.3 Tips for Using Templates
Many list owners require prospective subscribers to fill in a little questionnaire before being added to the list, or to explicitly state that they have read the list charter and agree to follow all rules or be removed from the list. The most convenient method, for both list owner and subscriber, is to have the SUBSCRIBE command return a copy of the questionnaire (or list charter, etc.), and not forward the request to the owner. The user answers the questions and returns them directly to the list owner, who then adds the subscriber manually. Naturally, it is more convenient for the user if this information arrives in a separate message, with a 'Reply-To:' field pointing to the list owner's address. Thus, you should not use the SUB_OWNER template form for this purpose, because it is a linear template form and does not give you any control over the 'Reply-To:' field. The SUB_OWNER template form could be modified to read "A copy of the list charter is being sent to you, please read it carefully and follow the instructions to confirm your acceptance of our terms and conditions." The list charter would then be sent separately, through the ADDREQ1 template form. You would use the .RE OWNERS command to instruct LISTSERV to point the 'Reply-To:' field to the list owners, and .TO &WHOM to change the destination from list owner to subscriber. If you want to receive a copy of the message, you can use .TO &WHOM cc: xxx@yyy.
When writing template forms, it is a good idea to use substitutions (&XXXX) for information which may change in the future. In particular, it is not uncommon for lists to have to be moved from one host to another, and this will be a lot easier if the template forms use substitutions for the list address and list host. The &LISTADDR substitution translates the full address of the list (XYZ-L@XYZ.COM), whereas &LISTNAME is just the name (XYZ-L). For references to the server and host, use &MYHOST for the Internet hostname, &MYSELF for the server address (normally LISTSERV@&MYHOST), and &OWNER for the xxx-request mailbox address. These substitutions are "universal" and can be used in all template forms. For instance, if you decide to make a bottom banner with instructions for leaving the list, the text could read: "To leave the list, send a SIGNOFF &LISTNAME command to &MYSELF or, if you experience difficulties, write to &OWNER."
9.7 Using the DAYSEQ(n) Function
The DAYSEQ(n) function is quite powerful. This function allows the list owner to code template forms (such as the PROBE1 or BOTTOM_BANNER messages) that change or "rotate" automatically.
The DAYSEQ(n) function is invoked in a .BB - .EB conditional block, and n corresponds to the number of days in the rotation period, i.e., to the number of variations that you want to make to the text of the message. &DAYSEQ(n) returns a number from 1 to n which increases by 1 every day, with no special regard for weekends. That is, if the rotation period is to last for a week, you code DAYSEQ(7). If the rotation period is 15 days, you code DAYSEQ(15). Two examples follow:
9.7.1 Rotating Bottom Banner
To create a rotating bottom banner, follow this example. A list has three commercial sponsors, each of whom are provided with an advertisement every three days. (Note that this doesn’t take weekends into account; in this example, if company A is featured in the banner on Monday, it will be featured again on Thursday and then again on Sunday. However, in the following week it will be featured on Wednesday, Saturday, and Tuesday, so it will actually get rather good coverage.) Our BOTTOM_BANNER template form would look like this:
>>> BOTTOM_BANNER
.BB &DAYSEQ(3) = 1
Today’s copy of the &LISTNAME newsletter has been brought to you by Company A.
.EB
.BB &DAYSEQ(3) = 2
Today’s copy of the &LISTNAME newsletter has been brought to you by Company B.
.EB
.BB &DAYSEQ(3) = 3
Today’s copy of the &LISTNAME newsletter has been brought to you by Company C.
.EB
 
If a company needs to get a higher percentage of "air" time than another, you can simply assign it more than one of the possible n values of &DAYSEQ(n). For instance, if you have two companies but one should get twice as many days of "air" time, you might code something like this:
>>> BOTTOM_BANNER
.BB (&DAYSEQ(3) = 1) OR (&DAYSEQ(3) = 3)
Today’s copy of the &LISTNAME newsletter has been brought to you by Company A.
.EB
.BB &DAYSEQ(3) = 2
Today’s copy of the &LISTNAME newsletter has been brought to you by Company B.
.EB
 
This would cause Company A’s message to appear on days 1 and 3 of the rotation period and Company B’s message to appear on day 2 only.
9.7.2 Rotating FAQ via the PROBE1 Template and "Renewal= xx-Daily"
Subscription renewal can be coded with daily granularity (however, please note that it is and remains inadvisable to use renewal intervals of less than a week). If you further code subscription probing into the "Renewal=" keyword with the ",Probe" parameter, you open up the possibility of turning the standard PROBE1 template form into a periodic FAQ. Here’s how:
We’ll assume to start that you will code "Renewal= 15-Daily,Probe" in your list header. (You can experiment with other numbers, but since we have two messages and will be using &DAYSEQ(2), we need an odd renewal period.) We’ll also assume that you want to send two versions of your FAQ each month; the first, a complete FAQ document, and the second, an abbreviated "reminder" version that just contains information about how to sign off, how to post to the list, and so forth. The basic algorithm is therefore:
When &DAYSEQ(2) = 1, send the full FAQ.
When &DAYSEQ(2) = 2, as it will 15 days later, send the abbreviated FAQ.
Your PROBE1 template form would thus look like this:
>>> PROBE1 Periodic FAQ posting for &LISTNAME
&WEEKDAY, &DATE &TIME
.BB &DAYSEQ(2) = 1
This is the complete FAQ for &LISTNAME. Please read it and keep a copy for future reference. A FAQ document for &LISTNAME is distributed every 15 days, the full FAQ alternating with a shorter "reminder" FAQ.
 
<body of the full FAQ document>
.EB
.BB &DAYSEQ(2) = 2
This is the abbreviated FAQ for &LISTNAME. Please read it and keep a copy for future reference. A FAQ document for &LISTNAME is distributed every 15 days, the full FAQ alternating with a shorter "reminder" FAQ.
 
<body of the abbreviated FAQ document>
.EB
9.7.3 Calculating the Value for DAYSEQ()
When you first start using a rotating banner with the &DAYSEQ variable, the &DAYSEQ(n)= 1 period begins based on the number of days elapsed since a baseline. On VM (and in REXX generally) you can calculate today's value easily with:
/* */
say Date('B') + 1
If you do not have access to a REXX interpreter, Date('B') is described as "the number of complete days (that is, not including the current day) since and including the base date, 1 Jan 0001, in the format 'dddddd' (no leading zeros or blanks)."2 It also is equal to the C language expression time(0)/86400 + 719162 or, for OpenVMS users, to the Smithsonian base date plus 678575.
For example, for Friday 22 Oct 2004, the value of Date('B') + 1 is 731876. This value increases by one every day at midnight.
9.8 Storing the <listname>.MAILTPL File on the Host Machine
The procedure differs slightly on VM systems, but the following will work for unix, VMS and Windows systems:
1. Get a copy of DEFAULT.MAILTPL and edit it.
2. Be sure that you have defined a "personal password" to LISTSERV with the PW ADD command before you PUT the template file. If you have done this but can't remember the password, send a PW RESET command to LISTSERV, then a new PW ADD command.
3. Send the file to LISTSERV with a PUT listname MAILTPL PW=XXXXXXXX command at the top of the file, just as if you were storing the list itself. Replace XXXXXXXX with your personal password.
The variation for VM systems is that the LISTSERV maintainer will have to create a fileid for the file before it can be PUT on the server and seen by LISTSERV.
Note: The LISTSERV maintainer can create and edit these files in place with any standard text editor. Changes made to template files in this way are available to LISTSERV immediately after they are saved.
9.9 DIGEST-H and INDEX-H Template Files
Two other template files that are available pertain to the automatic “digestification” feature. You may create and store files called listname DIGEST-H and listname INDEX-H. These files define custom digest headers and custom index headers, respectively. The DIGEST-H and INDEX-H files are plain text files, like the WELCOME and FAREWELL files, and the instructions for storing them on the server are identical. Note that, as with the WELCOME and FAREWELL files, you cannot use the template formatting commands and replaceable parameters discussed above.
Figure 9-3 Typical Contents of a DIGEST-H or INDEX-H File
The contents of DIGEST-H and INDEX-H are appended to the digest or index, respectively, immediately following the list of topics.
Figure 9-4 Sample DIGEST Output for a List with a DIGEST-H File
Notes: The INDEX-H output would be similar to the above figure, following the list of postings.

You can’t add a digest or index “footer” because according to the standard, anything after the end of the digest text is supposed to be discarded.
9.10 WWW Interface Templates and Template Forms
The following describes the available template files and their respective template forms for the WWW archive and administration interface. L-Soft does not advise modifying these templates unless you know exactly what you are doing. If you modify the templates it is strongly recommended that you keep copies of the originals in a safe location for fall-back. In practice, this means that you should NEVER edit the default template files themselves.
9.10.1 Web Forms (Static) Contained in DEFAULT MAILTPL
Note: We no longer provide a complete list of template forms in this section as there are simply too many of them. Templates are listed by name and description in the customization section of the web interface.
9.10.2 The WWW_ARCHIVE.MAILTPL File
In LISTSERV 14.3, this file became obsolete. LISTSERV will migrate existing templates from WWW_ARCHIVE MAILTPL to SITE MAILTPL, unless one of the following conditions arises:
A conflicting template (same name, different contents) is already in SITE MAILTPL; or
The copy of the template in WWW_ARCHIVE matches the first template in the system search order.
If there are no conflicts, WWW_ARCHIVE MAILTPL is then renamed to WWW_ARCHIVE OLDTPL. If a conflict is detected, LISTSERV will not attempt to determine which version of the template is "correct", but rather will log something like the following:
7 Oct 2004 10:57:05 Migrating templates from WWW_ARCHIVE to SITE...
- $TEST_TEMPLATE: conflicting version found in SITE
7 Oct 2004 10:57:05 Conflicts detected, finish migration manually
It is then incumbent on the site maintainer to harmonize the differing versions of any templates reported to be in conflict.
9.10.3 The DEFAULT.WWWPTL File (Dynamic Templates)
The DEFAULT WWWPTL file contains the default templates for the parts of the WWW archive interface that are not defined in DEFAULT MAILTPL. Unless you have specific issues that need to be resolved (such as a national language preference or a need to point certain links to non-standard locations), it is strongly recommended NOT to edit this file. One reason for this is that DEFAULT WWWTPL will be overwritten by a software update. The safest approach to customizing the look and feel of your site is to use the customization features built into the web interface, which save your customizations in a different place.
When customizing these templates, there are two fundamental differences between them and the templates in DEFAULT MAILTPL:
1. Any substitution variable that you use (for instance, &LISTNAME) must be escaped with a "+" symbol between the ampersand and the name of the variable, thus: &+LISTNAME. (Note that, as with the regular mail template forms, not all substitu­tion variables are available in every HTML template form.)
2. Any dot-formatting command you use (for instance, .CC , .BB , etc.) must have a "+" symbol rather than the dot, thus: +CC +BB
Note: We no longer provide a complete list of template forms in this section as there are simply too many of them. Templates are listed by name and description in the customization section of the web interface.
9.10.4 The SITE.WWWTPL File
The preferred method of editing site.wwwtpl is to use the web interface's built-in customization features to edit templates. L-Soft no longer recommends editing site.wwwtpl by hand.
However, if desired, you can override the default.wwwtpl file by providing a customized site.wwwtpl file in LISTSERV's A directory.
The site.wwwtpl file is the file in which edited web templates are placed. This prevents your site-wide definitions being overwritten in an upgrade (i.e., when default.wwwtpl will normally be overwritten). If a given template is found in site.wwwtpl, that version of the template takes precedence over the one found in default.wwwtpl. This means that you don't have to duplicate every template form in default.wwwtpl, just the ones you don't want overwritten by an upgrade.
Note that for list-level templates, site.wwwtpl will itself be overridden by definitions in any listname.wwwtpl files you have installed.
9.10.5 National Language Template Files (idiom.mailtpl)
National language templates can be written and used with LISTSERV (L-Soft does not provide them). The use of such templates is optional and governed by two settings:
Site-wide – The DEFAULT_LANGUAGE= site configuration variable allows you to set the site-wide national language template for use by all lists on the server. By default this variable is unset and DEFAULT MAILTPL (or the corresponding customizations in SITE MAILTPL) is used.
List-level – The Language= list header keyword can be used to specify a national language template to be used for a particular list, for instance a Spanish-language list on an otherwise English-language server.
To create a national language template, you simply copy DEFAULT MAILTPL to idiom MAILTPL , where idiom is the name of the language, and translate it as desired. You also use idiom to specify the value for DEFAULT_LANGUAGE= and/or Language=. For a given language you can specify anything you want for idiom; in other words LISTSERV does not care if you call the file FRANCAIS MAILTPL or FRENCH MAILTPL, but if you do call it FRENCH MAILTPL you must specify FRENCH as the idiom, and likewise, if you call it FRANCAIS MAILTPL you must specify FRANCAIS as the idiom. LISTSERV has no information about what a given language is called, it simply looks for a MAILTPL file for the idiom data supplied.
If you are going to translate the web interface template forms into idiom as well, you will need to copy DEFAULT WWWTPL to idiom MAILTPL and again, translate as desired. This requires that you add a special template form to WWW_ARCHIVE MAILTPL, so that the 'wa' CGI script will know what to look for, as follows:
>>> LANGUAGE
idiom
where idiom is, of course, the same value we've been talking about above. For instance for a FRANCAIS idiom you'd use
>>> LANGUAGE
FRANCAIS
See also Section 9.3.1 Mail Templates regarding the use of 8-bit characters in template forms.
9.10.6 Template Precedence
For template forms found in DEFAULT MAILTPL, the following precedence is used when LISTSERV searches for a given template form:
listname MAILTPL
idiom MAILTPL
WWW_ARCHIVE MAILTPL
DEFAULT MAILTPL
That is to say, if LISTSERV needs a copy of the ADD1 mail template form, it will look first in the listname.mailtpl file for the list in question. If no such file exists, or if ADD1 is not present in listname.mailtpl, LISTSERV will look in idiom.MAILTPL (if Language= or DEFAULT_LANGUAGE= is set to idiom). Again, if the ADD1 form is not present in idiom.mailtpl, or if idiom.mailtpl does not exist, LISTSERV will then look in default.mailtpl (www_archive.mailtpl is skipped because ADD1 is not a web template form) and pull out the default ADD1 template form.
For template forms found in DEFAULT WWWTPL the precedence is:
listname WWWTPL
idiom WWWTPL
SITE WWWTPL
DEFAULT WWWTPL
The same sequence of events applies as for the MAILTPL files, except that SITE WWWTPL is never skipped (all template forms in the WWWTPL files are web forms).
9.11 Serving Up Custom Web Pages for your List
This feature is not available in LISTSERV Lite.
Originally in order to serve up custom or special web pages for a list it was necessary to construct those pages as HTML files and place them either into the /archives directory or link them from somewhere else. This was sometimes impossible for list owners who had no administrative access to the server's web directories or who had no other place from which to serve web pages.
It is possible to add ad-hoc web page templates by creating new (non-standard) template forms and enabling their display by setting a special variable value, SHOWTPL_ALLOWED, in the template form. For instance, one could set up a page with special administrative information, the list charter, netiquette information, or the like, and serve it and maintain it directly from the LISTSERV web template interface without need for any other access to the server.
9.11.1 A Practical Example: ADMIN_POST
The author used to serve up an administrative posting via FTP back in the days when his lists lived on a server that had FTP access to the archive notebooks. When FTP access to the server was cut off due to security concerns, he had to find another way to serve the information via the web. Here is how it was done:
(The following example assumes that you have the 1.8e web administration interface installed. New template forms cannot be created this way in previous versions.)
First, log into the web administration interface. Choose the list for which you will be making a new page, and then click the [Templates] button to enter the mail and web template editing area. Since the template you will be creating is a web template, click the [Switch to WWW templates] button to change modes.
Next, type the name of the new template form into the box provided, and click [Create]. The Edit List Template screen opens with the command response
The ADMIN_POST form has been successfully stored in the TEST template library.
In the Description box, type a description of the template, for example, "Administrative information page".
In the large text box provided for the template text, first type the following line:
+SE SHOWTPL_ALLOWED 1
This line tells LISTSERV that it is allowed to serve the page on the web. If the line is not found, the template will not be available.
Following this line you can start adding your HTML. However note carefully that you cannot override the default headers and footers that have already been defined by other template forms in the library. You can start with a <title></title> block but it will be followed by the pre-defined header and then by your HTML.
After adding your HTML, click [Update], and the template form will be stored. The URL for the page you are defining in this example will be http://your_server_hostname/path_to_wa?SHOWTPL=ADMIN_POST&L=listname (the parameters for 'wa' are case-sensitive and must be sent in upper case). For instance, the author's version of the ADMIN_POST template form can be viewed at http://peach.ease.lsoft.com/scripts/wa.exe?SHOWTPL=ADMIN_POST&L=VISBAS-L.
9.12 Modifying the Output of LISTSERV's HELP Command (non-VM)
LISTSERV's HELP command output is designed primarily to show the basic syntax of certain commonly used commands, and point users to other documents that explain how to use LISTSERV. Some sites may wish to amplify the message, and this can be done by creating a file called 'localcmd.helpfile' in the same directory where LISTSERV keeps permvars.file, default.mailtpl, and so forth.
Note: L-Soft does not recommend removal or alteration of the LSVHELP.FILE that ships with the software (and which contains the default text for the HELP command response) as LISTSERV expects it to be present and it will be overwritten in an upgrade.
LOCALCMD HELPFILE was originally intended to allow non-VM sites to document local commands constructed by using list exits (see the Advanced Topics Guide for LISTSERV for details regarding list exits and local commands). As such, when LISTSERV sees a LOCALCMD HELPFILE, it appends the contents of LOCALCMD HELPFILE after a line that says "The following local commands are also available:". For instance, if you have a local command called /XYZ, you could have a LOCALCMD HELPFILE containing something like:
/XYZ <options> (One line description of /XYZ)
and the output of HELP would then be
> help
LISTSERV(R) version 15.5 - most commonly used commands
INFO <topic|listname> Order documentation (plain text files)
SUBscribe listname <full name> Subscribe to a list
SIGNOFF listname Sign off from a list
SIGNOFF * (NETWIDE - from all lists on all servers
Query listname Query your subscription options
Search listname keyword... Search list archives
SET listname options Update your subscription options
INDex <listname> Order a list of LISTSERV files
GET filename filetype Order a file from LISTSERV
There are more commands; send an INFO REFCARD command for a comprehensive reference card, or just INFO for a list of available documentation files.
If you prefer, you can use LISTSERV through its web interface at http://listserv.example.com/cgi-bin/wa.exe (the full manuals can also be browsed online at this URL).
The following local commands are available at this installation:
/XYZ <options> (One line description of /XYZ)
This server is managed by:
LSTMAINT@LISTSERV.EXAMPLE.COM
For most sites, however, locally-added commands probably won't be available. If you use the LOCALCMD HELPFILE functionality at all, it will likely be to enhance the output in order to make it more understandable for users. So you probably would not want to see the line "The following local commands are available at this installation:" followed by text that doesn't document commands. You can turn off this line by simply adding
.NH
as the first line of LOCALCMD HELPFILE. Note that .NH is the only formatting command available in LOCALCMD HELPFILE; it is otherwise a flat ASCII file that outputs exactly as you type it.
Let's say that you are having a problem where the LISTSERV postmasters are fielding a lot of questions that really ought to be sent to list owners (get me off this list, my address changed, etc.) and a little investigation indicates that these people are getting the postmaster address from the HELP command. It's not reasonable to remove the postmaster's address from the output since it should always be possible to find out who is running the server (in case loops develop, etc.), but you could create a LOCALCMD HELPFILE like the following to indicate to users where various kinds of questions should be sent:
.NH
For help with a specific list, please write to the list owner(s) at the generic list owner's address. This address takes the form
listname-REQUEST@LISTSERV.EXAMPLE.COM
For instance, if you are subscribed to a list called DOGLIST-L, to contact the list owners you would write to
DOGLIST-L-REQUEST@LISTSERV.EXAMPLE.COM
PLEASE DO NOT ACTUALLY WRITE TO DOGLIST-L-REQUEST. This is just an example, you must substitute the name of the mailing list in question. There is no DOGLIST-L mailing list on this server and mail sent to DOGLIST-L-REQUEST is discarded unread.
Please do not write to the server manager unless you do not get a response from the list owner. Thank you!
9.13 The $SITE$.MAILTPL File
Note: Because any customizations made at the site level to the default templates now go into the site-level SITE MAILTPL file, which will not be disturbed during an upgrade, defining site-wide defaults in the old $SITE$ MAILTPL file, which in any case did not work for all templates and was never intended for this purpose to begin with, is now obsolete. Most if not all templates that were formerly generated internally by LISTSERV can now be customized as mail templates, message templates, or message fragments, depending on the message.
Sites that are still using $SITE$ MAILTPL for this or any other purpose should migrate to the new system. L-Soft support will not field support inquiries concerning $SITE$ MAILTPL for LISTSERV 15 and later, but will request that you migrate the templates concerned into the new system.
 
 
 

1
Thanks to Marty Hoag of NEW-LIST.

2
Cowlishaw, Michael: The REXX Language: A Practical Approach to Programming, 2nd ed., p.92. Englewood Cliffs, NJ: Prentiss-Hall, Inc., 1990.